agent-workflow-kit-cli 1.3.0 → 1.3.2
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/dist/cli/commands/add.js +1 -1
- package/dist/cli/commands/doctor.js +8 -1
- package/dist/cli/commands/init.js +91 -1
- package/dist/cli/index.js +2 -2
- package/dist/core/analyzer.js +146 -1
- package/dist/core/awos/intelligence.js +30 -6
- package/dist/core/detector.js +32 -4
- package/package.json +1 -1
- package/templates/dotnet/AGENTS.md.hbs +53 -0
- package/templates/dotnet/rules/api-structure.md +43 -0
- package/templates/dotnet/rules/csharp-style.md +33 -0
- package/templates/dotnet/rules/dependency-injection.md +54 -0
- package/templates/dotnet/rules/error-handling-validation.md +86 -0
- package/templates/dotnet/skills/dotnet-controller/SKILL.md +24 -0
- package/templates/express/AGENTS.md.hbs +41 -0
- package/templates/express/rules/error-handling.md +88 -0
- package/templates/express/rules/express-style.md +39 -0
- package/templates/express/rules/router-controller.md +27 -0
- package/templates/express/skills/express-endpoint/SKILL.md +24 -0
- package/templates/nestjs/AGENTS.md.hbs +38 -0
- package/templates/nestjs/rules/module-architecture.md +35 -0
- package/templates/nestjs/rules/nestjs-style.md +41 -0
- package/templates/nestjs/rules/validation-errors.md +46 -0
- package/templates/nestjs/skills/nestjs-module/SKILL.md +25 -0
- package/templates/next-js/AGENTS.md.hbs +41 -0
- package/templates/next-js/rules/data-fetching-mutations.md +36 -0
- package/templates/next-js/rules/next-style.md +32 -0
- package/templates/next-js/rules/seo-metadata.md +50 -0
- package/templates/next-js/rules/server-client-components.md +27 -0
- package/templates/next-js/skills/next-feature/SKILL.md +26 -0
- package/templates/react-ts/AGENTS.md.hbs +109 -32
- package/templates/react-ts/rules/data-fetching.md +45 -0
- package/templates/react-ts/rules/forms-validation.md +55 -0
- package/templates/react-ts/rules/premium-ui.md +45 -0
- package/templates/react-ts/rules/react-style.md +38 -26
- package/templates/react-ts/rules/routing-splitting.md +21 -0
- package/templates/react-ts/rules/seo-accessibility.md +34 -0
- package/templates/react-ts/skills/react-feature/SKILL.md +5 -5
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Quy Ước Đặt Tên & Coding Style cho Next.js (App Router)
|
|
2
|
+
|
|
3
|
+
Tài liệu này đặc tả quy ước đặt tên file, thư mục, cấu trúc import và tổ chức folder trong các dự án Next.js App Router.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🏷️ Quy Ước Đặt Tên (Naming Conventions)
|
|
8
|
+
|
|
9
|
+
| Đối Tượng | Quy Chuẩn Đặt Tên | Ví Dụ Minh Họa |
|
|
10
|
+
| :--- | :--- | :--- |
|
|
11
|
+
| **Thư mục Route (`app/`)** | lowercase hoặc kebab-case | `app/dashboard/`, `app/user-profile/` |
|
|
12
|
+
| **Route Nhóm (Route Groups)** | Bọc trong dấu ngoặc đơn `(group-name)` | `app/(auth)/login/`, `app/(dashboard)/layout.tsx` |
|
|
13
|
+
| **Route Động (Dynamic Routes)** | Bọc trong dấu ngoặc vuông `[paramName]` | `app/blog/[id]/page.tsx`, `app/shop/[...slug]/page.tsx` |
|
|
14
|
+
| **Tệp Giao Diện Đặc Trưng** | Định dạng chuẩn Next.js (lowercase.tsx) | `page.tsx`, `layout.tsx`, `loading.tsx`, `error.tsx` |
|
|
15
|
+
| **Route Handlers** | Định dạng file API endpoint của Next.js | `route.ts` |
|
|
16
|
+
| **Component UI Phụ Trợ** | PascalCase.tsx | `Button.tsx`, `ProductCard.tsx`, `SidebarSkeleton.tsx` |
|
|
17
|
+
| **Custom Hooks** | camelCase bắt đầu bằng tiền tố `use` | `useAuth.ts`, `useLocalStorage.ts` |
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 📦 Imports & Aliasing
|
|
22
|
+
- **Absolute Imports:** Luôn luôn sử dụng absolute imports với alias `@/` trỏ tới thư mục `src/` hoặc root (ví dụ: `import { Button } from "@/components/ui/Button"`). Nghiêm cấm sử dụng relative imports với nhiều tầng nhảy thư mục sâu (ví dụ: `../../../../Button`).
|
|
23
|
+
- **CSS / Styles Imports:** Đặt các styles toàn cục trong một file duy nhất (như `globals.css` hoặc `index.css`) được import trong file `layout.tsx` gốc. Không import file CSS tùy tiện trong các component con.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 📁 Tổ Chức Thư Mục (Folder Organization)
|
|
28
|
+
- Giữ các thư mục bên trong `app/` dành riêng cho việc khai báo routing và giao diện trang tương ứng.
|
|
29
|
+
- Đặt các component nghiệp vụ, hook, service và type bên trong thư mục `src/features/` hoặc `src/components/` bên ngoài thư mục `app/`. Mỗi feature (ví dụ: `billing`) nên đóng gói các tài nguyên liên quan:
|
|
30
|
+
- `src/features/billing/components/BillingForm.tsx`
|
|
31
|
+
- `src/features/billing/hooks/useBilling.ts`
|
|
32
|
+
- Xuất bản public APIs của feature qua một file `index.ts` sạch sẽ.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Tối Ưu Hóa SEO & Cấu Trúc Semantic HTML
|
|
2
|
+
|
|
3
|
+
Tài liệu này quy định việc sử dụng cấu trúc thẻ Semantic, tối ưu hóa điều hướng hình ảnh và tích hợp Metadata API của Next.js để đạt thứ hạng SEO tốt nhất.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🔍 Tích Hợp Metadata API Của Next.js
|
|
8
|
+
- **Metadata Tĩnh:** Khai báo đối tượng `metadata` tĩnh trong các layouts hoặc pages không có biến số động:
|
|
9
|
+
```typescript
|
|
10
|
+
export const metadata = {
|
|
11
|
+
title: 'Dashboard | Skillverse Platform',
|
|
12
|
+
description: 'Trang tổng quan quản lý khóa học',
|
|
13
|
+
};
|
|
14
|
+
```
|
|
15
|
+
- **Metadata Động:** Đối với các route động (như trang chi tiết bài viết, khóa học), khai báo cấu hình SEO thông qua hàm `generateMetadata` đối với các route động để tối ưu hóa SEO tối đa cho hệ thống tìm kiếm:
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { Metadata } from 'next';
|
|
19
|
+
|
|
20
|
+
type Props = { params: Promise<{ id: string }> };
|
|
21
|
+
|
|
22
|
+
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
|
23
|
+
const id = (await params).id;
|
|
24
|
+
const course = await getCourseDetail(id);
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
title: `${course.title} | Skillverse Platform`,
|
|
28
|
+
description: course.shortDescription,
|
|
29
|
+
openGraph: { images: [course.thumbnailUrl] }
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 🎨 Cấu Trúc Semantic HTML5
|
|
37
|
+
- **Thẻ cấu trúc:** Bắt buộc xây dựng bố cục trang bằng các thẻ HTML5 ngữ nghĩa thay vì lạm dụng các thẻ `<div>` vô nghĩa:
|
|
38
|
+
- `<header>`: Thanh tiêu đề hoặc thanh đầu trang chính.
|
|
39
|
+
- `<nav>`: Danh mục liên kết điều hướng cốt lõi.
|
|
40
|
+
- `<main>`: Bao bọc duy nhất phần nội dung cốt lõi của trang.
|
|
41
|
+
- `<section>`: Phân đoạn chủ đề nội dung tổng quát.
|
|
42
|
+
- `<article>`: Các thành phần độc lập (bài viết blog, phần tử thẻ card sản phẩm).
|
|
43
|
+
- `<footer>`: Chứa thông tin bản quyền và liên kết chân trang.
|
|
44
|
+
- **Tiêu đề h-tags:** Đảm bảo thứ tự logic của các thẻ tiêu đề (từ `<h1>` đến `<h6>`). Đảm bảo có duy nhất một thẻ `<h1>` trên mỗi trang.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## ⚡ Tối Ưu Hóa Hình Ảnh & Điều Hướng
|
|
49
|
+
- **Tối ưu hình ảnh:** Tuyệt đối không dùng thẻ `<img>` thô. Bắt buộc sử dụng `<Image />` từ `next/image` với đầy đủ thuộc tính `sizes` và cấu hình `priority` cho các hình ảnh xuất hiện ở nấc màn hình đầu tiên (Above the fold).
|
|
50
|
+
- **Tối ưu điều hướng:** Dùng `<Link />` từ `next/link` để kích hoạt cơ chế pre-fetching tài nguyên ngầm khi link xuất hiện trong viewport, giúp chuyển trang tức thì.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# React Server Components (RSC) vs React Client Components (RCC)
|
|
2
|
+
|
|
3
|
+
Tài liệu này quy định ranh giới kiến trúc và quy tắc phân loại component trong ứng dụng Next.js sử dụng App Router.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🏛️ React Server Components (RSC)
|
|
8
|
+
- **Mặc định:** Tất cả các page, layout và component được tạo bên trong thư mục routing `app/` mặc định phải là React Server Components (RSC).
|
|
9
|
+
- **Lợi ích của RSC:**
|
|
10
|
+
- Gọi dữ liệu (data fetching) trực tiếp sử dụng async/await.
|
|
11
|
+
- Sử dụng an toàn các thư viện phía server (truy vấn DB, đọc file, import khóa bảo mật).
|
|
12
|
+
- Giảm dung lượng bundle size gửi xuống client do mã nguồn RSC chỉ biên dịch và chạy trên server.
|
|
13
|
+
- **Quy tắc:**
|
|
14
|
+
- Thực hiện toàn bộ việc nạp dữ liệu và cấu trúc khung trang bên trong các RSC.
|
|
15
|
+
- Không thêm `"use client"` vào các layout hoặc page entry points trừ khi bắt buộc.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 💻 React Client Components (RCC)
|
|
20
|
+
- **Định nghĩa:** Các component chạy trên trình duyệt để hỗ trợ tương tác và cập nhật trạng thái động từ người dùng.
|
|
21
|
+
- **Dấu hiệu nhận biết RCC:** Chỉ gắn directive `"use client"` ở lớp component lá (Leaf Components) khi component:
|
|
22
|
+
- Sử dụng các Hook vòng đời và trạng thái của React (`useState`, `useReducer`, `useEffect`, `useLayoutEffect`).
|
|
23
|
+
- Gọi các API đặc trưng của trình duyệt (`window`, `localStorage`, custom viewport hooks).
|
|
24
|
+
- Đăng ký các callback lắng nghe sự kiện DOM (như `onClick`, `onChange`, `onSubmit`).
|
|
25
|
+
- **Phân tách ranh giới RCC:**
|
|
26
|
+
- Giữ RCC ở cấp lá (Leaf Components) cuối cùng của cây dựng hình để tối ưu hiệu năng.
|
|
27
|
+
- *Ví dụ:* Nếu trang danh sách sản phẩm (RSC) có thanh tìm kiếm (RCC), hãy tách thanh tìm kiếm thành một component riêng (`<SearchBar />` có `"use client"`) và import vào trang cha chạy ở phía server.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: next-feature
|
|
3
|
+
description: Sinh hoặc mở rộng một page hoặc route handler Next.js + TypeScript mới kèm caching và metadata
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Tuân thủ quy trình này để tạo một page, layout hoặc API route handler mới trong Next.js.
|
|
7
|
+
|
|
8
|
+
Đầu vào (Inputs):
|
|
9
|
+
- featureName: Tên của route hoặc trang (ví dụ: `dashboard`)
|
|
10
|
+
- targetPath: Thư mục chứa route bên trong `app/` để triển khai
|
|
11
|
+
- userFlow: Mô tả tóm tắt hành vi và bố cục giao diện của trang
|
|
12
|
+
|
|
13
|
+
Các bước thực hiện (Steps):
|
|
14
|
+
1. Quét các thư mục lân cận trong `app/` để tham chiếu các layout chung và ranh giới xử lý lỗi (`error.tsx`).
|
|
15
|
+
2. Thiết lập cấu trúc thư mục route theo chuẩn Next.js (ví dụ: `app/(dashboard)/billing`).
|
|
16
|
+
3. Khai báo interface cho route params và query parameters.
|
|
17
|
+
4. Triển khai cấu trúc trang hoặc layout dưới dạng **React Server Component (RSC)**.
|
|
18
|
+
5. Nếu có tương tác người dùng hoặc form, hãy tách thành các component con cấp lá (RCC) được đánh dấu `"use client"` rồi import vào RSC.
|
|
19
|
+
6. Thiết lập cơ chế cache rõ ràng cho toàn bộ các thao tác gọi dữ liệu `fetch()`.
|
|
20
|
+
7. Cấu hình metadata tĩnh hoặc động thông qua hàm `generateMetadata`.
|
|
21
|
+
8. Định nghĩa file xử lý lỗi cục bộ (`error.tsx`) tại thư mục route gần nhất để bắt lỗi runtime.
|
|
22
|
+
9. Thực hiện kiểm tra lỗi cục bộ:
|
|
23
|
+
- `{{runCommand}} lint`
|
|
24
|
+
- `{{runCommand}} typecheck`
|
|
25
|
+
- `{{runCommand}} test`
|
|
26
|
+
- `{{runCommand}} build`
|
|
@@ -1,47 +1,124 @@
|
|
|
1
1
|
## React + TypeScript Guidelines
|
|
2
2
|
|
|
3
|
-
###
|
|
4
|
-
|
|
3
|
+
### 🔄 End-to-End Agent Development Lifecycle
|
|
4
|
+
AI Agents must execute all React + TypeScript tasks following this structured 5-stage lifecycle:
|
|
5
|
+
1. **Design & Code:** Implement components and logic following the guidelines below. Keep logic inside Custom Hooks.
|
|
6
|
+
2. **Comprehensive Testing:** Write component tests using React Testing Library and hook tests for complex behavior.
|
|
7
|
+
3. **Code Quality & Validation:** Perform self-review and execute dynamic linter, type checks, and tests:
|
|
8
|
+
- Linting check: `{{runCommand}} lint`
|
|
9
|
+
- Type checking: `{{runCommand}} typecheck`
|
|
10
|
+
- Unit tests: `{{runCommand}} test` (or `{{runCommand}} test -- --run` in CI/CD)
|
|
11
|
+
- Production build: `{{runCommand}} build`
|
|
12
|
+
4. **Dependency Management:** Install new packages using `{{packageManager}} add [package_name]` (or `npm install [package_name]` if using npm). Never manually modify the lock file `{{lockFile}}`.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
### 🏗️ Architecture & Feature Conventions
|
|
17
|
+
Use a strict **feature-first** modular packaging layout. Keep routing modules thin, and place feature UI, custom hooks, services, types, and tests together within the feature module:
|
|
5
18
|
|
|
6
19
|
```text
|
|
7
20
|
src/
|
|
8
|
-
app/ # App shell, router, providers
|
|
21
|
+
app/ # App shell, router, context providers
|
|
9
22
|
features/
|
|
10
23
|
billing/
|
|
11
|
-
components/
|
|
24
|
+
components/ # Feature-specific components
|
|
12
25
|
BillingPanel.tsx
|
|
13
|
-
hooks/
|
|
26
|
+
hooks/ # Feature-specific custom hooks (queries, state)
|
|
14
27
|
useBilling.ts
|
|
15
|
-
services/
|
|
28
|
+
services/ # API clients and data transformers
|
|
16
29
|
billingClient.ts
|
|
17
|
-
types
|
|
18
|
-
|
|
19
|
-
|
|
30
|
+
types/ # Feature type definitions
|
|
31
|
+
billing.ts
|
|
32
|
+
__tests__/ # Component and hook unit tests
|
|
33
|
+
BillingPanel.test.tsx
|
|
34
|
+
index.ts # Public API for this feature
|
|
35
|
+
shared/ # Core shared assets, hooks, components, utils
|
|
20
36
|
components/
|
|
21
37
|
hooks/
|
|
22
38
|
utils/
|
|
23
39
|
```
|
|
24
40
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
### 🎨 Aesthetics, Styling & Premium UI
|
|
44
|
+
The UI must feel premium, modern, and cohesive.
|
|
45
|
+
- **Strict Tailwind CSS usage**: Never write inline custom CSS. Build the interface entirely using Tailwind Utility Classes.
|
|
46
|
+
- **Dynamic Classes helper**: Never use string interpolation to join dynamic classNames. Always use the `cn()` helper (combining `clsx` and `tailwind-merge`):
|
|
47
|
+
```typescript
|
|
48
|
+
// src/utils/cn.ts
|
|
49
|
+
import { ClassValue, clsx } from "clsx";
|
|
50
|
+
import { twMerge } from "tailwind-merge";
|
|
51
|
+
|
|
52
|
+
export function cn(...inputs: ClassValue[]) {
|
|
53
|
+
return twMerge(clsx(inputs));
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
Usage:
|
|
57
|
+
`className={cn("px-4 py-2 text-white transition-all", isActive ? "bg-blue-500" : "bg-gray-500", customClass)}`
|
|
58
|
+
- **Mobile-First Design**: Design layouts for mobile by default. Use breakpoints (`sm:`, `md:`, `lg:`, `xl:`) only to add or modify responsive styles as viewport size increases.
|
|
59
|
+
- **Micro-animations & Motion**: Use `framer-motion` (or equivalent core transition library) for physical state changes:
|
|
60
|
+
- Transition duration should be short (between `0.2s` and `0.3s`).
|
|
61
|
+
- Use natural easing curves (`easeOut`, `easeInOut`) or spring physics for buttons/modals.
|
|
62
|
+
- Wrap conditional components in `<AnimatePresence>` to execute smooth exit animations.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
### 🌐 Asynchronous Server-State & API Call Conventions
|
|
67
|
+
- **No raw useEffect Fetching**: Never fetch data using raw `useEffect` blocks.
|
|
68
|
+
- **Centralized API Client**: Route all outgoing requests through a unified client instance (e.g. `src/lib/api-client.ts`) that manages baseURL, interceptors, auth token inclusion, and global error mappings.
|
|
69
|
+
- **Asynchronous Server-State**: Manage all server state using **TanStack Query (React Query)** or **SWR**.
|
|
70
|
+
- **Separation of Concerns**: UI components must only call custom query hooks and render UI based on three states (`isLoading`, `isError`, and `data`). All fetching, caching, and mutation logic must be kept inside custom hooks:
|
|
71
|
+
```typescript
|
|
72
|
+
// src/features/roadmap/api/use-roadmap.ts
|
|
73
|
+
import { useQuery } from "@tanstack/react-query";
|
|
74
|
+
import { apiClient } from "@/lib/api-client";
|
|
75
|
+
|
|
76
|
+
export const useRoadmap = (roadmapId: string) => {
|
|
77
|
+
return useQuery({
|
|
78
|
+
queryKey: ["roadmaps", roadmapId],
|
|
79
|
+
queryFn: async () => {
|
|
80
|
+
const response = await apiClient.get(`/roadmaps/${roadmapId}`);
|
|
81
|
+
return response.data;
|
|
82
|
+
},
|
|
83
|
+
staleTime: 5 * 60 * 1000,
|
|
84
|
+
gcTime: 10 * 60 * 1000,
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
### 📝 Forms & Schema Validation
|
|
92
|
+
Forms must remain performant and prevent rendering bottleneck.
|
|
93
|
+
- **React Hook Form**: Manage form states with React Hook Form to isolate re-rendering and ensure smooth typing.
|
|
94
|
+
- **Controller integration**: For complex third-party elements (Rich Text Editors, selectors, etc.), wrap them in the RHF `<Controller>` component.
|
|
95
|
+
- **Schema-Driven Validation**: Avoid raw if/else statements for input validation. Use **Zod** to declare data schemas and automatically resolve validator rules:
|
|
96
|
+
```typescript
|
|
97
|
+
import { useForm } from "react-hook-form";
|
|
98
|
+
import { zodResolver } from "@hookform/resolvers/zod";
|
|
99
|
+
import * as z from "zod";
|
|
100
|
+
|
|
101
|
+
const loginSchema = z.object({
|
|
102
|
+
email: z.string().min(1, "Email cannot be empty").email("Invalid email format"),
|
|
103
|
+
password: z.string().min(8, "Password must contain at least 8 characters"),
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
### ⚡ Routing & Code Splitting
|
|
110
|
+
Optimizing bundle loading performance is mandatory.
|
|
111
|
+
- **Code Splitting**: Do not statically import Page Components. Use `React.lazy()` to segment routes into separate chunks loaded only when the route is visited.
|
|
112
|
+
- **Premium Loading**: Wrap all lazy-loaded route elements inside a `<Suspense>` boundary containing a premium Shimmer Skeleton loader or spinner.
|
|
113
|
+
- **Centralized Data Routers**: Configure routes using `createBrowserRouter` (React Router v6+) instead of JSX tags.
|
|
114
|
+
- **Loaders & Actions**: Fetch data parallel to route transitions using router Loaders, and manage data mutations via router Actions.
|
|
115
|
+
- **Route Error Boundaries**: Specify an `errorElement` on all primary route branches to isolate crashes and show a dedicated recovery panel instead of freezing the entire application.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
### 🔍 SEO & Accessibility (a11y)
|
|
120
|
+
- **Dynamic SEO Metadata**: Update document metadata (`title`, `description`, Open Graph tags) on route changes using `react-helmet-async`.
|
|
121
|
+
- **Semantic HTML5 Structure**: Restructure elements using semantic tags: `<header>`, `<nav>`, `<main>`, `<section>`, `<article>`, `<footer>`. Ensure heading tags (`<h1>` to `<h6>`) follow logical hierarchy.
|
|
122
|
+
- **Accessible Images**: All `<img>` tags must possess an `alt` attribute. Provide descriptive alt text for informative images; write `alt=""` for purely decorative images so screen readers skip them.
|
|
123
|
+
- **Icon-Only Controls**: Buttons or links containing only SVG icons (e.g. close buttons, like buttons) must have an explicit `aria-label` or `aria-labelledby` attribute.
|
|
124
|
+
- **Visual Keyboard Focus**: Do not disable the browser focus outline without adding a custom indicator. Interactable elements must display a distinct ring when navigated via keyboard (`:focus-visible`, e.g. `focus-visible:ring-2 focus-visible:ring-primary focus-visible:outline-none`).
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Asynchronous Server-State & API Call Rules
|
|
2
|
+
|
|
3
|
+
This ruleset governs network communication, caching, server-state syncing, and component integration logic to guarantee high performance, security, and clean separation of concerns.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🚫 No Raw useEffect Fetching
|
|
8
|
+
- **Forbidden**: Do not write raw `useEffect` blocks to fetch remote data inside UI components. Raw effects are prone to memory leaks, state sync race conditions, lack of cache validation, and component bloatedness.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 🔌 Centralized API Client
|
|
13
|
+
- **Single Instance**: Route all HTTP/HTTPS outgoing traffic through a unified API client instance (e.g. located at `src/lib/api-client.ts`).
|
|
14
|
+
- **Responsibility**:
|
|
15
|
+
- Configure core variables (e.g. `baseURL`, `timeout`).
|
|
16
|
+
- Attach authorization tokens dynamically via request interceptors.
|
|
17
|
+
- Implement unified global error handling (e.g. intercepting `401 Unauthorized` for token refresh, `403 Forbidden`, `500 Server Error`).
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 🔄 Server-State Management
|
|
22
|
+
- **Library Selection**: Use **TanStack Query (React Query)** or **SWR** to manage asynchronous server-state (fetching, caching, caching invalidation, background updates).
|
|
23
|
+
- **Separation of Concerns**: UI components must never deal with query functions or endpoints. Components only request custom query hooks and render the layout based on:
|
|
24
|
+
- `isLoading`: displays placeholder/Skeleton UI.
|
|
25
|
+
- `isError`: displays recovery panel/notification.
|
|
26
|
+
- `data`: displays final UI.
|
|
27
|
+
- **Hook Encapsulation**: Declare data fetching inside specialized feature-local custom hooks:
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
// src/features/roadmap/api/use-roadmap.ts
|
|
31
|
+
import { useQuery } from "@tanstack/react-query";
|
|
32
|
+
import { apiClient } from "@/lib/api-client";
|
|
33
|
+
|
|
34
|
+
export const useRoadmap = (roadmapId: string) => {
|
|
35
|
+
return useQuery({
|
|
36
|
+
queryKey: ["roadmaps", roadmapId],
|
|
37
|
+
queryFn: async () => {
|
|
38
|
+
const response = await apiClient.get(`/roadmaps/${roadmapId}`);
|
|
39
|
+
return response.data;
|
|
40
|
+
},
|
|
41
|
+
staleTime: 5 * 60 * 1000, // consider data fresh for 5 minutes
|
|
42
|
+
gcTime: 10 * 60 * 1000, // keep in cache for 10 minutes before garbage collection
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
```
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Form Management & Schema Validation Rules
|
|
2
|
+
|
|
3
|
+
This ruleset governs the design and implementation of input fields, submissions, validations, and custom component bindings inside React forms.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## ⚡ Form Performance (React Hook Form)
|
|
8
|
+
- **High Performance**: Use **React Hook Form (RHF)** to handle form state through uncontrolled inputs. This isolates rendering, preventing expensive keypress lag or component bottlenecks on large forms.
|
|
9
|
+
- **Controlled Integration**: For custom/third-party UI controls that cannot be controlled natively (such as Rich Text Editors, custom Select dropdowns, calendar selectors), wrap them within RHF's `<Controller>` component to synchronize state efficiently.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 🛡️ Schema-Driven Validation (Zod)
|
|
14
|
+
- **No manual checking**: Never use complex if/else blocks or custom validation scripts inside submit handlers to check forms.
|
|
15
|
+
- **Zod Resolving**: Use **Zod** to declare form schemas. Bind them to React Hook Form using `zodResolver` to automatically map validator rules and throw clean, localized error messages:
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
// Example feature form implementation
|
|
19
|
+
import { useForm } from "react-hook-form";
|
|
20
|
+
import { zodResolver } from "@hookform/resolvers/zod";
|
|
21
|
+
import * as z from "zod";
|
|
22
|
+
import { cn } from "@/utils/cn";
|
|
23
|
+
|
|
24
|
+
const loginSchema = z.object({
|
|
25
|
+
email: z.string().min(1, "Email cannot be empty").email("Invalid email format"),
|
|
26
|
+
password: z.string().min(8, "Password must contain at least 8 characters"),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
type LoginFields = z.infer<typeof loginSchema>;
|
|
30
|
+
|
|
31
|
+
export const LoginForm = () => {
|
|
32
|
+
const { register, handleSubmit, formState: { errors, isSubmitting } } = useForm<LoginFields>({
|
|
33
|
+
resolver: zodResolver(loginSchema),
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const onSubmit = async (data: LoginFields) => {
|
|
37
|
+
// Execute authentication pipeline
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
|
|
42
|
+
<div>
|
|
43
|
+
<input
|
|
44
|
+
{...register("email")}
|
|
45
|
+
className={cn("border px-3 py-2 rounded", errors.email && "border-red-500")}
|
|
46
|
+
/>
|
|
47
|
+
{errors.email && <p className="text-red-500 text-sm mt-1">{errors.email.message}</p>}
|
|
48
|
+
</div>
|
|
49
|
+
<button type="submit" disabled={isSubmitting} className="px-4 py-2 bg-primary text-white rounded">
|
|
50
|
+
{isSubmitting ? "Processing..." : "Login"}
|
|
51
|
+
</button>
|
|
52
|
+
</form>
|
|
53
|
+
);
|
|
54
|
+
};
|
|
55
|
+
```
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Aesthetics, Styling & Premium UI Rules
|
|
2
|
+
|
|
3
|
+
This ruleset outlines strict requirements for styling, responsiveness, and micro-animations to ensure premium visual excellence and high UX fidelity.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🎨 Tailwind CSS Guidelines
|
|
8
|
+
- **No inline custom CSS**: All interface elements must be constructed using Tailwind utility classes. Do not write inline custom CSS (e.g. style properties or stylesheet files containing static layouts) unless standard utility classes are insufficient.
|
|
9
|
+
- **Dynamic Classes handling**: Never use string interpolation or string addition (e.g. `isActive ? 'bg-blue-500' : 'bg-gray-500'`) to concatenate dynamic class names. This causes CSS specificity issues and classes override failure.
|
|
10
|
+
- **Helper cn() usage**: Always use the custom `cn()` helper utility that integrates `clsx` and `tailwind-merge` for combining dynamic class values:
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
// src/utils/cn.ts
|
|
14
|
+
import { ClassValue, clsx } from "clsx";
|
|
15
|
+
import { twMerge } from "tailwind-merge";
|
|
16
|
+
|
|
17
|
+
export function cn(...inputs: ClassValue[]) {
|
|
18
|
+
return twMerge(clsx(inputs));
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
* **Incorrect (❌ Forbidden)**:
|
|
23
|
+
```tsx
|
|
24
|
+
<button className={`px-4 py-2 text-white ${isActive ? 'bg-blue-500' : 'bg-gray-500'} ${customClass}`}>
|
|
25
|
+
```
|
|
26
|
+
* **Correct (✔️ Required)**:
|
|
27
|
+
```tsx
|
|
28
|
+
<button className={cn("px-4 py-2 text-white transition-all", isActive ? "bg-blue-500" : "bg-gray-500", customClass)}>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 📱 Mobile-First Responsiveness
|
|
34
|
+
- **Default Styles**: Apply classes for the smallest screen size (mobile viewport) by default.
|
|
35
|
+
- **Breakpoint Overrides**: Use breakpoints (`sm:`, `md:`, `lg:`, `xl:`, `2xl:`) to introduce or change styling parameters for larger viewports.
|
|
36
|
+
- **Layout Checking**: Always verify flex direction (`flex-col` vs `flex-row`), grid layout templates (`grid-cols-1` vs `md:grid-cols-3`), padding, margin, and typography scales on both small and large viewports to avoid layout issues.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## ⚡ Micro-animations & Motion
|
|
41
|
+
- **Libraries**: Use `framer-motion` (or the core `motion` package) for micro-animations and physical state changes.
|
|
42
|
+
- **Natural Transitions**:
|
|
43
|
+
- Keep animations fast and responsive: transition duration must range between `0.2s` and `0.3s`.
|
|
44
|
+
- Use natural, fluid easing curves (like `easeOut` or `easeInOut`) or spring-based models for buttons, toggles, hover states, and modals.
|
|
45
|
+
- **Unmounting Transitions**: When components unmount or disappear from the DOM, they must be wrapped within the `<AnimatePresence>` component to ensure exit animations complete smoothly without sudden visual disappearance.
|
|
@@ -1,29 +1,41 @@
|
|
|
1
1
|
# React + TypeScript Style Rules
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
-
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
|
|
9
|
-
## Imports
|
|
10
|
-
- Use `@/` absolute alias paths. Avoid relative parent paths (`../../`).
|
|
11
|
-
- Use `import type` for types.
|
|
12
|
-
- Keep feature internals private; expose via `index.ts` only when needed.
|
|
13
|
-
|
|
14
|
-
## React & JSX
|
|
15
|
-
- Components must focus on UI/composition.
|
|
16
|
-
- Move side effects (fetching, subscriptions, timers) to custom hooks.
|
|
17
|
-
- Use shorthand for boolean props: `<Input disabled />`.
|
|
18
|
-
- Handle async UI states: loading, error, empty, success.
|
|
19
|
-
|
|
20
|
-
## State Management
|
|
21
|
-
- Prefer local component state.
|
|
22
|
-
- Use Context API for stable app-level state (auth, theme).
|
|
23
|
-
- Use Zustand for frequent, cross-feature state updates.
|
|
24
|
-
|
|
25
|
-
## Testing
|
|
26
|
-
- Test user behavior via React Testing Library.
|
|
27
|
-
- Test hooks with complex branching/cleanup.
|
|
28
|
-
- Avoid snapshot testing unless output is small & stable.
|
|
3
|
+
This ruleset outlines base conventions for React + TypeScript projects. Detail guidelines are split into specialized modules which the agent MUST follow:
|
|
4
|
+
- Styling & Aesthetics: See `@premium-ui.md`
|
|
5
|
+
- Data Fetching & Server-State: See `@data-fetching.md`
|
|
6
|
+
- Form Handling & Zod Validation: See `@forms-validation.md`
|
|
7
|
+
- Code Splitting & Routing: See `@routing-splitting.md`
|
|
8
|
+
- SEO & Accessibility (a11y): See `@seo-accessibility.md`
|
|
29
9
|
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 🏷️ Naming Conventions
|
|
13
|
+
- **Components**: PascalCase (e.g. `Navbar.tsx`, `InstallSection.tsx`).
|
|
14
|
+
- **Custom hooks**: camelCase starting with `use` (e.g. `useAuth.ts`, `useCustomers.ts`).
|
|
15
|
+
- **Helpers & variables**: camelCase (e.g. `formatCurrency`, `customerData`).
|
|
16
|
+
- **Types & interfaces**: PascalCase (e.g. `ButtonProps`, `CustomerData`).
|
|
17
|
+
- **Routes**: `<name>.route.tsx` (e.g. `customers.route.tsx`).
|
|
18
|
+
- **Feature Folders**: kebab-case or lowercase (e.g. `billing`, `user-profile`).
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 📦 Imports
|
|
23
|
+
- **Absolute imports**: Always use absolute alias paths starting with `@/` (e.g. `import { Button } from "@/shared/components"`). Avoid deep relative parent imports (e.g. `../../components`).
|
|
24
|
+
- **Type imports**: Always use `import type` when importing types or interfaces to optimize bundle compilation.
|
|
25
|
+
- **Encapsulation**: Keep feature-internal files private. Only export public features via the module `index.ts`.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## ⚙️ React & JSX Guidelines
|
|
30
|
+
- **UI Composition**: Components must focus solely on rendering UI/composition and delegating logic.
|
|
31
|
+
- **Logic Delegation**: Keep side effects (fetching, subscriptions, timers, complex state transitions) inside custom hooks.
|
|
32
|
+
- **Shorthand Props**: Prefer shorthand for boolean flags (e.g. `<Input disabled />` instead of `<Input disabled={true} />`).
|
|
33
|
+
- **Async UI States**: Always explicitly handle async UI transitions (e.g. loading, error, empty, success).
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 💾 State Management
|
|
38
|
+
- **Local State**: Prefer component-local state (`useState`, `useReducer`) for isolated UI interactions.
|
|
39
|
+
- **Context API**: Use the Context API only for low-frequency global values (e.g. theme, locale, user session credentials).
|
|
40
|
+
- **Zustand**: Use Zustand for frequent, cross-feature state updates or complex frontend state orchestration.
|
|
41
|
+
- **Locality**: Keep state as close to the components consuming it as possible before lifting it up.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Code Splitting & Routing Rules
|
|
2
|
+
|
|
3
|
+
This ruleset outlines expectations for structuring router declarations, loading performance optimization, and runtime boundary protections.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## ⚡ Code Splitting (Dynamic Imports)
|
|
8
|
+
- **Dynamic Pages**: Do not statically import full page components at the top level of router files. This bundles the entire application code into a single file and degrades initial page load performance.
|
|
9
|
+
- **Lazy Loading**: Use `React.lazy()` to import page components dynamically, dividing route destinations into separate bundles:
|
|
10
|
+
```typescript
|
|
11
|
+
const DashboardPage = React.lazy(() => import("@/features/dashboard/components/DashboardPage"));
|
|
12
|
+
```
|
|
13
|
+
- **Fallback Suspension**: Wrap lazy-loaded components in a `<Suspense>` component. Provide a high-fidelity shimmer skeleton loader or loading indicator as the fallback property to maintain visual continuity.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 🗺️ Centralized Routing Architecture (React Router v6+)
|
|
18
|
+
- **Data Router**: Define routes as data configuration arrays using `createBrowserRouter` instead of JSX-based `<Routes>` declarations.
|
|
19
|
+
- **Data Loaders**: Utilize router Loaders to pre-fetch required data in parallel with route navigation.
|
|
20
|
+
- **Data Actions**: Utilize router Actions to handle data modification (mutations and forms submissions).
|
|
21
|
+
- **Page Crash Isolation**: Define a dedicated `errorElement` on all primary parent route levels. When a page encounters a crash (e.g. invalid API response, parsing failure), the local `ErrorBoundary` will intercept the error and render a recovery screen without crashing the rest of the application.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# SEO & Accessibility (a11y) Rules
|
|
2
|
+
|
|
3
|
+
This ruleset governs semantic document structures, title/meta tag updates, and accessibility integrations to ensure excellent indexing and keyboard/screen-reader compatibility.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🔍 SEO & Semantic HTML
|
|
8
|
+
- **Dynamic SEO Metadata**: Update document headers dynamically (e.g. `document.title`, description tags, and Open Graph tags) on page transitions using `react-helmet-async` (or the routing framework's metadata controller).
|
|
9
|
+
- **Semantic Structure**: Do not use `<div>` tags for all layouts. Utilize HTML5 semantic elements to establish logical document outline sections:
|
|
10
|
+
- `<header>`: Site or section navigation header.
|
|
11
|
+
- `<nav>`: Core navigation links.
|
|
12
|
+
- `<main>`: Singular primary content of the body.
|
|
13
|
+
- `<section>`: Generic thematic block.
|
|
14
|
+
- `<article>`: Self-contained composition (posts, articles, cards).
|
|
15
|
+
- `<footer>`: Copyright, contact, and structural footers.
|
|
16
|
+
- **Heading Hierarchy**: Align heading tags (`<h1>` to `<h6>`) logically. Ensure there is only one `<h1>` per page, and header levels are nested sequentially.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## ♿ Accessibility (a11y) Standards
|
|
21
|
+
- **Image alt attributes**:
|
|
22
|
+
- All `<img>` tags must have an `alt` attribute.
|
|
23
|
+
- Provide short, descriptive descriptions for informative images.
|
|
24
|
+
- For decorative images, write `alt=""` so that screen readers skip reading their filenames aloud.
|
|
25
|
+
- **Icon-Only Controls**: Every button, link, or clickable component that wraps only an icon (e.g. SVG close button `X`, favorite button heart, menu hamburger icon) must include a descriptive `aria-label` or `aria-labelledby` attribute.
|
|
26
|
+
- **Visual Keyboard Focus**: Do not strip or disable the browser's default blue focus rings without adding an alternative visual indicator. All interactive inputs, buttons, and links must display a prominent border ring when navigated via keyboard:
|
|
27
|
+
```css
|
|
28
|
+
/* Example utility or class selector */
|
|
29
|
+
.focus-indicator:focus-visible {
|
|
30
|
+
outline: none;
|
|
31
|
+
box-shadow: 0 0 0 2px var(--color-primary-offset), 0 0 0 4px var(--color-primary);
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
In Tailwind: `focus-visible:ring-2 focus-visible:ring-primary focus-visible:outline-none`.
|
|
@@ -15,11 +15,11 @@ Steps:
|
|
|
15
15
|
2. Define feature-local types first, including loading, error, empty, and success state shapes.
|
|
16
16
|
3. Create or update the custom hook that owns fetching, side effects, derived state, and cleanup.
|
|
17
17
|
4. Create or update PascalCase components that render UI and delegate logic to hooks.
|
|
18
|
-
5. Add styles using
|
|
18
|
+
5. Add styles using Tailwind CSS utility classes and Framer Motion for micro-animations; do not write custom inline CSS.
|
|
19
19
|
6. Wire the feature into the route or parent component through the smallest public API needed.
|
|
20
20
|
7. Add tests for component behavior and hook logic when branching, async work, or cleanup is present.
|
|
21
21
|
8. Run validations:
|
|
22
|
-
- `
|
|
23
|
-
- `
|
|
24
|
-
- `
|
|
25
|
-
- `
|
|
22
|
+
- `{{runCommand}} lint`
|
|
23
|
+
- `{{runCommand}} typecheck`
|
|
24
|
+
- `{{runCommand}} test`
|
|
25
|
+
- `{{runCommand}} build`
|