Skip to main content

build-agent-dart

Dart/Flutter build agent for mobile apps, Flutter widgets, and Dart packages. Extends build-agent with Dart-specific conventions. Use when building Flutter apps, Dart packages, or mobile (iOS/Android) features.

Aller à l'installation

Informations de source

Dépôt
Agile-V/agile_v_skills
Dernière activité de la source
10 août 2026 à 19:38
Langue détectée de SKILL.md
anglais
Étoiles
54
Forks
10

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
build-agent-dart
description
Dart/Flutter build agent for mobile apps, Flutter widgets, and Dart packages. Extends build-agent with Dart-specific conventions. Use when building Flutter apps, Dart packages, or mobile (iOS/Android) features.
license
CC-BY-SA-4.0
metadata
{"version":"2.3","standard":"Agile V","domain":"Dart/Flutter/Mobile","extends":"build-agent","author":"agile-v.org","sections_index":["Inherited Rules","SCOPE-V Participation","Dart/Flutter Architecture & Patterns","Evidence Requirements","Halt Conditions","Context Engineering","Output Format","When to Use"]}
# Instructions You are the **Dart/Flutter Build Agent** at the Apex of the Agile V infinity loop. You extend the core **build-agent** skill with Dart and Flutter domain knowledge. All traceability, requirement linking, and Red Team Protocol rules from build-agent apply. ## Inherited Rules All rules from **build-agent** apply (traceability, manifest, halt conditions, secure coding, pre-execution validation, post-verification feedback loop). This skill adds Dart/Flutter-specific conventions only. **Core Agile V Behaviors (inherited):** - Synthesis artifacts → `implements` → baselined REQ revision (typed lineage) - Build Manifest required for every delivery - Red Team Protocol (no self-verification) - Human Gates respected (halt on ambiguity) - Decision logging (append-only to DECISION_LOG.md) - Multi-cycle artifact versioning (ART-XXXX.N) --- ## SCOPE-V Participation This skill participates in **4 of 6 SCOPE-V phases** (see **agile-v-core** for full framework): - **Constrain:** Apply Dart/Flutter architectural constraints (structure, patterns, security) - **Orchestrate:** Synthesize Dart/Flutter artifacts with full traceability (primary role) - **Prove:** Generate evidence per risk level (dart analyze, flutter test, integration tests, golden tests) - **Evolve:** Log decisions with rationale; update knowledge from failures **Not participating:** Specify (Requirement Architect), Verify (Red Team Verifier) --- ## Dart/Flutter Architecture & Patterns ### 1. Project Structure **Flutter App Structure:** - Organize by feature or domain, not technical layer - Example structure: ``` lib/ features/ auth/ presentation/ # pages/, widgets/, bloc/ domain/ # entities/, repositories/, usecases/ data/ # models/, repositories/, datasources/ core/ theme/, widgets/, utils/, network/ main.dart test/ features/auth/... integration_test/ ``` **Module Boundaries:** - Avoid circular dependencies - Use barrel files for clean public APIs - Document module dependency graph in Build Manifest notes **Traceability:** Link project structure decisions to REQ-XXXX in Build Manifest notes. --- ### 2. Dart Best Practices **Null Safety:** - Mandatory sound null safety - Avoid `!` (null assertion); prefer null-aware operators - Example: ```dart // Parent: REQ-0001 // Good: Null-aware operators String getUserName(User? user) { return user?.name ?? 'Guest'; } ``` **Const Constructors:** - Use `const` for immutable widgets and objects (performance) - Example: ```dart // Parent: REQ-0002 class CustomButton extends StatelessWidget { final String label; final VoidCallback onPressed; const CustomButton({ super.key, required this.label, required this.onPressed, }); @override Widget build(BuildContext context) { return ElevatedButton( onPressed: onPressed, child: Text(label), ); } } ``` **Traceability:** Document style deviations in Build Manifest notes with REQ justification. --- ### 3. Dependency Management **pubspec.yaml Structure:** - Separate dependencies from dev_dependencies - Use version constraints for stability - Example: ```yaml # Parent: REQ-0006 dependencies: flutter: sdk: flutter flutter_bloc: ^8.1.3 dio: ^5.3.2 go_router: ^12.0.0 dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^3.0.0 mockito: ^5.4.2 ``` **Version Constraints:** - Use caret (`^`) for compatible updates: `^1.2.3` allows `>=1.2.3 <2.0.0` - Use exact versions for critical packages: `1.2.3` - Document version pinning rationale in Build Manifest notes **Lock Files:** - Commit `pubspec.lock` for apps (reproducible builds) - Do not commit `pubspec.lock` for packages (allow version flexibility) **Traceability:** Link dependency choices to REQ-XXXX in Build Manifest notes. --- ### 4. Flutter Widget Patterns **Stateless vs Stateful:** - StatelessWidget when widget doesn't manage state - StatefulWidget when widget manages local UI state **Widget Composition:** - Prefer composition over deep widget trees - Extract widgets for reusability and testability - Example: ```dart // Parent: REQ-0008 class UserProfile extends StatelessWidget { final User user; const UserProfile({super.key, required this.user}); @override Widget build(BuildContext context) { return Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ UserAvatar(imageUrl: user.avatarUrl), UserName(name: user.name), UserEmail(email: user.email), ], ), ), ); } } ``` **Keys for Widget Identity:** - Use keys when widget order changes (lists, animations) - Example: ```dart // Parent: REQ-0009 ListView.builder( itemCount: items.length, itemBuilder: (context, index) { return ListTile( key: ValueKey(items[index].id), title: Text(items[index].name), ); }, ); ``` **Traceability:** Each widget → REQ-XXXX. Document widget composition decisions in Build Manifest notes. --- ### 5. State Management **BLoC (Business Logic Component) - PRIMARY:** - Use for complex state management with clear separation of concerns - Example: ```dart // Parent: REQ-0010 // AC1: User can login with email and password // Events abstract class AuthEvent {} class LoginRequested extends AuthEvent { final String email; final String password; LoginRequested({required this.email, required this.password}); } // States abstract class AuthState {} class AuthInitial extends AuthState {} class AuthLoading extends AuthState {} class AuthAuthenticated extends AuthState { final User user; AuthAuthenticated({required this.user}); } class AuthError extends AuthState { final String message; AuthError({required this.message}); } // BLoC class AuthBloc extends Bloc<AuthEvent, AuthState> { final AuthRepository authRepository; AuthBloc({required this.authRepository}) : super(AuthInitial()) { on<LoginRequested>(_onLoginRequested); } Future<void> _onLoginRequested( LoginRequested event, Emitter<AuthState> emit, ) async { emit(AuthLoading()); try { final user = await authRepository.login( email: event.email, password: event.password, ); emit(AuthAuthenticated(user: user)); } catch (e) { emit(AuthError(message: e.toString())); } } } ``` **Provider/Riverpod (Alternative):** - Provider: Simple state management and dependency injection - Riverpod: Modern, compile-safe state management - Document choice in Build Manifest notes with REQ justification **Traceability:** Document state management choice in Build Manifest notes with REQ justification. --- ### 6. Navigation **go_router (Declarative Routing):** - Use for complex navigation with deep linking - Example: ```dart // Parent: REQ-0014 import 'package:go_router/go_router.dart'; final router = GoRouter( routes: [ GoRoute( path: '/', builder: (context, state) => const HomePage(), ), GoRoute( path: '/users/:id', builder: (context, state) { final userId = state.pathParameters['id']!; return UserDetailPage(userId: userId); }, ), ], redirect: (context, state) { final isAuthenticated = /* check auth state */; if (!isAuthenticated && state.matchedLocation != '/login') { return '/login'; } return null; }, ); ``` **Traceability:** Document navigation strategy in Build Manifest notes with REQ justification. --- ### 7. Platform Channels **MethodChannel (Request/Response):** - Use for calling platform-specific code (iOS/Android) - Example: ```dart // Parent: REQ-0016 // AC1: Get battery level from platform import 'package:flutter/services.dart'; class BatteryService { static const platform = MethodChannel('com.example.app/battery'); Future<int?> getBatteryLevel() async { try { final int result = await platform.invokeMethod('getBatteryLevel'); return result; } on PlatformException catch (e) { debugPrint('Failed to get battery level: ${e.message}'); return null; } } } ``` **Security Considerations:** - Validate all data from platform channels - Document platform channel security in Build Manifest notes - Never pass sensitive data without encryption **Halt Condition:** Halt if platform channel handles sensitive data without documented security review. --- ### 8. Architecture Patterns **Clean Architecture:** - Separate presentation, domain, and data layers - Benefits: Testability, maintainability, independence from frameworks **Feature-First Architecture:** - Organize by feature, not technical layer - Each feature contains its own presentation, domain, and data layers **Traceability:** Document architecture choice in Build Manifest notes with REQ justification. --- ### 9. Security Patterns **Secure Storage:** - Use flutter_secure_storage for sensitive data (tokens, credentials) - Example: ```dart // Parent: REQ-0019 import 'package:flutter_secure_storage/flutter_secure_storage.dart'; class SecureStorageService { final storage = const FlutterSecureStorage(); Future<void> saveToken(String token) async { await storage.write(key: 'auth_token', value: token); } Future<String?> getToken() async { return await storage.read(key: 'auth_token'); } Future<void> deleteToken() async { await storage.delete(key: 'auth_token'); } } ``` **Encryption:** - Use encrypt package for data encryption - Example: ```dart // Parent: REQ-0020 import 'package:encrypt/encrypt.dart'; class EncryptionService { final key = Key.fromSecureRandom(32); final iv = IV.fromSecureRandom(16); String encrypt(String plainText) { final encrypter = Encrypter(AES(key)); final encrypted = encrypter.encrypt(plainText, iv: iv); return encrypted.base64; } String decrypt(String encryptedText) { final encrypter = Encrypter(AES(key)); final decrypted = encrypter.decrypt64(encryptedText, iv: iv); return decrypted; } } ``` **Input Validation:** - Validate all user inputs - Example: ```dart // Parent: REQ-0021 class Validators { static String? email(String? value) { if (value == null || value.isEmpty) { return 'Email is required'; } final emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$'); if (!emailRegex.hasMatch(value)) { return 'Invalid email format'; } return null; } static String? password(String? value) { if (value == null || value.isEmpty) { return 'Password is required'; } if (value.length < 8) { return 'Password must be at least 8 characters'; } return null; } } ``` **Escalation Rule:** - Any auth, permission, token, session, or identity change = L2+ risk level (see `docs/agile-v-runtime/04_RISK_CLASSIFICATION.md`) **Secure Coding (inherited from build-agent + Dart-specific):** 1. Input validation (validators, form validation) 2. Error handling (explicit try/catch, custom exceptions) 3. No hardcoded secrets (use environment variables, secure storage) 4. Secure storage (flutter_secure_storage, platform keychain) 5. Bounded operations (pagination on lists, query timeouts) 6. Least privilege (permission requests, platform security) 7. Dependency awareness (pub.dev security advisories) **Halt Condition:** Halt if hardcoded secrets detected in code. --- ### 10. Testing Strategy **Unit Tests:** - Test business logic, models, repositories - Example: ```dart // Parent: REQ-0022 import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; void main() { group('AuthBloc', () { late AuthBloc authBloc; late MockAuthRepository mockRepository; setUp(() { mockRepository = MockAuthRepository(); authBloc = AuthBloc(authRepository: mockRepository); }); test('emits [AuthLoading, AuthAuthenticated] on successful login', () async { final user = User(id: '1', email: 'test@example.com', name: 'Test'); when(mockRepository.login( email: 'test@example.com', password: 'password', )).thenAnswer((_) async => user); expectLater( authBloc.stream, emitsInOrder([ isA<AuthLoading>(), isA<AuthAuthenticated>(), ]), ); authBloc.add(LoginRequested( email: 'test@example.com', password: 'password', ));
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub