flutter-pro-max-cli 2.1.0 → 2.1.4
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/README.md +39 -19
- package/assets/templates/base/quick-reference.md +67 -7
- package/assets/templates/base/skill-content-10k.md +220 -0
- package/assets/templates/base/skill-content-4k.md +110 -0
- package/assets/templates/base/skill-content.md +283 -19
- package/assets/templates/platforms/agent.json +2 -1
- package/assets/templates/platforms/claude.json +1 -0
- package/assets/templates/platforms/codebuddy.json +2 -1
- package/assets/templates/platforms/codex.json +2 -1
- package/assets/templates/platforms/continue.json +2 -1
- package/assets/templates/platforms/copilot.json +2 -1
- package/assets/templates/platforms/cursor.json +1 -0
- package/assets/templates/platforms/gemini.json +3 -2
- package/assets/templates/platforms/junie.json +19 -0
- package/assets/templates/platforms/kiro.json +1 -0
- package/assets/templates/platforms/opencode.json +2 -1
- package/assets/templates/platforms/qoder.json +1 -0
- package/assets/templates/platforms/roocode.json +1 -0
- package/assets/templates/platforms/trae.json +2 -1
- package/assets/templates/platforms/vscode.json +19 -0
- package/assets/templates/platforms/windsurf.json +1 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.js +3 -1
- package/dist/utils/detect.js +4 -0
- package/dist/utils/template.js +5 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -68,29 +68,36 @@ flutter-pro-max update --ai claude
|
|
|
68
68
|
|
|
69
69
|
## 🤖 Supported AI Assistants
|
|
70
70
|
|
|
71
|
-
This CLI bridges the gap between the Flutter Pro Max knowledge base and your development tools:
|
|
72
|
-
|
|
73
|
-
| Assistant | Type Flag | Install Type |
|
|
74
|
-
|
|
75
|
-
| **Claude Code** | `claude` | Full |
|
|
76
|
-
| **Codex CLI** | `codex` | Full |
|
|
77
|
-
| **Continue** | `continue` | Full |
|
|
78
|
-
| **
|
|
79
|
-
| **
|
|
80
|
-
| **
|
|
81
|
-
| **
|
|
82
|
-
| **
|
|
83
|
-
| **
|
|
84
|
-
| **
|
|
85
|
-
| **
|
|
86
|
-
| **
|
|
87
|
-
| **
|
|
88
|
-
| **
|
|
71
|
+
This CLI bridges the gap between the Flutter Pro Max knowledge base and your development tools (16 platforms):
|
|
72
|
+
|
|
73
|
+
| Assistant | Type Flag | Install Type | Template | Limit |
|
|
74
|
+
|-----------|-----------|--------------|----------|-------|
|
|
75
|
+
| **Claude Code** | `claude` | Full | Full (~15KB) | No Limit |
|
|
76
|
+
| **Codex CLI** | `codex` | Full | Full (~15KB) | No Limit |
|
|
77
|
+
| **Continue** | `continue` | Full | Full (~15KB) | No Limit |
|
|
78
|
+
| **JetBrains AI (Junie)** | `junie` | Full | Full (~15KB) | No Limit |
|
|
79
|
+
| **Gemini CLI** | `gemini` | Full | Full (~15KB) | 1M+ Tokens |
|
|
80
|
+
| **OpenCode** | `opencode` | Full | Full (~15KB) | No Limit |
|
|
81
|
+
| **CodeBuddy** | `codebuddy` | Full | Full (~15KB) | No Limit |
|
|
82
|
+
| **Trae** | `trae` | Full | Full (~15KB) | No Limit |
|
|
83
|
+
| **Antigravity (Google)** | `antigravity` | Full | Compact (~5KB) | **12,000 chars** |
|
|
84
|
+
| **Cursor** | `cursor` | Reference | Full (~13KB) | No Limit |
|
|
85
|
+
| **Windsurf** | `windsurf` | Reference | Full (~13KB) | No Limit |
|
|
86
|
+
| **GitHub Copilot** | `copilot` | Reference | Mini (~2KB) | **~4,000 chars** |
|
|
87
|
+
| **VS Code** | `vscode` | Reference | Mini (~2KB) | Unknown |
|
|
88
|
+
| **Kiro** | `kiro` | Reference | Full (~13KB) | No Limit |
|
|
89
|
+
| **RooCode** | `roocode` | Reference | Full (~13KB) | No Limit |
|
|
90
|
+
| **Qodo/Qoder** | `qoder` | Reference | Full (~13KB) | No Limit |
|
|
89
91
|
|
|
90
92
|
**Install Types:**
|
|
91
93
|
- **Full**: Data và scripts nằm trong skill folder (standalone, ~500KB)
|
|
92
94
|
- **Reference**: Skill file trỏ đến `.shared/` folder chung (tiết kiệm dung lượng khi dùng nhiều assistants)
|
|
93
95
|
|
|
96
|
+
**Templates (theo platform limits - dựa trên [Flutter AI Rules](https://docs.flutter.dev/ai/ai-rules)):**
|
|
97
|
+
- **Full (~15KB)**: Đầy đủ rules, code examples, Material 3 theming, accessibility
|
|
98
|
+
- **Compact (~5KB)**: Core rules, essential patterns (Antigravity 12k limit)
|
|
99
|
+
- **Mini (~2KB)**: Essential rules only (Copilot ~4k limit)
|
|
100
|
+
|
|
94
101
|
---
|
|
95
102
|
|
|
96
103
|
## 📊 What Gets Installed
|
|
@@ -168,7 +175,11 @@ cli/
|
|
|
168
175
|
│ ├── scripts/ # Python search scripts
|
|
169
176
|
│ └── templates/
|
|
170
177
|
│ ├── base/ # Markdown templates
|
|
171
|
-
│
|
|
178
|
+
│ │ ├── skill-content.md # Full template (~13KB)
|
|
179
|
+
│ │ ├── skill-content-10k.md # Compact (~5KB)
|
|
180
|
+
│ │ ├── skill-content-4k.md # Mini (~2KB)
|
|
181
|
+
│ │ └── quick-reference.md # Add-on (~2KB)
|
|
182
|
+
│ └── platforms/ # 16 platform JSON configs
|
|
172
183
|
├── package.json
|
|
173
184
|
└── tsconfig.json
|
|
174
185
|
```
|
|
@@ -182,6 +193,15 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
182
193
|
|
|
183
194
|
## 📝 Changelog
|
|
184
195
|
|
|
196
|
+
### v2.2.0 (2026-02-02)
|
|
197
|
+
- **Flutter AI Rules**: Cập nhật theo [Flutter Official AI Rules](https://docs.flutter.dev/ai/ai-rules)
|
|
198
|
+
- **Platform Limits**: Tạo templates phù hợp với giới hạn từng platform
|
|
199
|
+
- `skill-content.md` (~13KB) - Full template
|
|
200
|
+
- `skill-content-10k.md` (~5KB) - Compact (Antigravity)
|
|
201
|
+
- `skill-content-4k.md` (~2KB) - Mini (Copilot, VS Code)
|
|
202
|
+
- **New Platforms**: JetBrains AI (Junie), VS Code
|
|
203
|
+
- **Native-First State**: ValueNotifier/ChangeNotifier mặc định
|
|
204
|
+
|
|
185
205
|
### v2.1.0 (2026-01-27)
|
|
186
206
|
- **Type Safety**: Full Python type hints cho Pylance strict mode
|
|
187
207
|
- **Python 3.10+**: Minimum Python version updated
|
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
|
|
2
|
-
---
|
|
3
|
-
|
|
4
2
|
## Quick Reference
|
|
5
3
|
|
|
4
|
+
### AI Tools Commands
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
# Format code (ALWAYS run after changes)
|
|
8
|
+
dart format .
|
|
9
|
+
|
|
10
|
+
# Auto-fix common issues
|
|
11
|
+
dart fix --apply
|
|
12
|
+
|
|
13
|
+
# Analyze with lints
|
|
14
|
+
flutter analyze .
|
|
15
|
+
|
|
16
|
+
# Run tests
|
|
17
|
+
flutter test .
|
|
18
|
+
|
|
19
|
+
# Build runner for code generation
|
|
20
|
+
dart run build_runner build --delete-conflicting-outputs
|
|
21
|
+
```
|
|
22
|
+
|
|
6
23
|
### Search Commands
|
|
7
24
|
|
|
8
25
|
```bash
|
|
@@ -12,16 +29,32 @@ python3 {{SCRIPT_PATH}}/search.py "ListView" --top 5
|
|
|
12
29
|
# Specific domain
|
|
13
30
|
python3 {{SCRIPT_PATH}}/search.py "network http" --domain package --top 5
|
|
14
31
|
|
|
15
|
-
# Stack filter
|
|
16
|
-
python3 {{SCRIPT_PATH}}/search.py "state" --stack
|
|
32
|
+
# Stack filter (native-first: valuenotifier, changenotifier)
|
|
33
|
+
python3 {{SCRIPT_PATH}}/search.py "state" --stack provider --top 5
|
|
17
34
|
|
|
18
35
|
# JSON output
|
|
19
36
|
python3 {{SCRIPT_PATH}}/search.py "login" --json --top 3
|
|
20
37
|
```
|
|
21
38
|
|
|
39
|
+
### Package Management
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Add dependency
|
|
43
|
+
flutter pub add <package_name>
|
|
44
|
+
|
|
45
|
+
# Add dev dependency
|
|
46
|
+
flutter pub add dev:<package_name>
|
|
47
|
+
|
|
48
|
+
# Add override
|
|
49
|
+
flutter pub add override:<package_name>:<version>
|
|
50
|
+
|
|
51
|
+
# Remove dependency
|
|
52
|
+
dart pub remove <package_name>
|
|
53
|
+
```
|
|
54
|
+
|
|
22
55
|
### Example Workflow
|
|
23
56
|
|
|
24
|
-
**User Request:** "Tạo màn hình đăng nhập
|
|
57
|
+
**User Request:** "Tạo màn hình đăng nhập"
|
|
25
58
|
|
|
26
59
|
1. **Search widgets:**
|
|
27
60
|
```bash
|
|
@@ -35,7 +68,34 @@ python3 {{SCRIPT_PATH}}/search.py "login" --json --top 3
|
|
|
35
68
|
|
|
36
69
|
3. **Search packages:**
|
|
37
70
|
```bash
|
|
38
|
-
python3 {{SCRIPT_PATH}}/search.py "validation" --domain package --
|
|
71
|
+
python3 {{SCRIPT_PATH}}/search.py "validation" --domain package --top 5
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
4. **Apply results** với native state management (ValueNotifier/ChangeNotifier)
|
|
75
|
+
|
|
76
|
+
5. **Validate:**
|
|
77
|
+
```bash
|
|
78
|
+
dart format . && flutter analyze . && flutter test .
|
|
39
79
|
```
|
|
40
80
|
|
|
41
|
-
|
|
81
|
+
### Quick Code Templates
|
|
82
|
+
|
|
83
|
+
```dart
|
|
84
|
+
// Structured Logging (use instead of print)
|
|
85
|
+
import 'dart:developer' as developer;
|
|
86
|
+
developer.log('Message', name: 'app.module', error: e, stackTrace: s);
|
|
87
|
+
|
|
88
|
+
// JSON Model
|
|
89
|
+
@JsonSerializable(fieldRename: FieldRename.snake)
|
|
90
|
+
class User {
|
|
91
|
+
final String firstName;
|
|
92
|
+
User({required this.firstName});
|
|
93
|
+
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// GoRouter Setup
|
|
97
|
+
final _router = GoRouter(routes: [
|
|
98
|
+
GoRoute(path: '/', builder: (_, __) => const HomeScreen()),
|
|
99
|
+
]);
|
|
100
|
+
MaterialApp.router(routerConfig: _router);
|
|
101
|
+
```
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
````markdown
|
|
2
|
+
# {{TITLE}}
|
|
3
|
+
|
|
4
|
+
{{DESCRIPTION}}
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 🏛️ ROLE: Flutter Expert
|
|
9
|
+
|
|
10
|
+
Expert Flutter & Dart Developer. Build **beautiful, performant, maintainable** applications.
|
|
11
|
+
|
|
12
|
+
### 🛠️ AI Tools Integration
|
|
13
|
+
|
|
14
|
+
| Tool | Purpose | Usage |
|
|
15
|
+
|------|---------|-------|
|
|
16
|
+
| `dart_format` | Format code | ALWAYS run after changes |
|
|
17
|
+
| `dart_fix` | Auto-fix errors | Run before commit |
|
|
18
|
+
| `flutter analyze` | Lint check | Catch issues early |
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 📐 CORE PHILOSOPHIES
|
|
23
|
+
|
|
24
|
+
### SOLID Principles (Mandatory)
|
|
25
|
+
|
|
26
|
+
| Principle | Rule | Example |
|
|
27
|
+
|-----------|------|---------|
|
|
28
|
+
| **S - Single Responsibility** | 1 class = 1 job | `LoginUseCase` only handles login |
|
|
29
|
+
| **O - Open/Closed** | Extend, don't modify | Use `abstract class` over `if-else` |
|
|
30
|
+
| **L - Liskov Substitution** | Subtypes replace base | `GoogleAuth extends AuthProvider` |
|
|
31
|
+
| **I - Interface Segregation** | No forced dependencies | Split `Readable` and `Writable` |
|
|
32
|
+
| **D - Dependency Inversion** | Depend on abstractions | Inject interface, not implementation |
|
|
33
|
+
|
|
34
|
+
### Pragmatic Rules
|
|
35
|
+
|
|
36
|
+
| Rule | Action |
|
|
37
|
+
|------|--------|
|
|
38
|
+
| **DRY** | Logic repeated >2x → Extract |
|
|
39
|
+
| **KISS** | Prefer simplest solution |
|
|
40
|
+
| **YAGNI** | Build only what's needed now |
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## ⛔ HARD CONSTRAINTS
|
|
45
|
+
|
|
46
|
+
### NO God Classes/Files
|
|
47
|
+
|
|
48
|
+
| Constraint | Limit | Action |
|
|
49
|
+
|------------|-------|--------|
|
|
50
|
+
| Public methods | ≤10 | 🔴 REFACTOR |
|
|
51
|
+
| Lines of logic | ≤200 | 🔴 REFACTOR |
|
|
52
|
+
| File size | ≤300 lines | 🔴 SPLIT |
|
|
53
|
+
| Classes per file | 1 main | 🔴 SEPARATE |
|
|
54
|
+
|
|
55
|
+
### Code Quality Standards
|
|
56
|
+
|
|
57
|
+
| Rule | Standard |
|
|
58
|
+
|------|----------|
|
|
59
|
+
| Line length | ≤80 characters |
|
|
60
|
+
| Naming | `PascalCase` types, `camelCase` members, `snake_case` files |
|
|
61
|
+
| Functions | <20 lines, single purpose |
|
|
62
|
+
| Null Safety | Sound. Avoid `!` unless guaranteed |
|
|
63
|
+
| Logging | `dart:developer` log(), NEVER print() |
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 🎯 DART BEST PRACTICES
|
|
68
|
+
|
|
69
|
+
### Async/Await
|
|
70
|
+
```dart
|
|
71
|
+
Future<User> fetchUser() async {
|
|
72
|
+
try {
|
|
73
|
+
final response = await api.getUser();
|
|
74
|
+
return User.fromJson(response);
|
|
75
|
+
} catch (e, s) {
|
|
76
|
+
developer.log('Failed', error: e, stackTrace: s);
|
|
77
|
+
rethrow;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Pattern Matching (Dart 3+)
|
|
83
|
+
```dart
|
|
84
|
+
// Records
|
|
85
|
+
(String name, int age) getUserInfo() => ('John', 25);
|
|
86
|
+
|
|
87
|
+
// Switch expressions
|
|
88
|
+
String describe(Shape s) => switch (s) {
|
|
89
|
+
Circle(radius: var r) => 'Circle $r',
|
|
90
|
+
Rectangle(w: var w, h: var h) => 'Rect ${w}x$h',
|
|
91
|
+
};
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## 🔧 FLUTTER STANDARDS
|
|
97
|
+
|
|
98
|
+
### State Management (Native-First)
|
|
99
|
+
```dart
|
|
100
|
+
// ValueNotifier for simple state
|
|
101
|
+
final counter = ValueNotifier<int>(0);
|
|
102
|
+
ValueListenableBuilder<int>(
|
|
103
|
+
valueListenable: counter,
|
|
104
|
+
builder: (_, value, __) => Text('Count: $value'),
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
// ChangeNotifier for complex state
|
|
108
|
+
class CartNotifier extends ChangeNotifier {
|
|
109
|
+
final List<Item> _items = [];
|
|
110
|
+
void addItem(Item item) {
|
|
111
|
+
_items.add(item);
|
|
112
|
+
notifyListeners();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
> ⚠️ NO Riverpod/Bloc/GetX unless explicitly requested
|
|
117
|
+
|
|
118
|
+
### Routing (GoRouter)
|
|
119
|
+
```dart
|
|
120
|
+
final router = GoRouter(routes: [
|
|
121
|
+
GoRoute(path: '/', builder: (_, __) => const HomeScreen()),
|
|
122
|
+
GoRoute(
|
|
123
|
+
path: 'details/:id',
|
|
124
|
+
builder: (_, state) => DetailScreen(id: state.pathParameters['id']!),
|
|
125
|
+
),
|
|
126
|
+
]);
|
|
127
|
+
MaterialApp.router(routerConfig: router);
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### JSON Serialization
|
|
131
|
+
```dart
|
|
132
|
+
@JsonSerializable(fieldRename: FieldRename.snake)
|
|
133
|
+
class User {
|
|
134
|
+
final String firstName;
|
|
135
|
+
User({required this.firstName});
|
|
136
|
+
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## 🎨 THEMING (Material 3)
|
|
143
|
+
|
|
144
|
+
```dart
|
|
145
|
+
final lightTheme = ThemeData(
|
|
146
|
+
colorScheme: ColorScheme.fromSeed(
|
|
147
|
+
seedColor: Colors.deepPurple,
|
|
148
|
+
brightness: Brightness.light,
|
|
149
|
+
),
|
|
150
|
+
useMaterial3: true,
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
final darkTheme = ThemeData(
|
|
154
|
+
colorScheme: ColorScheme.fromSeed(
|
|
155
|
+
seedColor: Colors.deepPurple,
|
|
156
|
+
brightness: Brightness.dark,
|
|
157
|
+
),
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
MaterialApp(
|
|
161
|
+
theme: lightTheme,
|
|
162
|
+
darkTheme: darkTheme,
|
|
163
|
+
themeMode: ThemeMode.system,
|
|
164
|
+
);
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Network Images
|
|
168
|
+
```dart
|
|
169
|
+
Image.network(
|
|
170
|
+
'https://example.com/img.png',
|
|
171
|
+
loadingBuilder: (ctx, child, prog) =>
|
|
172
|
+
prog == null ? child : const CircularProgressIndicator(),
|
|
173
|
+
errorBuilder: (ctx, err, stack) => const Icon(Icons.error),
|
|
174
|
+
);
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## ⚡ PERFORMANCE
|
|
180
|
+
|
|
181
|
+
| Practice | Guideline |
|
|
182
|
+
|----------|-----------|
|
|
183
|
+
| `const` constructors | Use everywhere possible |
|
|
184
|
+
| `ListView.builder` | For long lists |
|
|
185
|
+
| `compute()` | For heavy tasks (JSON parsing) |
|
|
186
|
+
| `SizedBox` | Prefer over `Container` for spacing |
|
|
187
|
+
| Build methods | Keep pure, no side effects |
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## ♿ ACCESSIBILITY
|
|
192
|
+
|
|
193
|
+
| Requirement | Standard |
|
|
194
|
+
|-------------|----------|
|
|
195
|
+
| Contrast | Minimum 4.5:1 for text |
|
|
196
|
+
| Large Text | Minimum 3:1 |
|
|
197
|
+
| Dynamic Scaling | Test up to 200% |
|
|
198
|
+
| Semantics | Label all interactive elements |
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## ✅ PRE-DELIVERY CHECKLIST
|
|
203
|
+
|
|
204
|
+
### Architecture
|
|
205
|
+
- [ ] No God Class (≤10 methods, ≤200 lines)
|
|
206
|
+
- [ ] No God File (≤300 lines)
|
|
207
|
+
- [ ] SOLID compliance
|
|
208
|
+
|
|
209
|
+
### Code Quality
|
|
210
|
+
- [ ] `const` constructors
|
|
211
|
+
- [ ] Sound Null Safety
|
|
212
|
+
- [ ] `dart_format` applied
|
|
213
|
+
- [ ] `flutter analyze` passed
|
|
214
|
+
|
|
215
|
+
### Testing
|
|
216
|
+
- [ ] Unit tests for domain
|
|
217
|
+
- [ ] Widget tests for UI
|
|
218
|
+
- [ ] Integration tests for E2E
|
|
219
|
+
{{QUICK_REFERENCE}}
|
|
220
|
+
````
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
````markdown
|
|
2
|
+
# {{TITLE}}
|
|
3
|
+
|
|
4
|
+
{{DESCRIPTION}}
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Role: Flutter Expert
|
|
9
|
+
|
|
10
|
+
Expert Flutter & Dart Developer. Build **beautiful, performant, maintainable** apps.
|
|
11
|
+
|
|
12
|
+
### AI Tools
|
|
13
|
+
- `dart_format` - ALWAYS format code
|
|
14
|
+
- `dart_fix` - Auto-fix errors
|
|
15
|
+
- `flutter analyze` - Lint check
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Core Rules
|
|
20
|
+
|
|
21
|
+
### SOLID (Mandatory)
|
|
22
|
+
| Principle | Rule |
|
|
23
|
+
|-----------|------|
|
|
24
|
+
| **S** | 1 class = 1 responsibility |
|
|
25
|
+
| **O** | Open for extension, closed for modification |
|
|
26
|
+
| **L** | Subtypes replaceable for base types |
|
|
27
|
+
| **I** | No forced unused dependencies |
|
|
28
|
+
| **D** | Depend on abstractions |
|
|
29
|
+
|
|
30
|
+
### Hard Limits
|
|
31
|
+
| Constraint | Limit |
|
|
32
|
+
|------------|-------|
|
|
33
|
+
| God Class | ≤10 methods, ≤200 lines |
|
|
34
|
+
| God File | ≤300 lines |
|
|
35
|
+
| Functions | <20 lines |
|
|
36
|
+
| Line length | ≤80 chars |
|
|
37
|
+
|
|
38
|
+
### Naming
|
|
39
|
+
- `PascalCase` - Types/Classes
|
|
40
|
+
- `camelCase` - Members/Variables
|
|
41
|
+
- `snake_case` - Files
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Flutter Standards
|
|
46
|
+
|
|
47
|
+
### State Management (Native-First)
|
|
48
|
+
```dart
|
|
49
|
+
// ValueNotifier for simple state
|
|
50
|
+
final counter = ValueNotifier<int>(0);
|
|
51
|
+
ValueListenableBuilder(
|
|
52
|
+
valueListenable: counter,
|
|
53
|
+
builder: (_, value, __) => Text('$value'),
|
|
54
|
+
);
|
|
55
|
+
```
|
|
56
|
+
> ⚠️ NO Riverpod/Bloc/GetX unless requested
|
|
57
|
+
|
|
58
|
+
### Routing (GoRouter)
|
|
59
|
+
```dart
|
|
60
|
+
final router = GoRouter(routes: [
|
|
61
|
+
GoRoute(path: '/', builder: (_, __) => HomeScreen()),
|
|
62
|
+
]);
|
|
63
|
+
MaterialApp.router(routerConfig: router);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Theming (Material 3)
|
|
67
|
+
```dart
|
|
68
|
+
ThemeData(
|
|
69
|
+
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
|
|
70
|
+
useMaterial3: true,
|
|
71
|
+
);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Performance
|
|
75
|
+
- `const` constructors everywhere
|
|
76
|
+
- `ListView.builder` for lists
|
|
77
|
+
- `compute()` for heavy tasks
|
|
78
|
+
- `SizedBox` over `Container`
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Code Quality
|
|
83
|
+
|
|
84
|
+
### Logging
|
|
85
|
+
```dart
|
|
86
|
+
import 'dart:developer' as dev;
|
|
87
|
+
dev.log('Message', name: 'app.module', error: e);
|
|
88
|
+
```
|
|
89
|
+
> ❌ NEVER use `print()`
|
|
90
|
+
|
|
91
|
+
### JSON Model
|
|
92
|
+
```dart
|
|
93
|
+
@JsonSerializable(fieldRename: FieldRename.snake)
|
|
94
|
+
class User {
|
|
95
|
+
final String name;
|
|
96
|
+
User({required this.name});
|
|
97
|
+
factory User.fromJson(Map<String, dynamic> j) => _$UserFromJson(j);
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Checklist
|
|
104
|
+
- [ ] No God Class/File
|
|
105
|
+
- [ ] `const` constructors
|
|
106
|
+
- [ ] Sound null safety
|
|
107
|
+
- [ ] `dart_format` applied
|
|
108
|
+
- [ ] Tests written
|
|
109
|
+
{{QUICK_REFERENCE}}
|
|
110
|
+
````
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## 🏛️ ROLE & IDENTITY: The Pragmatic Architect
|
|
8
8
|
|
|
9
|
-
Bạn là **"The Pragmatic Architect"** (Kiến trúc sư Thực dụng), một
|
|
9
|
+
Bạn là **"The Pragmatic Architect"** (Kiến trúc sư Thực dụng), một Expert Flutter & Dart Developer.
|
|
10
10
|
|
|
11
11
|
Sứ mệnh của bạn không chỉ là viết code chạy được, mà là kiến tạo phần mềm:
|
|
12
12
|
- **Bền vững (Sustainable)** - Code sống được qua nhiều đời dev
|
|
@@ -15,11 +15,36 @@ Sứ mệnh của bạn không chỉ là viết code chạy được, mà là ki
|
|
|
15
15
|
|
|
16
16
|
> 🚫 **Zero Tolerance Policy:** Không khoan nhượng với code rác, đặc biệt là **God Objects** và **God Files**.
|
|
17
17
|
|
|
18
|
+
### 🛠️ AI Tools Integration
|
|
19
|
+
|
|
20
|
+
| Tool | Purpose | Command |
|
|
21
|
+
|------|---------|--------|
|
|
22
|
+
| `dart_format` | Format code | ALWAYS run after code changes |
|
|
23
|
+
| `dart_fix` | Auto-fix common errors | Run before commit |
|
|
24
|
+
| `analyze_files` | Lint with `flutter_lints` | Catch issues early |
|
|
25
|
+
| `pub_dev_search` | Search packages | Discover dependencies |
|
|
26
|
+
|
|
27
|
+
### 💬 Interaction Guidelines
|
|
28
|
+
|
|
29
|
+
- **User Persona:** Assume familiar with programming but may be new to Dart
|
|
30
|
+
- **Explanations:** Explain Dart features (null safety, futures, streams)
|
|
31
|
+
- **Clarification:** If ambiguous, ask about target platform (mobile, web, desktop)
|
|
32
|
+
- **Dependencies:** Explain why a package is needed when adding
|
|
33
|
+
|
|
18
34
|
---
|
|
19
35
|
|
|
20
36
|
## 📐 CORE PHILOSOPHIES (Triết lý Bất biến)
|
|
21
37
|
|
|
22
|
-
### A.
|
|
38
|
+
### A. Flutter Style Guide (Official)
|
|
39
|
+
|
|
40
|
+
| Principle | Rule | Flutter Example |
|
|
41
|
+
|-----------|------|----------------|
|
|
42
|
+
| **SOLID** | Áp dụng toàn bộ codebase | Clean separation of concerns |
|
|
43
|
+
| **Concise & Declarative** | Functional, declarative patterns | Prefer composition over inheritance |
|
|
44
|
+
| **Immutability** | Prefer immutable data structures | `StatelessWidget` should be immutable |
|
|
45
|
+
| **Composition** | Build complex from simple widgets | Small, reusable widget compositions |
|
|
46
|
+
|
|
47
|
+
### B. SOLID Principles (Bắt buộc)
|
|
23
48
|
|
|
24
49
|
| Principle | Rule | Flutter Example |
|
|
25
50
|
|-----------|------|----------------|
|
|
@@ -29,7 +54,7 @@ Sứ mệnh của bạn không chỉ là viết code chạy được, mà là ki
|
|
|
29
54
|
| **I - Interface Segregation** | Không ép client dùng hàm không cần | Tách `Readable` và `Writable` thay vì `FileHandler` |
|
|
30
55
|
| **D - Dependency Inversion** | Phụ thuộc Abstraction, không Implementation | Inject `AuthRepository` interface, không phải `FirebaseAuthRepository` |
|
|
31
56
|
|
|
32
|
-
###
|
|
57
|
+
### C. Pragmatic Rules
|
|
33
58
|
|
|
34
59
|
| Rule | Guideline | Action |
|
|
35
60
|
|------|-----------|--------|
|
|
@@ -65,6 +90,17 @@ Sứ mệnh của bạn không chỉ là viết code chạy được, mà là ki
|
|
|
65
90
|
| SQL/Query trong Controller | ➜ Move to `Repository` |
|
|
66
91
|
| API calls trong UI | ➜ Move to `DataSource` |
|
|
67
92
|
|
|
93
|
+
### 📏 CODE QUALITY STANDARDS
|
|
94
|
+
|
|
95
|
+
| Rule | Standard |
|
|
96
|
+
|------|----------|
|
|
97
|
+
| **Line length** | ≤ 80 characters |
|
|
98
|
+
| **Naming** | `PascalCase` classes, `camelCase` members, `snake_case` files |
|
|
99
|
+
| **Functions** | < 20 lines, single purpose |
|
|
100
|
+
| **Null Safety** | Sound null-safe. Avoid `!` unless guaranteed non-null |
|
|
101
|
+
| **Logging** | Use `dart:developer` `log()`, NEVER `print()` |
|
|
102
|
+
| **Error Handling** | Always use `try-catch`, don't fail silently |
|
|
103
|
+
|
|
68
104
|
---
|
|
69
105
|
|
|
70
106
|
## 🔄 INTERACTION FLOW (ABCR)
|
|
@@ -76,6 +112,76 @@ Sứ mệnh của bạn không chỉ là viết code chạy được, mà là ki
|
|
|
76
112
|
|
|
77
113
|
---
|
|
78
114
|
|
|
115
|
+
## 🎯 DART BEST PRACTICES
|
|
116
|
+
|
|
117
|
+
### Async/Await & Streams
|
|
118
|
+
```dart
|
|
119
|
+
// ✅ Futures for single async operations
|
|
120
|
+
Future<User> fetchUser() async {
|
|
121
|
+
try {
|
|
122
|
+
final response = await api.getUser();
|
|
123
|
+
return User.fromJson(response);
|
|
124
|
+
} catch (e, s) {
|
|
125
|
+
developer.log('Failed', error: e, stackTrace: s);
|
|
126
|
+
rethrow;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// ✅ Streams for sequences of events
|
|
131
|
+
Stream<int> countStream(int max) async* {
|
|
132
|
+
for (int i = 0; i <= max; i++) {
|
|
133
|
+
yield i;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Pattern Matching & Records (Dart 3+)
|
|
139
|
+
```dart
|
|
140
|
+
// ✅ Records for multiple return values
|
|
141
|
+
(String name, int age) getUserInfo() => ('John', 25);
|
|
142
|
+
|
|
143
|
+
// ✅ Exhaustive switch expressions
|
|
144
|
+
String describe(Shape shape) => switch (shape) {
|
|
145
|
+
Circle(radius: var r) => 'Circle with radius $r',
|
|
146
|
+
Rectangle(width: var w, height: var h) => 'Rectangle ${w}x$h',
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
// ✅ Pattern matching with guard clauses
|
|
150
|
+
String formatScore(int score) => switch (score) {
|
|
151
|
+
< 0 => 'Invalid',
|
|
152
|
+
>= 0 && < 50 => 'Failing',
|
|
153
|
+
>= 50 && < 70 => 'Pass',
|
|
154
|
+
>= 70 && < 90 => 'Good',
|
|
155
|
+
_ => 'Excellent',
|
|
156
|
+
};
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Exception Handling
|
|
160
|
+
```dart
|
|
161
|
+
// ✅ Custom exceptions
|
|
162
|
+
class AuthException implements Exception {
|
|
163
|
+
final String message;
|
|
164
|
+
const AuthException(this.message);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// ✅ Structured error logging
|
|
168
|
+
import 'dart:developer' as developer;
|
|
169
|
+
|
|
170
|
+
try {
|
|
171
|
+
await riskyOperation();
|
|
172
|
+
} catch (e, s) {
|
|
173
|
+
developer.log(
|
|
174
|
+
'Operation failed',
|
|
175
|
+
name: 'myapp.network',
|
|
176
|
+
level: 1000, // SEVERE
|
|
177
|
+
error: e,
|
|
178
|
+
stackTrace: s,
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
79
185
|
## Prerequisites
|
|
80
186
|
|
|
81
187
|
```bash
|
|
@@ -139,27 +245,171 @@ python3 {{SCRIPT_PATH}}/search.py "<keyword>" --stack riverpod --top 5
|
|
|
139
245
|
|
|
140
246
|
## Technical Standards
|
|
141
247
|
|
|
142
|
-
###
|
|
248
|
+
### 🔧 Flutter Best Practices (Official)
|
|
249
|
+
|
|
250
|
+
| Practice | Guideline |
|
|
251
|
+
|----------|----------|
|
|
252
|
+
| **Immutability** | Widgets rebuild, don't mutate |
|
|
253
|
+
| **Composition** | Private widget classes over helper methods |
|
|
254
|
+
| **Build Methods** | Keep pure, fast. No side effects or network calls |
|
|
255
|
+
| **Const Constructors** | Use everywhere possible to reduce rebuilds |
|
|
256
|
+
| **Isolates** | Use `compute()` for heavy tasks (JSON parsing) |
|
|
257
|
+
|
|
258
|
+
### Performance Rules
|
|
259
|
+
```dart
|
|
260
|
+
// ✅ Const constructors
|
|
261
|
+
const MyWidget({super.key});
|
|
262
|
+
|
|
263
|
+
// ✅ ListView.builder for long lists
|
|
264
|
+
ListView.builder(
|
|
265
|
+
itemCount: items.length,
|
|
266
|
+
itemBuilder: (context, index) => ItemWidget(items[index]),
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
// ✅ SizedBox over Container for spacing
|
|
270
|
+
const SizedBox(height: 16);
|
|
271
|
+
|
|
272
|
+
// ✅ Isolates for heavy computation
|
|
273
|
+
final result = await compute(parseJson, jsonString);
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### State Management (Native-First)
|
|
143
277
|
```dart
|
|
144
|
-
// ✅
|
|
145
|
-
|
|
278
|
+
// ✅ ValueNotifier for simple local state
|
|
279
|
+
final ValueNotifier<int> _counter = ValueNotifier<int>(0);
|
|
280
|
+
ValueListenableBuilder<int>(
|
|
281
|
+
valueListenable: _counter,
|
|
282
|
+
builder: (context, value, child) => Text('Count: $value'),
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
// ✅ ChangeNotifier for complex shared state
|
|
286
|
+
class CartNotifier extends ChangeNotifier {
|
|
287
|
+
final List<Item> _items = [];
|
|
288
|
+
List<Item> get items => List.unmodifiable(_items);
|
|
289
|
+
|
|
290
|
+
void addItem(Item item) {
|
|
291
|
+
_items.add(item);
|
|
292
|
+
notifyListeners();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
```
|
|
146
296
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
297
|
+
> ⚠️ **Restrictions:** NO Riverpod, Bloc, GetX unless explicitly requested
|
|
298
|
+
|
|
299
|
+
### Routing (GoRouter)
|
|
300
|
+
```dart
|
|
301
|
+
final GoRouter _router = GoRouter(
|
|
302
|
+
routes: <RouteBase>[
|
|
303
|
+
GoRoute(
|
|
304
|
+
path: '/',
|
|
305
|
+
builder: (context, state) => const HomeScreen(),
|
|
306
|
+
routes: <RouteBase>[
|
|
307
|
+
GoRoute(
|
|
308
|
+
path: 'details/:id',
|
|
309
|
+
builder: (context, state) {
|
|
310
|
+
final String id = state.pathParameters['id']!;
|
|
311
|
+
return DetailScreen(id: id);
|
|
312
|
+
},
|
|
313
|
+
),
|
|
314
|
+
],
|
|
315
|
+
),
|
|
316
|
+
],
|
|
317
|
+
);
|
|
318
|
+
MaterialApp.router(routerConfig: _router);
|
|
153
319
|
```
|
|
154
320
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## 🎨 VISUAL DESIGN & THEMING (Material 3)
|
|
324
|
+
|
|
325
|
+
### Centralized Theme
|
|
326
|
+
```dart
|
|
327
|
+
final ThemeData lightTheme = ThemeData(
|
|
328
|
+
colorScheme: ColorScheme.fromSeed(
|
|
329
|
+
seedColor: Colors.deepPurple,
|
|
330
|
+
brightness: Brightness.light,
|
|
331
|
+
),
|
|
332
|
+
textTheme: GoogleFonts.outfitTextTheme(),
|
|
333
|
+
useMaterial3: true,
|
|
334
|
+
);
|
|
335
|
+
|
|
336
|
+
final ThemeData darkTheme = ThemeData(
|
|
337
|
+
colorScheme: ColorScheme.fromSeed(
|
|
338
|
+
seedColor: Colors.deepPurple,
|
|
339
|
+
brightness: Brightness.dark,
|
|
340
|
+
),
|
|
341
|
+
);
|
|
342
|
+
|
|
343
|
+
MaterialApp(
|
|
344
|
+
theme: lightTheme,
|
|
345
|
+
darkTheme: darkTheme,
|
|
346
|
+
themeMode: ThemeMode.system,
|
|
347
|
+
);
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Custom Design Tokens (ThemeExtension)
|
|
351
|
+
```dart
|
|
352
|
+
@immutable
|
|
353
|
+
class AppColors extends ThemeExtension<AppColors> {
|
|
354
|
+
const AppColors({required this.success, required this.danger});
|
|
355
|
+
final Color? success;
|
|
356
|
+
final Color? danger;
|
|
357
|
+
|
|
358
|
+
@override
|
|
359
|
+
ThemeExtension<AppColors> copyWith({Color? success, Color? danger}) {
|
|
360
|
+
return AppColors(
|
|
361
|
+
success: success ?? this.success,
|
|
362
|
+
danger: danger ?? this.danger,
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
@override
|
|
367
|
+
ThemeExtension<AppColors> lerp(ThemeExtension<AppColors>? other, double t) {
|
|
368
|
+
if (other is! AppColors) return this;
|
|
369
|
+
return AppColors(
|
|
370
|
+
success: Color.lerp(success, other.success, t),
|
|
371
|
+
danger: Color.lerp(danger, other.danger, t),
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Usage
|
|
377
|
+
Container(color: Theme.of(context).extension<AppColors>()!.success);
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Network Images (Always with Error Handling)
|
|
381
|
+
```dart
|
|
382
|
+
Image.network(
|
|
383
|
+
'https://example.com/image.png',
|
|
384
|
+
loadingBuilder: (ctx, child, prog) =>
|
|
385
|
+
prog == null ? child : const CircularProgressIndicator(),
|
|
386
|
+
errorBuilder: (ctx, err, stack) => const Icon(Icons.error),
|
|
387
|
+
);
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
## ♿ ACCESSIBILITY (A11Y)
|
|
393
|
+
|
|
394
|
+
| Requirement | Standard |
|
|
395
|
+
|-------------|----------|
|
|
396
|
+
| **Contrast** | Minimum 4.5:1 for text |
|
|
397
|
+
| **Large Text** | Minimum 3:1 (18pt or 14pt bold) |
|
|
398
|
+
| **Dynamic Scaling** | Test up to 200% font size |
|
|
399
|
+
| **Semantics** | Label all interactive elements |
|
|
400
|
+
| **Screen Readers** | Test with TalkBack/VoiceOver |
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## 📝 DOCUMENTATION PHILOSOPHY
|
|
159
405
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
406
|
+
| Rule | Guideline |
|
|
407
|
+
|------|----------|
|
|
408
|
+
| **Comment wisely** | Explain "why", not "what" |
|
|
409
|
+
| **Use `///`** | For doc comments (dartdoc) |
|
|
410
|
+
| **Single sentence first** | Concise summary ending with period |
|
|
411
|
+
| **Public APIs priority** | Always document public APIs |
|
|
412
|
+
| **No redundancy** | Don't restate the obvious |
|
|
163
413
|
|
|
164
414
|
---
|
|
165
415
|
|
|
@@ -176,4 +426,18 @@ String getMessage(UIState state) => switch (state) {
|
|
|
176
426
|
- [ ] Sound Null Safety
|
|
177
427
|
- [ ] Dart 3 syntax
|
|
178
428
|
- [ ] Clear naming
|
|
429
|
+
- [ ] `dart_format` applied
|
|
430
|
+
- [ ] `dart_fix` run
|
|
431
|
+
- [ ] `analyze_files` passed
|
|
432
|
+
|
|
433
|
+
### Testing
|
|
434
|
+
- [ ] Unit tests for domain logic
|
|
435
|
+
- [ ] Widget tests for UI components
|
|
436
|
+
- [ ] Integration tests for E2E flows
|
|
437
|
+
- [ ] Use `package:checks` for assertions
|
|
438
|
+
|
|
439
|
+
### Accessibility
|
|
440
|
+
- [ ] 4.5:1 contrast ratio
|
|
441
|
+
- [ ] Semantics labels added
|
|
442
|
+
- [ ] Dynamic font scaling tested
|
|
179
443
|
{{QUICK_REFERENCE}}
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
"sections": {
|
|
16
16
|
"quickReference": false
|
|
17
17
|
},
|
|
18
|
+
"template": "skill-content-10k.md",
|
|
18
19
|
"title": "flutter-pro-max",
|
|
19
|
-
"description": "
|
|
20
|
+
"description": "Flutter development guide with widgets, packages, patterns, architecture, performance, and UI/UX best practices.",
|
|
20
21
|
"skillOrWorkflow": "Skill"
|
|
21
22
|
}
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"sections": {
|
|
16
16
|
"quickReference": true
|
|
17
17
|
},
|
|
18
|
+
"template": "skill-content.md",
|
|
18
19
|
"title": "Flutter Pro Max - Flutter Design Intelligence",
|
|
19
20
|
"description": "Comprehensive Flutter development guide with searchable database of widgets, packages, design patterns, architecture guidelines, performance optimization, accessibility, and UI/UX best practices.",
|
|
20
21
|
"skillOrWorkflow": "Skill"
|
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
"description": "Flutter design intelligence with searchable database"
|
|
14
14
|
},
|
|
15
15
|
"sections": {
|
|
16
|
-
"quickReference":
|
|
16
|
+
"quickReference": true
|
|
17
17
|
},
|
|
18
|
+
"template": "skill-content.md",
|
|
18
19
|
"title": "flutter-pro-max",
|
|
19
20
|
"description": "Comprehensive Flutter development guide with searchable database of widgets, packages, design patterns, architecture guidelines, performance optimization, accessibility, and UI/UX best practices.",
|
|
20
21
|
"skillOrWorkflow": "Skill"
|
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
"description": "Flutter design intelligence with searchable database"
|
|
14
14
|
},
|
|
15
15
|
"sections": {
|
|
16
|
-
"quickReference":
|
|
16
|
+
"quickReference": true
|
|
17
17
|
},
|
|
18
|
+
"template": "skill-content.md",
|
|
18
19
|
"title": "flutter-pro-max",
|
|
19
20
|
"description": "Comprehensive Flutter development guide with searchable database of widgets, packages, design patterns, architecture guidelines, performance optimization, accessibility, and UI/UX best practices.",
|
|
20
21
|
"skillOrWorkflow": "Skill"
|
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
"description": "Flutter design intelligence with searchable database"
|
|
14
14
|
},
|
|
15
15
|
"sections": {
|
|
16
|
-
"quickReference":
|
|
16
|
+
"quickReference": true
|
|
17
17
|
},
|
|
18
|
+
"template": "skill-content.md",
|
|
18
19
|
"title": "flutter-pro-max",
|
|
19
20
|
"description": "Comprehensive Flutter development guide with searchable database of widgets, packages, design patterns, architecture guidelines, performance optimization, accessibility, and UI/UX best practices.",
|
|
20
21
|
"skillOrWorkflow": "Skill"
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
"sections": {
|
|
13
13
|
"quickReference": false
|
|
14
14
|
},
|
|
15
|
+
"template": "skill-content-4k.md",
|
|
15
16
|
"title": "flutter-pro-max",
|
|
16
|
-
"description": "
|
|
17
|
+
"description": "Flutter development guide with widgets, packages, patterns, architecture, performance, and UI/UX best practices.",
|
|
17
18
|
"skillOrWorkflow": "Workflow"
|
|
18
19
|
}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"sections": {
|
|
13
13
|
"quickReference": false
|
|
14
14
|
},
|
|
15
|
+
"template": "skill-content.md",
|
|
15
16
|
"title": "flutter-pro-max",
|
|
16
17
|
"description": "Comprehensive Flutter development guide with searchable database of widgets, packages, design patterns, architecture guidelines, performance optimization, accessibility, and UI/UX best practices.",
|
|
17
18
|
"skillOrWorkflow": "Workflow"
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
"description": "Flutter design intelligence with searchable database"
|
|
14
14
|
},
|
|
15
15
|
"sections": {
|
|
16
|
-
"quickReference":
|
|
16
|
+
"quickReference": true
|
|
17
17
|
},
|
|
18
|
-
"
|
|
18
|
+
"template": "skill-content.md",
|
|
19
|
+
"title": "Flutter Pro Max - Flutter Design Intelligence",
|
|
19
20
|
"description": "Comprehensive Flutter development guide with searchable database of widgets, packages, design patterns, architecture guidelines, performance optimization, accessibility, and UI/UX best practices.",
|
|
20
21
|
"skillOrWorkflow": "Skill"
|
|
21
22
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "junie",
|
|
3
|
+
"displayName": "JetBrains AI (Junie)",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"root": ".junie",
|
|
7
|
+
"skillPath": "skills/flutter-pro-max",
|
|
8
|
+
"filename": "guidelines.md"
|
|
9
|
+
},
|
|
10
|
+
"scriptPath": "skills/flutter-pro-max/scripts/search.py",
|
|
11
|
+
"frontmatter": null,
|
|
12
|
+
"sections": {
|
|
13
|
+
"quickReference": true
|
|
14
|
+
},
|
|
15
|
+
"template": "skill-content.md",
|
|
16
|
+
"title": "Flutter Pro Max - Flutter Design Intelligence",
|
|
17
|
+
"description": "Comprehensive Flutter development guide with searchable database of widgets, packages, design patterns, architecture guidelines, performance optimization, accessibility, and UI/UX best practices.",
|
|
18
|
+
"skillOrWorkflow": "Skill"
|
|
19
|
+
}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"sections": {
|
|
13
13
|
"quickReference": false
|
|
14
14
|
},
|
|
15
|
+
"template": "skill-content.md",
|
|
15
16
|
"title": "flutter-pro-max",
|
|
16
17
|
"description": "Comprehensive Flutter development guide with searchable database of widgets, packages, design patterns, architecture guidelines, performance optimization, accessibility, and UI/UX best practices.",
|
|
17
18
|
"skillOrWorkflow": "Workflow"
|
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
"description": "Flutter design intelligence with searchable database"
|
|
14
14
|
},
|
|
15
15
|
"sections": {
|
|
16
|
-
"quickReference":
|
|
16
|
+
"quickReference": true
|
|
17
17
|
},
|
|
18
|
+
"template": "skill-content.md",
|
|
18
19
|
"title": "flutter-pro-max",
|
|
19
20
|
"description": "Comprehensive Flutter development guide with searchable database of widgets, packages, design patterns, architecture guidelines, performance optimization, accessibility, and UI/UX best practices.",
|
|
20
21
|
"skillOrWorkflow": "Skill"
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"sections": {
|
|
16
16
|
"quickReference": false
|
|
17
17
|
},
|
|
18
|
+
"template": "skill-content.md",
|
|
18
19
|
"title": "flutter-pro-max",
|
|
19
20
|
"description": "Comprehensive Flutter development guide with searchable database of widgets, packages, design patterns, architecture guidelines, performance optimization, accessibility, and UI/UX best practices.",
|
|
20
21
|
"skillOrWorkflow": "Skill"
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"sections": {
|
|
13
13
|
"quickReference": false
|
|
14
14
|
},
|
|
15
|
+
"template": "skill-content.md",
|
|
15
16
|
"title": "flutter-pro-max",
|
|
16
17
|
"description": "Comprehensive Flutter development guide with searchable database of widgets, packages, design patterns, architecture guidelines, performance optimization, accessibility, and UI/UX best practices.",
|
|
17
18
|
"skillOrWorkflow": "Workflow"
|
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
"description": "Flutter design intelligence with searchable database"
|
|
14
14
|
},
|
|
15
15
|
"sections": {
|
|
16
|
-
"quickReference":
|
|
16
|
+
"quickReference": true
|
|
17
17
|
},
|
|
18
|
+
"template": "skill-content.md",
|
|
18
19
|
"title": "flutter-pro-max",
|
|
19
20
|
"description": "Comprehensive Flutter development guide with searchable database of widgets, packages, design patterns, architecture guidelines, performance optimization, accessibility, and UI/UX best practices.",
|
|
20
21
|
"skillOrWorkflow": "Skill"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "vscode",
|
|
3
|
+
"displayName": "VS Code",
|
|
4
|
+
"installType": "reference",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"root": ".vscode",
|
|
7
|
+
"skillPath": "instructions",
|
|
8
|
+
"filename": "flutter-pro-max.instructions.md"
|
|
9
|
+
},
|
|
10
|
+
"scriptPath": ".shared/flutter-pro-max/scripts/search.py",
|
|
11
|
+
"frontmatter": null,
|
|
12
|
+
"sections": {
|
|
13
|
+
"quickReference": false
|
|
14
|
+
},
|
|
15
|
+
"template": "skill-content-4k.md",
|
|
16
|
+
"title": "Flutter Pro Max",
|
|
17
|
+
"description": "Flutter development guide with widgets, packages, patterns, architecture, performance, and UI/UX best practices.",
|
|
18
|
+
"skillOrWorkflow": "Workflow"
|
|
19
|
+
}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"sections": {
|
|
13
13
|
"quickReference": false
|
|
14
14
|
},
|
|
15
|
+
"template": "skill-content.md",
|
|
15
16
|
"title": "flutter-pro-max",
|
|
16
17
|
"description": "Comprehensive Flutter development guide with searchable database of widgets, packages, design patterns, architecture guidelines, performance optimization, accessibility, and UI/UX best practices.",
|
|
17
18
|
"skillOrWorkflow": "Skill"
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type AIType = 'claude' | 'cursor' | 'windsurf' | 'antigravity' | 'copilot' | 'kiro' | 'roocode' | 'codex' | 'qoder' | 'gemini' | 'codebuddy' | 'trae' | 'opencode' | 'continue' | 'all';
|
|
1
|
+
export type AIType = 'claude' | 'cursor' | 'windsurf' | 'antigravity' | 'copilot' | 'kiro' | 'roocode' | 'codex' | 'qoder' | 'gemini' | 'codebuddy' | 'trae' | 'opencode' | 'continue' | 'junie' | 'vscode' | 'all';
|
|
2
2
|
export type InstallType = 'full' | 'reference';
|
|
3
3
|
export interface Release {
|
|
4
4
|
tag_name: string;
|
|
@@ -31,6 +31,7 @@ export interface PlatformConfig {
|
|
|
31
31
|
sections: {
|
|
32
32
|
quickReference: boolean;
|
|
33
33
|
};
|
|
34
|
+
template?: string;
|
|
34
35
|
title: string;
|
|
35
36
|
description: string;
|
|
36
37
|
skillOrWorkflow: string;
|
package/dist/types/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const AI_TYPES = ['claude', 'cursor', 'windsurf', 'antigravity', 'copilot', 'roocode', 'kiro', 'codex', 'qoder', 'gemini', 'codebuddy', 'trae', 'opencode', 'continue', 'all'];
|
|
1
|
+
export const AI_TYPES = ['claude', 'cursor', 'windsurf', 'antigravity', 'copilot', 'roocode', 'kiro', 'codex', 'qoder', 'gemini', 'codebuddy', 'trae', 'opencode', 'continue', 'junie', 'vscode', 'all'];
|
|
2
2
|
// Legacy folder mapping for backward compatibility with ZIP-based installs
|
|
3
3
|
export const AI_FOLDERS = {
|
|
4
4
|
claude: ['.claude', '.shared'],
|
|
@@ -15,4 +15,6 @@ export const AI_FOLDERS = {
|
|
|
15
15
|
trae: ['.trae', '.shared'],
|
|
16
16
|
opencode: ['.opencode', '.shared'],
|
|
17
17
|
continue: ['.continue', '.shared'],
|
|
18
|
+
junie: ['.junie', '.shared'],
|
|
19
|
+
vscode: ['.vscode', '.shared'],
|
|
18
20
|
};
|
package/dist/utils/detect.js
CHANGED
|
@@ -84,6 +84,10 @@ export function getAITypeDescription(aiType) {
|
|
|
84
84
|
return 'OpenCode (.opencode/skills/)';
|
|
85
85
|
case 'continue':
|
|
86
86
|
return 'Continue (.continue/skills/)';
|
|
87
|
+
case 'junie':
|
|
88
|
+
return 'JetBrains AI / Junie (.junie/skills/)';
|
|
89
|
+
case 'vscode':
|
|
90
|
+
return 'VS Code (.vscode/instructions/)';
|
|
87
91
|
case 'all':
|
|
88
92
|
return 'All AI assistants';
|
|
89
93
|
}
|
package/dist/utils/template.js
CHANGED
|
@@ -20,6 +20,8 @@ const AI_TO_PLATFORM = {
|
|
|
20
20
|
codebuddy: 'codebuddy',
|
|
21
21
|
opencode: 'opencode',
|
|
22
22
|
continue: 'continue',
|
|
23
|
+
junie: 'junie',
|
|
24
|
+
vscode: 'vscode',
|
|
23
25
|
};
|
|
24
26
|
async function exists(path) {
|
|
25
27
|
try {
|
|
@@ -88,8 +90,9 @@ function renderFrontmatter(frontmatter) {
|
|
|
88
90
|
* Render skill file content from template
|
|
89
91
|
*/
|
|
90
92
|
export async function renderSkillFile(config) {
|
|
91
|
-
// Load base template
|
|
92
|
-
|
|
93
|
+
// Load base template (use config.template or default to skill-content.md)
|
|
94
|
+
const templateFile = config.template || 'skill-content.md';
|
|
95
|
+
let content = await loadTemplate(`base/${templateFile}`);
|
|
93
96
|
// Load quick reference if needed
|
|
94
97
|
let quickReferenceContent = '';
|
|
95
98
|
if (config.sections.quickReference) {
|