chore: update README and CLI usage for cursor_gen, version bump to 1.0.1

- Changed CLI usage instructions from `dart run cursor_gen` to `cursor_gen` for global activation.
- Updated project-brief.yaml example and README to reflect new command usage.
- Added app_context section in project-brief.yaml for theme variants and RBAC roles.
- Fixed bundled template resolution for local and global installs to prevent 'Template not found' errors.
- Version bump to 1.0.1 with corresponding updates in CHANGELOG and pubspec.yaml.
This commit is contained in:
2026-05-13 12:08:52 +05:30
parent b05cdb7fbe
commit 54c66efe9b
157 changed files with 8233 additions and 570 deletions
@@ -0,0 +1,64 @@
---
description: "Freezed code generation conventions for {{PROJECT_NAME}} — Pillar 4"
alwaysApply: true
---
# Freezed Standards — {{PROJECT_NAME}}
## When to use Freezed
- All domain entities and data models — use `@freezed`
- Union types / sealed classes — use `@freezed` with multiple constructors
- BLoC states and events — use `@freezed`
## Model pattern
```dart
@freezed
class Product with _$Product {
const factory Product({
required String id,
required String name,
required double price,
@Default(0) int stockCount,
String? imageUrl,
}) = _Product;
factory Product.fromJson(Map<String, dynamic> json) => _$ProductFromJson(json);
}
```
## Union type pattern
```dart
@freezed
sealed class ProductState with _$ProductState {
const factory ProductState.initial() = ProductInitial;
const factory ProductState.loading() = ProductLoading;
const factory ProductState.loaded(List<Product> products) = ProductLoaded;
const factory ProductState.error(String message) = ProductError;
}
// Usage — exhaustive switch
final widget = state.when(
initial: () => const SizedBox.shrink(),
loading: () => const ProductShimmer(),
loaded: (products) => ProductList(products: products),
error: (msg) => ErrorWidget(message: msg),
);
```
## Critical rules
- **NEVER** edit `.freezed.dart` or `.g.dart` files — they are generated
- Run `dart run build_runner build --delete-conflicting-outputs` after changes
- Run `dart run build_runner watch` during development
- Add `*.freezed.dart` and `*.g.dart` to `.gitignore` (or commit them — team must decide)
- Always define `copyWith` via Freezed — never write manual `copyWith`
## Patterns to avoid
```dart
// ❌ Manual copyWith — replaced by Freezed
Product copyWith({String? name, double? price}) => Product(
id: id, name: name ?? this.name, price: price ?? this.price,
);
// ✅ Let Freezed generate it
product.copyWith(name: 'New Name', price: 9.99)
```
@@ -0,0 +1,42 @@
---
description: "Injectable dependency injection conventions for {{PROJECT_NAME}} — Pillar 4"
alwaysApply: true
---
# Injectable (get_it) Standards — {{PROJECT_NAME}}
## Setup
```dart
// lib/core/di/injection.dart
@InjectableInit()
void configureDependencies() => getIt.init();
```
## Annotations
```dart
@singleton // One instance for app lifetime
@lazySingleton // Created on first access (preferred for most services)
@injectable // New instance each time (use sparingly)
@factoryMethod // Custom factory logic
```
## Example
```dart
@lazySingleton
class ProductRepository {
final DioClient _client;
const ProductRepository(this._client); // Constructor injection
}
@injectable
class GetProductsUseCase {
final ProductRepository _repo;
const GetProductsUseCase(this._repo);
}
```
## Rules
- Run `dart run build_runner build` after adding/modifying `@injectable` annotations
- **NEVER** use `getIt<T>()` in widget `build()` methods — inject via constructor or provider
- Use `@module` for third-party registrations (Dio, SharedPreferences, etc.)
- Register environment-specific implementations with `@Environment('dev')` / `@Environment('prod')`
@@ -0,0 +1,37 @@
---
description: "json_serializable conventions for {{PROJECT_NAME}} — Pillar 4"
alwaysApply: true
---
# json_serializable Standards — {{PROJECT_NAME}}
## Model annotation
```dart
@JsonSerializable(explicitToJson: true) // explicitToJson for nested objects
class ProductDto {
final String id;
final String name;
@JsonKey(name: 'unit_price') // snake_case API → camelCase Dart
final double unitPrice;
@JsonKey(defaultValue: false)
final bool isActive;
final DateTime createdAt; // auto-converted from ISO 8601 string
const ProductDto({
required this.id,
required this.name,
required this.unitPrice,
required this.isActive,
required this.createdAt,
});
factory ProductDto.fromJson(Map<String, dynamic> json) => _$ProductDtoFromJson(json);
Map<String, dynamic> toJson() => _$ProductDtoToJson(this);
}
```
## Critical rules
- **NEVER** edit `*.g.dart` files
- Use `@JsonKey(defaultValue: ...)` for nullable API fields — API contracts change
- Use `explicitToJson: true` whenever the model has nested objects
- Null safety: API fields not guaranteed to be non-null should be `String?` not `String`
@@ -0,0 +1,30 @@
---
description: "Retrofit (Dio) API client conventions for {{PROJECT_NAME}} — Pillar 4"
alwaysApply: true
---
# Retrofit Standards — {{PROJECT_NAME}}
## API client definition
```dart
@RestApi()
abstract class ProductApiClient {
factory ProductApiClient(Dio dio, {String? baseUrl}) = _ProductApiClient;
@GET('/products')
Future<List<ProductDto>> getProducts(@Query('category') String? category);
@GET('/products/{id}')
Future<ProductDto> getProduct(@Path('id') String id);
@POST('/products')
Future<ProductDto> createProduct(@Body() CreateProductDto dto);
}
```
## Rules
- **NEVER** edit `*.g.dart` files
- Run `dart run build_runner build` after modifying API client
- All DTOs used in Retrofit must have `fromJson`/`toJson` (via `json_serializable` or Freezed)
- Handle `DioException` in the repository layer — never let it reach the presentation layer
- Use `@Headers({'Content-Type': 'application/json'})` at class level, not per-method