merge instructions into AGENTS.md
This commit is contained in:
parent
da2eeee518
commit
54f0385be4
3 changed files with 132 additions and 340 deletions
216
.github/copilot-instructions.md
vendored
216
.github/copilot-instructions.md
vendored
|
|
@ -1,216 +0,0 @@
|
|||
# Copilot Instructions for Frosty
|
||||
|
||||
## Project Overview
|
||||
|
||||
Frosty is a cross-platform Flutter app for Twitch that supports third-party emotes (7TV, BTTV, FFZ). The architecture is built around **MobX state management** with strict code generation requirements and a **shared HTTP client pattern** for API efficiency.
|
||||
|
||||
## Critical Development Workflow
|
||||
|
||||
### Essential Commands
|
||||
|
||||
**Dependencies and Development:**
|
||||
|
||||
- `flutter pub get` - Install dependencies
|
||||
- `flutter run` - Run the app on connected device/emulator
|
||||
- `flutter build apk` - Build Android APK
|
||||
- `flutter build ios` - Build iOS app
|
||||
- `flutter analyze` - Run static analysis and lint checks
|
||||
- `flutter test` - Run all tests
|
||||
|
||||
### Code Generation (REQUIRED)
|
||||
|
||||
All MobX stores and JSON models require code generation. **Always run after any MobX or model changes:**
|
||||
|
||||
```bash
|
||||
dart run build_runner build --delete-conflicting-outputs
|
||||
```
|
||||
|
||||
**Alternative commands:**
|
||||
|
||||
- `dart run build_runner build` - Generate code once
|
||||
- `dart run build_runner watch` - Watch and regenerate code on changes
|
||||
|
||||
Generated `.g.dart` files are excluded from linting but must be committed to source control.
|
||||
|
||||
### Environment Setup
|
||||
|
||||
Twitch API requires client credentials via `--dart-define`:
|
||||
|
||||
```bash
|
||||
flutter run --dart-define=clientId=YOUR_TWITCH_CLIENT_ID --dart-define=secret=YOUR_TWITCH_CLIENT_SECRET
|
||||
```
|
||||
|
||||
## Architecture Patterns
|
||||
|
||||
### State Management (MobX)
|
||||
|
||||
- **Store Pattern**: Each feature has stores in `lib/screens/{feature}/stores/` (not at screen root)
|
||||
- **Naming**: All stores end with `Store` suffix and have corresponding `.g.dart` files
|
||||
- **Global Stores**:
|
||||
- `AuthStore`, `SettingsStore` in `lib/screens/settings/stores/`
|
||||
- `GlobalAssetsStore` (shared emote/badge cache) in `lib/stores/`
|
||||
- **Dependency Injection**: Stores are provided via Provider in `main.dart` with shared HTTP client
|
||||
|
||||
### API Service Architecture
|
||||
|
||||
- **Shared HTTP Client**: Single Dio instance configured in `DioClient.createClient()` with:
|
||||
- Connection pooling and keep-alive headers for efficiency
|
||||
- Optimized timeouts: 8s connect, 15s receive, 10s send
|
||||
- Global Twitch User-Agent header
|
||||
- Simple logging in debug mode (not verbose to avoid log spam)
|
||||
- **API Services**: `TwitchApi`, `BTTVApi`, `FFZApi`, `SevenTVApi` in `lib/apis/`
|
||||
- **Authentication Interceptor**: `TwitchAuthInterceptor` automatically injects auth headers:
|
||||
- Detects Twitch API URLs and adds Authorization + Client-Id headers
|
||||
- Updates automatically when user authentication changes
|
||||
- Eliminates manual header passing throughout the codebase
|
||||
- **Error Handling**: `UnauthorizedInterceptor` catches 401 errors for token refresh
|
||||
- **Service Pattern**: All API services extend `BaseApiClient` for consistent error handling
|
||||
|
||||
### Project Structure
|
||||
|
||||
**Key Directories:**
|
||||
|
||||
- `lib/screens/` - UI screens organized by feature (home, channel, settings, onboarding)
|
||||
- Each screen has its own MobX stores in a `stores/` subdirectory
|
||||
- `lib/models/` - Data models with JSON serialization (uses `.g.dart` files)
|
||||
- `lib/apis/` - API services for Twitch, BTTV, FFZ, and 7TV
|
||||
- `lib/widgets/` - Reusable UI components
|
||||
- `lib/cache_manager.dart` - Custom cache management for images/media
|
||||
- `lib/utils.dart` - Utility functions and helpers
|
||||
- `lib/utils/` - Additional utility modules including context extensions
|
||||
|
||||
### Screen Organization
|
||||
|
||||
```
|
||||
lib/screens/{feature}/
|
||||
├── {feature}.dart # Main UI
|
||||
├── stores/ # Feature stores directory
|
||||
│ ├── {feature}_store.dart
|
||||
│ └── {feature}_store.g.dart
|
||||
└── subdirectories/ # Feature sub-components
|
||||
```
|
||||
|
||||
**Main Application Flow:**
|
||||
|
||||
1. App starts in `main.dart` with Firebase initialization and dependency injection via Provider
|
||||
2. Authentication handled by `AuthStore` using Twitch OAuth
|
||||
3. Settings persisted via `SettingsStore` with SharedPreferences
|
||||
4. API services inject common HTTP client for efficient connection reuse
|
||||
|
||||
### Model Generation
|
||||
|
||||
- **JSON Serialization**: Models use `@JsonSerializable()` with `.g.dart` companions
|
||||
- **Emote Architecture**: Base `Emote` class with platform-specific factories (`Emote.fromTwitch()`, `Emote.fromBTTV()`, `Emote.fromFFZ()`, `Emote.from7TV()`)
|
||||
|
||||
## Key Integration Points
|
||||
|
||||
### Firebase Services
|
||||
|
||||
Initialized in `main.dart` with error handling:
|
||||
|
||||
- Crashlytics for uncaught errors
|
||||
- Performance monitoring
|
||||
- Analytics
|
||||
|
||||
### Chat System
|
||||
|
||||
- **IRC Connection**: WebSocket to Twitch IRC for real-time chat
|
||||
- **Emote Loading**: Asynchronous third-party emote fetching (BTTV/FFZ/7TV)
|
||||
- **Message Parsing**: Custom rendering with emote/badge support
|
||||
- **Real-time IRC**: WebSocket connection to Twitch IRC with custom `IRCMessage` parsing
|
||||
- **Third-party Emotes**: Asynchronous loading of BTTV, FFZ, and 7TV assets via dedicated APIs
|
||||
- **Message Management**: 5000 message limit with 20% batch removal optimization for performance
|
||||
- **Assets Store**: Separate `ChatAssetsStore` manages emotes, badges, and chat-related data
|
||||
- **User interaction features**: Blocking, reporting, moderation capabilities
|
||||
|
||||
### Authentication Flow
|
||||
|
||||
- **OAuth**: Twitch OAuth via WebView in `AuthStore`
|
||||
- **Token Storage**: FlutterSecureStorage for secure token persistence
|
||||
- **Auto-refresh**: Token validation and refresh logic in `AuthStore`
|
||||
- **Two-tier Token System**:
|
||||
- Default app token for unauthenticated requests
|
||||
- Optional user token stored in Flutter Secure Storage
|
||||
- Automatic token validation on startup with fallback
|
||||
- **WebView OAuth Flow**: Custom JavaScript injection in WebView for seamless Twitch login experience without opening external browsers
|
||||
- **Secure Storage Cleanup**: First-run detection clears secure storage to handle Android/iOS uninstall scenarios where secure storage persists
|
||||
|
||||
## Code Style Enforcement
|
||||
|
||||
Analysis rules in `analysis_options.yaml`:
|
||||
|
||||
- Single quotes: `prefer_single_quotes`
|
||||
- Package imports: `always_use_package_imports`
|
||||
- Trailing commas: `require_trailing_commas`
|
||||
- Final locals: `prefer_final_locals`
|
||||
- Additional rules: `directives_ordering`, `avoid_void_async`, `always_declare_return_types`, `avoid_redundant_argument_values`, `unnecessary_parenthesis`
|
||||
|
||||
**Important**: `.g.dart` files are excluded from analysis but must be committed to source control.
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### MobX Reactions
|
||||
|
||||
```dart
|
||||
late final ReactionDisposer _disposeReaction;
|
||||
_disposeReaction = reaction(
|
||||
(_) => authStore.isLoggedIn,
|
||||
(_) => _selectedIndex = 0,
|
||||
);
|
||||
```
|
||||
|
||||
### Settings Persistence
|
||||
|
||||
Auto-saving pattern in `main.dart`:
|
||||
|
||||
```dart
|
||||
autorun((_) => prefs.setString('settings', jsonEncode(settingsStore)));
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
|
||||
API services use typed exceptions via `BaseApiClient` (`lib/apis/base_api_client.dart`):
|
||||
- `ApiException`, `NetworkException`, `TimeoutException`, `ServerException`, `NotFoundException`, `UnauthorizedException`
|
||||
|
||||
## MobX Store Implementation
|
||||
|
||||
### Store Pattern
|
||||
|
||||
All stores follow `StoreBase with _$StoreName` pattern:
|
||||
|
||||
- Generate `.g.dart` files with `dart run build_runner build`
|
||||
- Use `@observable`, `@action`, and `@computed` annotations
|
||||
- Settings store uses `@JsonSerializable()` with automatic persistence via `autorun()`
|
||||
|
||||
### Authentication Headers
|
||||
|
||||
Generated as `@computed` properties that automatically update when tokens change.
|
||||
|
||||
### State Persistence
|
||||
|
||||
Settings automatically saved to SharedPreferences via MobX `autorun()` reaction.
|
||||
|
||||
## Custom Cache Management
|
||||
|
||||
- **Orphaned File Cleanup**: `CustomCacheManager.removeOrphanedCacheFiles()` runs on startup to remove files not in database
|
||||
- **Optimized Settings**: 30-day stale period, 10,000 max objects for efficient image caching across the app
|
||||
|
||||
## Code Style Guidelines
|
||||
|
||||
- **Prefer modern Flutter/Dart features and type-safety**
|
||||
- **Use consistent naming, comments, and styles matching the existing codebase**
|
||||
- **Single quotes, trailing commas, and final locals per lint rules**
|
||||
- **Package imports over relative imports**
|
||||
- **Observer widgets only wrap necessary UI components for MobX optimization**
|
||||
|
||||
## Platform Support
|
||||
|
||||
- **iOS/Android**: Native platform features via plugins
|
||||
- **Custom Cache**: `CustomCacheManager` for media caching
|
||||
- **PiP Mode**: Custom implementation via git dependency
|
||||
|
||||
## Commit Convention
|
||||
|
||||
Commits use lowercase, descriptive messages without prefixes (e.g., `fix landscape bottom padding in chat bottom bar`, `add swipe pip gesture support`). Keep commits tightly scoped.
|
||||
|
||||
When working with this codebase, always consider MobX code generation requirements and the shared HTTP client pattern for API efficiency.
|
||||
131
AGENTS.md
Normal file
131
AGENTS.md
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
# AGENTS.md
|
||||
|
||||
## Development Workflow
|
||||
|
||||
**Plan Mode**: When in plan mode, interview thoroughly before coding:
|
||||
- Ask detailed questions about technical implementation, UI/UX concerns, tradeoffs, and edge cases
|
||||
- Continue asking questions until all requirements and non-obvious decisions are clear
|
||||
- Don't begin implementation until all important details are resolved
|
||||
|
||||
**Pattern Consistency**: When implementing new code:
|
||||
- Search the codebase to find existing usages and implementations
|
||||
- Prefer following established patterns, styles, and practices for consistency
|
||||
|
||||
## Development Commands
|
||||
|
||||
**Common Commands:**
|
||||
- `flutter pub get` - Install dependencies
|
||||
- `flutter run --dart-define=clientId=YOUR_CLIENT_ID --dart-define=secret=YOUR_CLIENT_SECRET` - Run with Twitch API credentials
|
||||
- `flutter analyze` - Run static analysis and lint checks
|
||||
- `flutter test` - Run all tests
|
||||
- `flutter test test/path/to/test.dart` - Run a single test file
|
||||
- `flutter build apk` / `flutter build ios` - Build release binaries
|
||||
|
||||
**Code Generation** (required after changing MobX stores or `@JsonSerializable` models):
|
||||
- `dart run build_runner build` - Generate once
|
||||
- `dart run build_runner build --delete-conflicting-outputs` - Force rebuild all
|
||||
- `dart run build_runner watch` - Watch mode for development
|
||||
|
||||
Generated `.g.dart` files are excluded from linting but must be committed to source control.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
**State Management**: MobX with code generation. All stores end with `Store` and have corresponding `.g.dart` generated files.
|
||||
|
||||
**Key Directories**:
|
||||
- `lib/screens/` - UI screens organized by feature (home, channel, settings, onboarding)
|
||||
- `lib/models/` - Data models with JSON serialization (uses .g.dart files)
|
||||
- `lib/apis/` - API services for Twitch, BTTV, FFZ, and 7TV
|
||||
- `lib/widgets/` - Reusable UI components
|
||||
- `lib/utils/` - Utility modules including context extensions
|
||||
|
||||
**Screen Organization**: `lib/screens/{feature}/` contains `{feature}.dart` (main UI), `stores/` subdirectory with MobX stores, and feature sub-components.
|
||||
|
||||
**Main Application Flow**:
|
||||
1. App starts in `main.dart` with Firebase initialization and dependency injection via Provider
|
||||
2. Authentication handled by `AuthStore` using Twitch OAuth
|
||||
3. Settings persisted via `SettingsStore` with SharedPreferences and MobX `autorun()`
|
||||
4. API services share a common Dio HTTP client for efficient connection reuse
|
||||
|
||||
**Global Stores** (injected via Provider in `main.dart`):
|
||||
- `AuthStore` (`lib/screens/settings/stores/`) - Authentication state and token management
|
||||
- `SettingsStore` (`lib/screens/settings/stores/`) - User preferences with automatic persistence via MobX `autorun()`
|
||||
- `GlobalAssetsStore` (`lib/stores/`) - Shared cache for global emotes and badges across all chat tabs
|
||||
|
||||
## HTTP & API Architecture
|
||||
|
||||
**Shared HTTP Client**: Single Dio instance configured in `DioClient.createClient()` with:
|
||||
- Connection pooling and keep-alive headers for efficiency
|
||||
- Optimized timeouts: 8s connect, 15s receive, 10s send
|
||||
- Frosty User-Agent header for Twitch API compatibility
|
||||
|
||||
**Authentication Interceptor**: `TwitchAuthInterceptor` automatically injects auth headers for Twitch API URLs. `UnauthorizedInterceptor` catches 401 errors for token refresh.
|
||||
|
||||
**Two-tier Token System**: Default app token for unauthenticated requests + optional user token in Flutter Secure Storage.
|
||||
|
||||
**BaseApiClient Pattern**: All API services (`TwitchApi`, `BTTVApi`, `FFZApi`, `SevenTVApi`) extend `BaseApiClient` which provides:
|
||||
- Generic GET/POST/PUT/DELETE methods with centralized error handling
|
||||
- Automatic conversion of `DioException` to typed exceptions
|
||||
|
||||
**Exception Hierarchy**: `ApiException` base class with `NetworkException`, `TimeoutException`, `ServerException`, `NotFoundException`, `UnauthorizedException` (see `lib/apis/base_api_client.dart`).
|
||||
|
||||
## MobX Store Implementation
|
||||
|
||||
**Store Pattern**: All stores follow `StoreBase with _$StoreName` pattern:
|
||||
|
||||
```dart
|
||||
class SomeStore = SomeStoreBase with _$SomeStore;
|
||||
|
||||
abstract class SomeStoreBase with Store {
|
||||
@observable
|
||||
var someValue = '';
|
||||
|
||||
@action
|
||||
void updateValue(String value) => someValue = value;
|
||||
|
||||
@computed
|
||||
String get derivedValue => someValue.toUpperCase();
|
||||
}
|
||||
```
|
||||
|
||||
**MobX Reactions** (for side effects and persistence):
|
||||
|
||||
```dart
|
||||
// Auto-save settings whenever they change (in main.dart)
|
||||
autorun((_) => prefs.setString('settings', jsonEncode(settingsStore)));
|
||||
|
||||
// React to specific state changes
|
||||
reaction((_) => authStore.isLoggedIn, (_) => _selectedIndex = 0);
|
||||
```
|
||||
|
||||
## Chat System Architecture
|
||||
|
||||
- **Real-time IRC**: WebSocket connection to Twitch IRC with custom `IRCMessage` parsing
|
||||
- **Third-party Emotes**: Asynchronous loading of BTTV, FFZ, and 7TV assets via dedicated APIs
|
||||
- **Message Management**: 5000 message limit with 20% batch removal optimization
|
||||
- **Assets Store**: `ChatAssetsStore` manages channel-specific emotes/badges
|
||||
- **User Interaction**: Blocking, reporting, and moderation capabilities
|
||||
|
||||
## Additional Patterns
|
||||
|
||||
**Emote Architecture**: Base `Emote` class with platform-specific factories: `Emote.fromTwitch()`, `Emote.fromBTTV()`, `Emote.fromFFZ()`, `Emote.from7TV()`.
|
||||
|
||||
**Custom Cache Manager**: Uses 30-day stale period and 10k max objects. `CustomCacheManager.removeOrphanedCacheFiles()` runs on startup to clean files not in database.
|
||||
|
||||
**Secure Storage Cleanup**: First-run detection clears Flutter Secure Storage to handle Android/iOS uninstall edge case where secure storage persists but app data is wiped.
|
||||
|
||||
**Authentication Flow**:
|
||||
- OAuth via WebView with custom JavaScript injection for seamless Twitch login
|
||||
- Token storage in FlutterSecureStorage
|
||||
- Auto-refresh and validation logic in `AuthStore`
|
||||
|
||||
## Code Style
|
||||
|
||||
**Lint Rules** (from `analysis_options.yaml`):
|
||||
- `prefer_single_quotes`, `always_use_package_imports`, `require_trailing_commas`
|
||||
- `prefer_final_locals`, `prefer_final_in_for_each`, `avoid_redundant_argument_values`
|
||||
- `directives_ordering`, `avoid_void_async`, `always_declare_return_types`, `unnecessary_parenthesis`
|
||||
|
||||
## Commit Convention
|
||||
|
||||
Commits use lowercase, descriptive messages without prefixes (e.g., `fix landscape bottom padding in chat bottom bar`, `add swipe pip gesture support`). Keep commits tightly scoped.
|
||||
125
CLAUDE.md
125
CLAUDE.md
|
|
@ -2,127 +2,4 @@
|
|||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Development Workflow
|
||||
|
||||
**Plan Mode**: When in plan mode, interview thoroughly before coding:
|
||||
- Ask detailed questions about technical implementation, UI/UX concerns, tradeoffs, and edge cases
|
||||
- Continue asking questions until all requirements and non-obvious decisions are clear
|
||||
- Don't begin implementation until all important details are resolved
|
||||
|
||||
**Pattern Consistency**: When implementing new code:
|
||||
- Search the codebase to find existing usages and implementations
|
||||
- Prefer following established patterns, styles, and practices for consistency
|
||||
|
||||
## Development Commands
|
||||
|
||||
**Common Commands:**
|
||||
- `flutter pub get` - Install dependencies
|
||||
- `flutter run --dart-define=clientId=YOUR_CLIENT_ID --dart-define=secret=YOUR_CLIENT_SECRET` - Run with Twitch API credentials
|
||||
- `flutter analyze` - Run static analysis and lint checks
|
||||
- `flutter test` - Run all tests
|
||||
- `flutter build apk` / `flutter build ios` - Build release binaries
|
||||
|
||||
**Code Generation** (required after changing MobX stores or `@JsonSerializable` models):
|
||||
- `dart run build_runner build` - Generate once
|
||||
- `dart run build_runner build --delete-conflicting-outputs` - Force rebuild all
|
||||
- `dart run build_runner watch` - Watch mode for development
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
**State Management**: MobX with code generation. All stores end with `Store` and have corresponding `.g.dart` generated files.
|
||||
|
||||
**Key Directories**:
|
||||
|
||||
- `lib/screens/` - UI screens organized by feature (home, channel, settings, onboarding)
|
||||
- Each screen has its own MobX stores in a `stores/` subdirectory
|
||||
- `lib/models/` - Data models with JSON serialization (uses .g.dart files)
|
||||
- `lib/apis/` - API services for Twitch, BTTV, FFZ, and 7TV
|
||||
- `lib/widgets/` - Reusable UI components
|
||||
- `lib/utils/` - Utility modules including context extensions
|
||||
|
||||
**Main Application Flow**:
|
||||
|
||||
1. App starts in `main.dart` with Firebase initialization and dependency injection via Provider
|
||||
2. Authentication handled by `AuthStore` using Twitch OAuth
|
||||
3. Settings persisted via `SettingsStore` with SharedPreferences and MobX `autorun()`
|
||||
4. API services share a common Dio HTTP client for efficient connection reuse
|
||||
|
||||
**Global Stores** (injected via Provider in `main.dart`):
|
||||
|
||||
- `AuthStore` (`lib/screens/settings/stores/`) - Authentication state and token management
|
||||
- `SettingsStore` (`lib/screens/settings/stores/`) - User preferences with automatic persistence via MobX `autorun()`
|
||||
- `GlobalAssetsStore` (`lib/stores/`) - Shared cache for global emotes and badges across all chat tabs
|
||||
|
||||
**HTTP & Auth**: Centralized Dio client (`DioClient.createClient()`) with connection pooling and optimized timeouts. `TwitchAuthInterceptor` auto-injects auth headers for Twitch API URLs. `UnauthorizedInterceptor` catches 401 errors for token refresh. Two-tier token system: default app token + optional user token in Flutter Secure Storage.
|
||||
|
||||
## MobX Store Implementation
|
||||
|
||||
**Store Pattern**: All stores follow `StoreBase with _$StoreName` pattern:
|
||||
|
||||
```dart
|
||||
class SomeStore = SomeStoreBase with _$SomeStore;
|
||||
|
||||
abstract class SomeStoreBase with Store {
|
||||
@observable
|
||||
var someValue = '';
|
||||
|
||||
@action
|
||||
void updateValue(String value) => someValue = value;
|
||||
|
||||
@computed
|
||||
String get derivedValue => someValue.toUpperCase();
|
||||
}
|
||||
```
|
||||
|
||||
**MobX Reactions** (for side effects and persistence):
|
||||
|
||||
```dart
|
||||
// Auto-save settings whenever they change (in main.dart)
|
||||
autorun((_) => prefs.setString('settings', jsonEncode(settingsStore)));
|
||||
|
||||
// React to specific state changes
|
||||
reaction((_) => authStore.isLoggedIn, (_) => _selectedIndex = 0);
|
||||
```
|
||||
|
||||
## Chat System Architecture
|
||||
|
||||
- **Real-time IRC**: WebSocket connection to Twitch IRC with custom `IRCMessage` parsing
|
||||
- **Third-party Emotes**: Asynchronous loading of BTTV, FFZ, and 7TV assets via dedicated APIs
|
||||
- **Message Management**: 5000 message limit with 20% batch removal optimization
|
||||
- **Assets Store**: `ChatAssetsStore` manages channel-specific emotes/badges
|
||||
|
||||
## Additional Patterns
|
||||
|
||||
**Emote Architecture**: Base `Emote` class with platform-specific factories: `Emote.fromTwitch()`, `Emote.fromBTTV()`, `Emote.fromFFZ()`, `Emote.from7TV()`.
|
||||
|
||||
**Custom Cache Manager**: Uses 30-day stale period and 10k max objects. `CustomCacheManager.removeOrphanedCacheFiles()` runs on startup to clean files not in database.
|
||||
|
||||
**Secure Storage Cleanup**: First-run detection clears Flutter Secure Storage to handle Android/iOS uninstall edge case where secure storage persists but app data is wiped.
|
||||
|
||||
## API Architecture
|
||||
|
||||
**BaseApiClient Pattern**: All API services (`TwitchApi`, `BTTVApi`, `FFZApi`, `SevenTVApi`) extend `BaseApiClient` which provides:
|
||||
- Generic GET/POST/PUT/DELETE methods with centralized error handling
|
||||
- Automatic conversion of `DioException` to typed exceptions
|
||||
|
||||
**Exception Hierarchy** (in `lib/apis/base_api_client.dart`):
|
||||
- `ApiException` - Base class for all API errors
|
||||
- `NetworkException` - Connection errors (no internet)
|
||||
- `TimeoutException` - Request timeouts
|
||||
- `ServerException` - 5xx server errors
|
||||
- `NotFoundException` - 404 errors
|
||||
- `UnauthorizedException` - 401 errors (triggers token refresh)
|
||||
|
||||
## Code Style
|
||||
|
||||
**Lint Rules** (from `analysis_options.yaml`):
|
||||
- `prefer_single_quotes`, `always_use_package_imports`, `require_trailing_commas`
|
||||
- `prefer_final_locals`, `prefer_final_in_for_each`, `avoid_redundant_argument_values`
|
||||
- `directives_ordering`, `avoid_void_async`, `always_declare_return_types`, `unnecessary_parenthesis`
|
||||
|
||||
**Other**:
|
||||
- Generated `.g.dart` files must be committed alongside source changes
|
||||
|
||||
## Commit Convention
|
||||
|
||||
Commits use lowercase, descriptive messages without prefixes (e.g., `fix landscape bottom padding in chat bottom bar`, `add swipe pip gesture support`). Keep commits tightly scoped.
|
||||
@AGENTS.md
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue