@aicgen/aicgen 1.0.0-beta.2 → 1.0.1

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.
Files changed (39) hide show
  1. package/.agent/rules/api-design.md +649 -0
  2. package/.agent/rules/architecture.md +2507 -0
  3. package/.agent/rules/best-practices.md +622 -0
  4. package/.agent/rules/code-style.md +308 -0
  5. package/.agent/rules/design-patterns.md +577 -0
  6. package/.agent/rules/devops.md +230 -0
  7. package/.agent/rules/error-handling.md +417 -0
  8. package/.agent/rules/instructions.md +28 -0
  9. package/.agent/rules/language.md +786 -0
  10. package/.agent/rules/performance.md +710 -0
  11. package/.agent/rules/security.md +587 -0
  12. package/.agent/rules/testing.md +572 -0
  13. package/.agent/workflows/add-documentation.md +10 -0
  14. package/.agent/workflows/generate-integration-tests.md +10 -0
  15. package/.agent/workflows/generate-unit-tests.md +11 -0
  16. package/.agent/workflows/performance-audit.md +11 -0
  17. package/.agent/workflows/refactor-extract-module.md +12 -0
  18. package/.agent/workflows/security-audit.md +12 -0
  19. package/.gemini/instructions.md +4843 -0
  20. package/AGENTS.md +9 -11
  21. package/bun.lock +755 -4
  22. package/claude.md +2 -2
  23. package/config.example.yml +129 -0
  24. package/config.yml +38 -0
  25. package/data/guideline-mappings.yml +128 -0
  26. package/data/language/dart/async.md +289 -0
  27. package/data/language/dart/basics.md +280 -0
  28. package/data/language/dart/error-handling.md +355 -0
  29. package/data/language/dart/index.md +10 -0
  30. package/data/language/dart/testing.md +352 -0
  31. package/data/language/swift/basics.md +477 -0
  32. package/data/language/swift/concurrency.md +654 -0
  33. package/data/language/swift/error-handling.md +679 -0
  34. package/data/language/swift/swiftui-mvvm.md +795 -0
  35. package/data/language/swift/testing.md +708 -0
  36. package/data/version.json +10 -8
  37. package/dist/index.js +50295 -29101
  38. package/jest.config.js +46 -0
  39. package/package.json +13 -2
@@ -0,0 +1,280 @@
1
+ # Dart Fundamentals
2
+
3
+ ## Null Safety
4
+
5
+ Dart has sound null safety - non-nullable by default:
6
+
7
+ ```dart
8
+ // Non-nullable types
9
+ String name = 'Alice'; // Cannot be null
10
+ int age = 30; // Cannot be null
11
+
12
+ // Nullable types - add ?
13
+ String? middleName; // Can be null
14
+ int? optionalAge; // Can be null
15
+
16
+ // ❌ Compile error
17
+ String lastName = null; // Error: Can't assign null to non-nullable
18
+
19
+ // ✅ Correct
20
+ String? lastName = null; // OK: Explicitly nullable
21
+ ```
22
+
23
+ ## Type Annotations
24
+
25
+ Always use explicit types for clarity:
26
+
27
+ ```dart
28
+ // ✅ Explicit types
29
+ String getUserName(int userId) {
30
+ final User user = fetchUser(userId);
31
+ return user.name;
32
+ }
33
+
34
+ // Variables
35
+ final String message = 'Hello';
36
+ const int maxRetries = 3;
37
+ List<String> names = ['Alice', 'Bob'];
38
+
39
+ // ❌ Avoid dynamic
40
+ dynamic data = fetchData(); // No type safety
41
+
42
+ // ✅ Use specific types
43
+ Map<String, dynamic> data = fetchData();
44
+ ```
45
+
46
+ ## Null-Aware Operators
47
+
48
+ ```dart
49
+ // ?. - Null-aware access
50
+ String? name = user?.name; // null if user is null
51
+
52
+ // ?? - Null coalescing
53
+ String displayName = user?.name ?? 'Guest';
54
+
55
+ // ??= - Null-aware assignment
56
+ name ??= 'Unknown'; // Assign only if null
57
+
58
+ // ! - Null assertion (use sparingly)
59
+ String name = user!.name; // Assert user is not null
60
+ ```
61
+
62
+ ## Collections
63
+
64
+ ```dart
65
+ // Lists
66
+ final List<String> fruits = ['apple', 'banana'];
67
+ fruits.add('orange');
68
+
69
+ // Sets (unique values)
70
+ final Set<int> uniqueIds = {1, 2, 3};
71
+
72
+ // Maps
73
+ final Map<String, int> scores = {
74
+ 'Alice': 100,
75
+ 'Bob': 95,
76
+ };
77
+
78
+ // ✅ Use collection if for conditional elements
79
+ final List<String> items = [
80
+ 'required',
81
+ if (showOptional) 'optional',
82
+ if (user != null) user.name,
83
+ ];
84
+
85
+ // ✅ Use spread operator
86
+ final List<int> combined = [...list1, ...list2];
87
+ ```
88
+
89
+ ## Functions
90
+
91
+ ```dart
92
+ // Named parameters (recommended for multiple params)
93
+ void createUser({
94
+ required String email,
95
+ required String name,
96
+ int? age,
97
+ }) {
98
+ // email and name are required
99
+ // age is optional
100
+ }
101
+
102
+ createUser(email: 'test@example.com', name: 'Alice');
103
+
104
+ // Positional parameters
105
+ int add(int a, int b) => a + b;
106
+
107
+ // Optional positional
108
+ String greet(String name, [String? title]) {
109
+ return title != null ? '$title $name' : name;
110
+ }
111
+
112
+ // Arrow syntax for single expressions
113
+ bool isAdult(int age) => age >= 18;
114
+ ```
115
+
116
+ ## Classes
117
+
118
+ ```dart
119
+ // ✅ Use final for immutable fields
120
+ class User {
121
+ final String id;
122
+ final String email;
123
+ String name; // Mutable
124
+
125
+ User({
126
+ required this.id,
127
+ required this.email,
128
+ required this.name,
129
+ });
130
+
131
+ // Named constructors
132
+ User.guest() : id = '', email = '', name = 'Guest';
133
+
134
+ // Factory constructors
135
+ factory User.fromJson(Map<String, dynamic> json) {
136
+ return User(
137
+ id: json['id'] as String,
138
+ email: json['email'] as String,
139
+ name: json['name'] as String,
140
+ );
141
+ }
142
+ }
143
+
144
+ // ✅ Immutable classes with const
145
+ class Point {
146
+ final double x;
147
+ final double y;
148
+
149
+ const Point(this.x, this.y);
150
+ }
151
+
152
+ const origin = Point(0, 0); // Compile-time constant
153
+ ```
154
+
155
+ ## Enums
156
+
157
+ ```dart
158
+ // Simple enum
159
+ enum Status {
160
+ pending,
161
+ processing,
162
+ completed,
163
+ failed,
164
+ }
165
+
166
+ // Enhanced enums (Dart 2.17+)
167
+ enum UserRole {
168
+ admin('Administrator', level: 3),
169
+ editor('Editor', level: 2),
170
+ viewer('Viewer', level: 1);
171
+
172
+ const UserRole(this.displayName, {required this.level});
173
+
174
+ final String displayName;
175
+ final int level;
176
+
177
+ bool canEdit() => level >= 2;
178
+ }
179
+
180
+ // Usage
181
+ final role = UserRole.admin;
182
+ print(role.displayName); // 'Administrator'
183
+ print(role.canEdit()); // true
184
+ ```
185
+
186
+ ## Extension Methods
187
+
188
+ ```dart
189
+ // Add methods to existing types
190
+ extension StringExtensions on String {
191
+ bool get isEmail => contains('@');
192
+
193
+ String capitalize() {
194
+ if (isEmpty) return this;
195
+ return '${this[0].toUpperCase()}${substring(1)}';
196
+ }
197
+ }
198
+
199
+ // Usage
200
+ print('test@example.com'.isEmail); // true
201
+ print('hello'.capitalize()); // 'Hello'
202
+ ```
203
+
204
+ ## Cascade Notation
205
+
206
+ ```dart
207
+ // ✅ Use cascades for fluent method chaining
208
+ final user = User(id: '1', email: 'test@example.com', name: 'Alice')
209
+ ..setRole(UserRole.admin)
210
+ ..setActive(true)
211
+ ..save();
212
+
213
+ // ✅ Building objects
214
+ final button = Button()
215
+ ..text = 'Submit'
216
+ ..onPressed = handleSubmit
217
+ ..enabled = true;
218
+ ```
219
+
220
+ ## Late Variables
221
+
222
+ ```dart
223
+ // late - initialize later, but before use
224
+ class UserService {
225
+ late final Database db;
226
+
227
+ Future<void> init() async {
228
+ db = await Database.connect();
229
+ }
230
+
231
+ Future<User> getUser(String id) async {
232
+ return db.query('SELECT * FROM users WHERE id = ?', [id]);
233
+ }
234
+ }
235
+
236
+ // ⚠️ Runtime error if accessed before initialization
237
+ late String config;
238
+ print(config); // Error!
239
+
240
+ // ✅ Initialize before use
241
+ config = loadConfig();
242
+ print(config); // OK
243
+ ```
244
+
245
+ ## Naming Conventions
246
+
247
+ ```dart
248
+ // ✓ Classes/Enums/Typedefs: PascalCase
249
+ class UserAccount { }
250
+ enum OrderStatus { }
251
+ typedef IntCallback = void Function(int);
252
+
253
+ // ✓ Variables/Functions/Parameters: camelCase
254
+ String userName = 'Alice';
255
+ void processOrder() { }
256
+
257
+ // ✓ Constants: lowerCamelCase
258
+ const maxRetries = 3;
259
+ const apiBaseUrl = 'https://api.example.com';
260
+
261
+ // ✓ Private members: prefix with _
262
+ class User {
263
+ String _password; // Private field
264
+ void _hashPassword() { } // Private method
265
+ }
266
+
267
+ // ✓ Files: snake_case
268
+ // user_service.dart
269
+ // order_repository.dart
270
+ ```
271
+
272
+ ## Best Practices
273
+
274
+ - Prefer `final` over `var` for immutability
275
+ - Use `const` for compile-time constants
276
+ - Leverage null safety - avoid `!` assertion
277
+ - Use named parameters for functions with multiple parameters
278
+ - Make classes immutable when possible
279
+ - Use extension methods to add functionality to existing types
280
+ - Follow the official Dart style guide
@@ -0,0 +1,355 @@
1
+ # Error Handling in Dart
2
+
3
+ ## Custom Exceptions
4
+
5
+ ```dart
6
+ // ✅ Create structured exception hierarchy
7
+ class AppException implements Exception {
8
+ final String message;
9
+ final int? code;
10
+ final dynamic details;
11
+
12
+ AppException(this.message, {this.code, this.details});
13
+
14
+ @override
15
+ String toString() => 'AppException: $message (code: $code)';
16
+ }
17
+
18
+ class NotFoundException extends AppException {
19
+ NotFoundException(String resource, String id)
20
+ : super('$resource with id $id not found', code: 404);
21
+ }
22
+
23
+ class ValidationException extends AppException {
24
+ ValidationException(String message, {Map<String, String>? errors})
25
+ : super(message, code: 400, details: errors);
26
+ }
27
+
28
+ // Usage
29
+ throw NotFoundException('User', userId);
30
+ throw ValidationException('Invalid input', errors: {'email': 'Invalid format'});
31
+ ```
32
+
33
+ ## Try-Catch-Finally
34
+
35
+ ```dart
36
+ // ✅ Catch specific exceptions first
37
+ Future<User> fetchUser(String id) async {
38
+ try {
39
+ final response = await http.get('/api/users/$id');
40
+ return User.fromJson(response.data);
41
+ } on NetworkException catch (e) {
42
+ print('Network error: ${e.message}');
43
+ throw AppException('Network request failed', details: e);
44
+ } on FormatException catch (e) {
45
+ print('Invalid JSON: $e');
46
+ throw AppException('Invalid response format');
47
+ } catch (e, stackTrace) {
48
+ print('Unexpected error: $e');
49
+ print('Stack trace: $stackTrace');
50
+ rethrow;
51
+ } finally {
52
+ print('Request completed');
53
+ }
54
+ }
55
+
56
+ // ✅ Use finally for cleanup
57
+ Future<void> processFile(String path) async {
58
+ File? file;
59
+ try {
60
+ file = File(path);
61
+ final content = await file.readAsString();
62
+ await processContent(content);
63
+ } catch (e) {
64
+ print('Error processing file: $e');
65
+ rethrow;
66
+ } finally {
67
+ // Always runs, even if exception thrown
68
+ await file?.close();
69
+ }
70
+ }
71
+ ```
72
+
73
+ ## Result Type Pattern
74
+
75
+ ```dart
76
+ // ✅ Explicit success/failure without exceptions
77
+ class Result<T> {
78
+ final T? data;
79
+ final AppException? error;
80
+
81
+ const Result.success(T data) : data = data, error = null;
82
+ const Result.failure(AppException error) : data = null, error = error;
83
+
84
+ bool get isSuccess => error == null;
85
+ bool get isFailure => error != null;
86
+ }
87
+
88
+ // Usage
89
+ Future<Result<User>> fetchUserSafe(String id) async {
90
+ try {
91
+ final user = await fetchUser(id);
92
+ return Result.success(user);
93
+ } on AppException catch (e) {
94
+ return Result.failure(e);
95
+ } catch (e) {
96
+ return Result.failure(AppException('Unknown error: $e'));
97
+ }
98
+ }
99
+
100
+ // Consumer handles explicitly
101
+ final result = await fetchUserSafe('123');
102
+ if (result.isSuccess) {
103
+ print('User: ${result.data!.name}');
104
+ } else {
105
+ print('Error: ${result.error!.message}');
106
+ }
107
+ ```
108
+
109
+ ## Either Type Pattern
110
+
111
+ ```dart
112
+ // ✅ Functional error handling
113
+ sealed class Either<L, R> {
114
+ const Either();
115
+ }
116
+
117
+ class Left<L, R> extends Either<L, R> {
118
+ final L value;
119
+ const Left(this.value);
120
+ }
121
+
122
+ class Right<L, R> extends Either<L, R> {
123
+ final R value;
124
+ const Right(this.value);
125
+ }
126
+
127
+ // Usage
128
+ Future<Either<AppException, User>> fetchUser(String id) async {
129
+ try {
130
+ final user = await _fetchUser(id);
131
+ return Right(user);
132
+ } on AppException catch (e) {
133
+ return Left(e);
134
+ }
135
+ }
136
+
137
+ // Pattern matching (Dart 3.0+)
138
+ final result = await fetchUser('123');
139
+ switch (result) {
140
+ case Left(value: final error):
141
+ print('Error: ${error.message}');
142
+ case Right(value: final user):
143
+ print('User: ${user.name}');
144
+ }
145
+ ```
146
+
147
+ ## Validation
148
+
149
+ ```dart
150
+ // ✅ Validate early, throw specific errors
151
+ class UserValidator {
152
+ static void validate(String email, String password) {
153
+ if (email.isEmpty) {
154
+ throw ValidationException('Email is required');
155
+ }
156
+
157
+ if (!email.contains('@')) {
158
+ throw ValidationException('Invalid email format');
159
+ }
160
+
161
+ if (password.length < 8) {
162
+ throw ValidationException('Password must be at least 8 characters');
163
+ }
164
+ }
165
+ }
166
+
167
+ // Usage
168
+ try {
169
+ UserValidator.validate(email, password);
170
+ await createUser(email, password);
171
+ } on ValidationException catch (e) {
172
+ showError(e.message);
173
+ }
174
+ ```
175
+
176
+ ## Assert for Development
177
+
178
+ ```dart
179
+ // ✅ Use assert for development-time checks
180
+ void transfer(Account from, Account to, double amount) {
181
+ assert(amount > 0, 'Amount must be positive');
182
+ assert(from.balance >= amount, 'Insufficient funds');
183
+
184
+ from.withdraw(amount);
185
+ to.deposit(amount);
186
+ }
187
+
188
+ // Assertions only run in debug mode
189
+ // In production, they're removed
190
+ ```
191
+
192
+ ## Error Boundaries (Flutter)
193
+
194
+ ```dart
195
+ // ✅ Catch errors at widget level
196
+ class ErrorBoundary extends StatefulWidget {
197
+ final Widget child;
198
+
199
+ const ErrorBoundary({required this.child});
200
+
201
+ @override
202
+ State<ErrorBoundary> createState() => _ErrorBoundaryState();
203
+ }
204
+
205
+ class _ErrorBoundaryState extends State<ErrorBoundary> {
206
+ Object? error;
207
+
208
+ @override
209
+ Widget build(BuildContext context) {
210
+ if (error != null) {
211
+ return ErrorWidget(error: error!);
212
+ }
213
+
214
+ return ErrorWrapper(
215
+ onError: (error, stackTrace) {
216
+ setState(() => this.error = error);
217
+ },
218
+ child: widget.child,
219
+ );
220
+ }
221
+ }
222
+ ```
223
+
224
+ ## Global Error Handling
225
+
226
+ ```dart
227
+ // ✅ Catch uncaught errors
228
+ void main() {
229
+ // Synchronous errors
230
+ FlutterError.onError = (details) {
231
+ print('Flutter error: ${details.exception}');
232
+ print('Stack trace: ${details.stack}');
233
+ reportError(details.exception, details.stack);
234
+ };
235
+
236
+ // Asynchronous errors
237
+ PlatformDispatcher.instance.onError = (error, stack) {
238
+ print('Async error: $error');
239
+ reportError(error, stack);
240
+ return true;
241
+ };
242
+
243
+ runApp(MyApp());
244
+ }
245
+
246
+ void reportError(Object error, StackTrace? stackTrace) {
247
+ // Send to error tracking service
248
+ }
249
+ ```
250
+
251
+ ## Retry Pattern
252
+
253
+ ```dart
254
+ // ✅ Retry with exponential backoff
255
+ Future<T> retryWithBackoff<T>(
256
+ Future<T> Function() operation, {
257
+ int maxAttempts = 3,
258
+ Duration initialDelay = const Duration(seconds: 1),
259
+ }) async {
260
+ int attempt = 0;
261
+ while (true) {
262
+ try {
263
+ return await operation();
264
+ } catch (e) {
265
+ attempt++;
266
+ if (attempt >= maxAttempts) rethrow;
267
+
268
+ final delay = initialDelay * (1 << attempt); // Exponential backoff
269
+ print('Retry attempt $attempt after $delay');
270
+ await Future.delayed(delay);
271
+ }
272
+ }
273
+ }
274
+
275
+ // Usage
276
+ final user = await retryWithBackoff(
277
+ () => fetchUser('123'),
278
+ maxAttempts: 5,
279
+ );
280
+ ```
281
+
282
+ ## Circuit Breaker Pattern
283
+
284
+ ```dart
285
+ // ✅ Prevent cascading failures
286
+ class CircuitBreaker {
287
+ final int failureThreshold;
288
+ final Duration timeout;
289
+
290
+ int _failureCount = 0;
291
+ DateTime? _openedAt;
292
+
293
+ CircuitBreaker({
294
+ this.failureThreshold = 5,
295
+ this.timeout = const Duration(minutes: 1),
296
+ });
297
+
298
+ Future<T> execute<T>(Future<T> Function() operation) async {
299
+ if (_isOpen()) {
300
+ if (_shouldReset()) {
301
+ _reset();
302
+ } else {
303
+ throw AppException('Circuit breaker is open');
304
+ }
305
+ }
306
+
307
+ try {
308
+ final result = await operation();
309
+ _onSuccess();
310
+ return result;
311
+ } catch (e) {
312
+ _onFailure();
313
+ rethrow;
314
+ }
315
+ }
316
+
317
+ bool _isOpen() => _openedAt != null;
318
+
319
+ bool _shouldReset() {
320
+ return _openedAt != null &&
321
+ DateTime.now().difference(_openedAt!) > timeout;
322
+ }
323
+
324
+ void _onSuccess() {
325
+ _failureCount = 0;
326
+ }
327
+
328
+ void _onFailure() {
329
+ _failureCount++;
330
+ if (_failureCount >= failureThreshold) {
331
+ _openedAt = DateTime.now();
332
+ }
333
+ }
334
+
335
+ void _reset() {
336
+ _failureCount = 0;
337
+ _openedAt = null;
338
+ }
339
+ }
340
+ ```
341
+
342
+ ## Best Practices
343
+
344
+ - Create custom exception classes for different error types
345
+ - Catch specific exceptions before general ones
346
+ - Use `rethrow` to preserve stack traces
347
+ - Always clean up resources in `finally` blocks
348
+ - Validate input early and throw meaningful errors
349
+ - Use Result/Either types for expected failures
350
+ - Implement global error handlers for uncaught errors
351
+ - Use retry with exponential backoff for transient failures
352
+ - Implement circuit breakers for external service calls
353
+ - Don't catch exceptions you can't handle
354
+ - Include context in error messages
355
+ - Log errors with stack traces
@@ -0,0 +1,10 @@
1
+ # Dart Language Guidelines
2
+
3
+ Comprehensive guidelines for writing idiomatic Dart code.
4
+
5
+ ## Topics
6
+
7
+ - [Fundamentals](basics.md) - Types, null safety, syntax
8
+ - [Async Programming](async.md) - Futures, async/await, Streams
9
+ - [Error Handling](error-handling.md) - Exceptions and error patterns
10
+ - [Testing](testing.md) - Unit and widget testing