flutter-pro-max-cli
Advanced tools
| --- | ||
| description: Xử lý Network Failures, Tránh bão Request, Exponential Backoff, Circuit Breaker | ||
| globs: lib/data/**/*.dart, lib/services/**/*.dart, lib/repositories/**/*.dart | ||
| --- | ||
| # Rule: Network & API Resiliency | ||
| > Kích hoạt: Khi viết API calls, cấu hình HTTP clients (Dio/Http), xử lý timeout | ||
| ## Nguyên tắc: Tránh bão Request | ||
| Khi API lỗi do server quá tải, **TUYỆT ĐỐI KHÔNG** dùng vòng lặp retry vô tội vạ, vì sẽ tạo thêm gánh nặng làm sập hẳn server đang "thở oxy". | ||
| ### Giải pháp bắt buộc | ||
| | Tình huống | Kỹ thuật áp dụng | | ||
| |------------|------------------| | ||
| | Lỗi 5xx / Timeout | **Exponential Backoff**: Tăng thời gian chờ sau mỗi lần thử (vd: 1s, 2s, 4s, 8s...) | | ||
| | Server chết liên tục | **Circuit Breaker**: Ngắt hoàn toàn request trong 1 khoảng thời gian nhất định để server phục hồi. | | ||
| | Mạng chập chờn | Cảnh báo UI thanh lịch (Snackbar / Retry button), không quăng exception đỏ màn hình. | | ||
| > 🔴 **Luôn tự hỏi:** *"Nếu API endpoint này sập, app của mình có sập theo hay không bị treo cứng không?"* |
| --- | ||
| description: Tư duy Offline-First, Cache dữ liệu, Đồng bộ ngầm, Xử lý khi mất mạng | ||
| globs: lib/data/**/*.dart, lib/repositories/**/*.dart, lib/presentation/**/*.dart | ||
| --- | ||
| # Rule: Offline-First Experience | ||
| > Kích hoạt: Khi thiết kế luồng dữ liệu, fetch data cho màn hình chính (Dashboard, List) | ||
| ## Nguyên tắc: Sống sót không cần mạng | ||
| Khi thiết bị lọt vào vùng mất mạng, **TUYỆT ĐỐI KHÔNG** để vòng xoay loading chạy vô tận hoặc văng ra màn hình trắng trơn. | ||
| ### Kiến trúc Offline-First | ||
| 1. **Lớp Cache Cache:** Bắt buộc có Local DB (SQLite, Isar, Hive) để lưu dữ liệu quan trọng. | ||
| 2. **Luồng ưu tiên Local:** | ||
| - Khi mở màn hình: Load data từ Local DB hiển thị lên UI **ngay lập tức**. | ||
| - Kích hoạt đồng bộ ngầm (background fetch) với server. | ||
| - Khi có data mới từ server: Cập nhật DB nội bộ, luồng stream tự động đẩy data thiết kế mới lên UI một cách mượt mà. | ||
| ### Checklist Offline | ||
| - [ ] Mở app khi ngắt Wi-Fi vẫn thấy được dữ liệu cũ. | ||
| - [ ] Thao tác (Like, Xoá, Nút bấm) được lưu tạm hàng đợi (Queue) để sync lại khi có mạng. | ||
| - [ ] Có thông báo tinh tế báo hiệu đang xài ở chế độ Offline. |
| --- | ||
| description: Xử lý Graceful Degradation, Fallback UI khi component/dữ liệu lỗi | ||
| globs: lib/presentation/**/*.dart, lib/ui/**/*.dart, lib/widgets/**/*.dart | ||
| --- | ||
| # Rule: Graceful Degradation (UI Fallback) | ||
| > Kích hoạt: Khi build UI components, handle Image Network, List Items | ||
| ## Nguyên tắc: Lỗi cục bộ không được sập toàn cục | ||
| Khi một thành phần UI hoặc dữ liệu bị fail, **đừng làm sập cả màn hình**. Tính thanh lịch của app nằm ở việc fallback giấu lỗi. | ||
| ### Các Fallback Pattern Bắt Buộc | ||
| | Lỗi Component | Giải pháp UI (Fallback) | | ||
| |---------------|-------------------------| | ||
| | Hình ảnh (Avatar, Banner) lỗi tải (CDN down/404) | Hiển thị Default Image Icon, Placeholder, hoặc Chữ cái đầu của Tên (Initials Avatar). | | ||
| | 1 Item lỗi trong ListView | Hiển thị `ErrorItemWidget` nhỏ cho riêng dòng đó, thay vì ném Exception break toàn list. | | ||
| | Font chữ không tải được | Cấu hình Fallback về System Font mặc định. | | ||
| | Widget tương tác lỗi | Vô hiệu hoá (Disable) nút bấm đó và đổi màu xám thay vì crash khi bấm. | | ||
| > 🔴 **Quy tắc vàng:** Luôn định nghĩa thuộc tính `errorBuilder` cho mọi Network Image. |
| --- | ||
| description: Xử lý Vòng đời thiêt bị (Lifecycle), Orientation Change, Background State | ||
| globs: lib/presentation/**/*.dart, lib/logic/**/*.dart, lib/providers/**/*.dart | ||
| --- | ||
| # Rule: State & Lifecycle Resilience | ||
| > Kích hoạt: Khi quản lý State (Bloc/Provider/Riverpod), xử lý orientation, handle app background state | ||
| ## Nguyên tắc: Chống hao pin & lag vô ích | ||
| Quản lý vòng đời (lifecycle) kém sẽ làm máy nóng, lag và hao pin nhanh chóng, đặc biệt trên thiết bị Android yếu. | ||
| ### Xử lý Lifecycle Events | ||
| 1. **Xoay màn hình (Orientation Change):** | ||
| - Việc xoay dọc/ngang không được làm trigger lại các API requests. | ||
| - State phải được giữ nguyên bằng cơ chế State Management chuyên biệt, widget chỉ rebuild UI Layout. | ||
| 2. **App chuyển vào nền (Backgrounded):** | ||
| - Lập tức ngắt (Pause/Cancel) các Streams liên tục (như vị trí GPS, socket). | ||
| - Tạm dừng các `Timer` đếm ngược. | ||
| 3. **Memory Warning (Cảnh báo RAM):** | ||
| - Clear cache hình ảnh trong bộ nhớ (ví dụ: xoá cache network images). | ||
| - Giải phóng tài nguyên memory lớn không dùng tới. | ||
| ### Rò rỉ bộ nhớ (Memory Leaks) | ||
| - Luôn gọi `dispose()` trên các Controller (AnimationController, ScrollController, TextEditingController). | ||
| - Đảm bảo huỷ (cancel) StreamSubscription khi Widget bị huỷ. |
@@ -0,1 +1,6 @@ | ||
| --- | ||
| description: Tự động sử dụng skill search trước khi viết code Flutter | ||
| globs: * | ||
| --- | ||
| # Rule: Tự động sử dụng Skill | ||
@@ -2,0 +7,0 @@ |
@@ -0,1 +1,6 @@ | ||
| --- | ||
| description: Tiêu chuẩn Code Quality, Think-Before-Code, Hard Constraints | ||
| globs: lib/**/*.dart | ||
| --- | ||
| # Rule: Code Quality & Hard Constraints | ||
@@ -2,0 +7,0 @@ |
@@ -0,1 +1,6 @@ | ||
| --- | ||
| description: Quy trình làm việc ABCR (Audit-Block-Critique-Refactor) khi nhận request | ||
| globs: * | ||
| --- | ||
| # Rule: Interaction Flow (ABCR) | ||
@@ -2,0 +7,0 @@ |
@@ -0,1 +1,6 @@ | ||
| --- | ||
| description: Đảm bảo tính nhất quán (Consistency) của UI, Design Tokens, Widget Patterns | ||
| globs: lib/presentation/**/*.dart, lib/ui/**/*.dart, lib/widgets/**/*.dart | ||
| --- | ||
| # Rule: App Consistency | ||
@@ -2,0 +7,0 @@ |
@@ -0,1 +1,6 @@ | ||
| --- | ||
| description: Xử lý lỗi, Try-catch, Result pattern, Không fail im lặng | ||
| globs: lib/data/**/*.dart, lib/services/**/*.dart, lib/repositories/**/*.dart, lib/domain/**/*.dart | ||
| --- | ||
| # Rule: Error Handling | ||
@@ -2,0 +7,0 @@ |
@@ -0,1 +1,6 @@ | ||
| --- | ||
| description: Viết Unit Test, Widget Test, Integration Test | ||
| globs: test/**/*.dart, lib/**/*.dart | ||
| --- | ||
| # Rule: Testing | ||
@@ -2,0 +7,0 @@ |
@@ -0,1 +1,6 @@ | ||
| --- | ||
| description: Tối ưu hiệu năng, const, ListView.builder, Async computation | ||
| globs: lib/presentation/**/*.dart, lib/ui/**/*.dart, lib/widgets/**/*.dart | ||
| --- | ||
| # Rule: Performance | ||
@@ -40,2 +45,12 @@ | ||
| ### 4. Performance (Bài toán Scale) | ||
| Code chạy mượt ở 10 items có thể crash app ở 10,000 items. Lỗi tràn RAM (OOM - Out of Memory) thường âm thầm và khó debug. | ||
| | Quy mô | Giải pháp Render | | ||
| |--------|------------------| | ||
| | Ít items (< 20) | `Column` bọc trong `SingleChildScrollView` (Có thể chấp nhận) | | ||
| | Nhiều items (Hàng ngàn) | **BẮT BUỘC** dùng `ListView.builder` kết hợp Pagination/Infinite Scroll | | ||
| | Bảng dữ liệu lớn | PaginatedDataTable hoặc Virtualized Lists | | ||
| ### Checklist trước ship | ||
@@ -45,5 +60,5 @@ | ||
| - [ ] ListView/GridView dùng `.builder` hoặc `.separated` | ||
| - [ ] Màn hình danh sách có hỗ trợ phân trang (Pagination) nếu data có thể phình to | ||
| - [ ] Không có `print()` còn sót (dùng `developer.log`) | ||
| - [ ] Images có loading/error builders | ||
| > 🔴 **Nếu list > 20 items → BẮT BUỘC dùng `.builder`.** Không exceptions. | ||
| > 🔴 **Nếu list > 20 items → BẮT BUỘC dùng `.builder`.** Luôn tự hỏi: *"Nếu user có 1 triệu record thì sao?"* |
@@ -0,1 +1,6 @@ | ||
| --- | ||
| description: Bảo mật, API Keys, Authentication, Data Protection | ||
| globs: lib/data/**/*.dart, lib/services/**/*.dart, lib/core/env/*.dart | ||
| --- | ||
| # Rule: Security | ||
@@ -2,0 +7,0 @@ |
@@ -0,1 +1,6 @@ | ||
| --- | ||
| description: Quản lý state theo cấp độ (Native-first), ValueNotifier | ||
| globs: lib/presentation/**/*.dart, lib/ui/**/*.dart | ||
| --- | ||
| # Rule: State Management | ||
@@ -2,0 +7,0 @@ |
@@ -0,1 +1,6 @@ | ||
| --- | ||
| description: Quy tắc đặt tên (Naming), Cấu trúc thư mục (Folder Structure), Git Commit | ||
| globs: lib/**/*.dart, test/**/*.dart | ||
| --- | ||
| # Rule: Naming & Conventions | ||
@@ -2,0 +7,0 @@ |
@@ -0,1 +1,6 @@ | ||
| --- | ||
| description: Tiêu chuẩn tiếp cận (Accessibility), Semantics, Contrast | ||
| globs: lib/presentation/**/*.dart, lib/widgets/**/*.dart | ||
| --- | ||
| # Rule: Accessibility | ||
@@ -2,0 +7,0 @@ |
@@ -175,2 +175,6 @@ import { readFile, mkdir, writeFile, cp, access, readdir } from 'node:fs/promises'; | ||
| } | ||
| // Helper to strip YAML frontmatter for appended files | ||
| const stripFrontmatter = (content) => { | ||
| return content.replace(/^---\n[\s\S]*?\n---\n+/, ''); | ||
| }; | ||
| // Concatenate all rule files | ||
@@ -180,3 +184,3 @@ const allRules = ['# Flutter Pro Max — Agent Rules\n']; | ||
| const content = await readFile(join(rulesDir, file), 'utf-8'); | ||
| allRules.push(content); | ||
| allRules.push(stripFrontmatter(content)); | ||
| } | ||
@@ -189,5 +193,8 @@ await writeFile(rulesFilePath, existing + allRules.join('\n---\n\n'), 'utf-8'); | ||
| await mkdir(rulesTargetDir, { recursive: true }); | ||
| // If rulesFile.path ends with .mdc, we use .mdc extension for files | ||
| const useMdc = config.rulesFile.path.endsWith('.mdc'); | ||
| for (const file of ruleFiles) { | ||
| const content = await readFile(join(rulesDir, file), 'utf-8'); | ||
| const targetPath = join(rulesTargetDir, file); | ||
| const targetExt = useMdc ? '.mdc' : '.md'; | ||
| const targetPath = join(rulesTargetDir, file.replace(/\.md$/, targetExt)); | ||
| await writeFile(targetPath, content, 'utf-8'); | ||
@@ -194,0 +201,0 @@ } |
+1
-1
| { | ||
| "name": "flutter-pro-max-cli", | ||
| "version": "2.3.4", | ||
| "version": "2.3.5", | ||
| "description": "CLI to install Flutter Pro Max skill for AI coding assistants", | ||
@@ -5,0 +5,0 @@ "type": "module", |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
456453
1.74%77
5.48%2686
0.26%