Imported from AbdallahRehab/weatherly (
AGENTS.md). Install upstream withnpx skills add AbdallahRehab/weatherly. Copyright stays with the author.
Agent guide — weatherly
Project
weatherly — Weatherly is a lightweight Flutter weather application that allows users to search for real-time weather information by city name. Built with Clean Architecture principles and Bloc for state management, the app fetches live data from WeatherAPI, displaying current temperature, weather conditions, and corresponding icons in a responsive, modular UI. It handles network and input errors gracefully, and supports offline access through local caching of the last successful weather query.
Generated by FlutterInit. Package: com.example.weatherly.
Stack
| Area | Choice |
|---|---|
| Architecture | clean |
| State management | bloc |
| Navigation | go_router |
| Backend | custom |
| Networking | Dio |
| Local storage | SharedPreferences, Secure storage |
| Theme preset | material3 |
| Dark mode | enabled (follows system) |
| ScreenUtil | yes |
| Localization | easy_localization (en, ar) |
| Flutter Hooks | enabled |
| Dotenv | enabled |
Architecture (clean)
lib/src/
├── features/<feature>/
│ ├── data/ # datasources, models, repository impls
│ ├── domain/ # entities, repo contracts, use cases
│ └── presentation/ # screens, widgets, state (bloc)
├── routing/
├── services/
├── shared/
└── theme/
Rules
domain/is pure Dart — no Flutter imports, no imports fromdata/.data/implements contracts fromdomain/— never the reverse.- Entities are not models — no
fromJson/toJsonon domain entities. - Use cases expose a single responsibility (typically one public
call()). presentation/talks to use cases or state layer — not datasources directly.
State management (bloc)
- Events and states are immutable — prefer
constconstructors. BlocBuilderfor UI rebuilds;BlocListenerfor side effects;BlocConsumerwhen both are needed.- Keep handlers thin — delegate to use cases, repositories, or services.
- One bloc per feature flow — do not share blocs across unrelated features.
Navigation
- All routes are defined in
lib/src/routing/app_router.dart— do not scatter route tables elsewhere. - Prefer typed/named routes from the central config — avoid hard-coded path strings in widgets when a named route exists.
context.go()replaces the stack;context.push()pushes on top.- Redirects and guards belong in the router configuration, not inside individual screens.
Backend (custom)
- HTTP/Dio client is configured in
lib/src/config/app_config.dart. - API calls belong in
lib/src/services/(e.g. auth service) using the shared client. - Base URL comes from environment / config — see SETUP.md.
For console setup (keys, native files, env), follow SETUP.md — do not duplicate platform steps here.
Networking
- Use the shared
Dioinstance fromlib/src/config/app_config.dart— neverDio()inside a widget or screen. - Extend or use existing services under
lib/src/services/for HTTP calls. - Map transport errors to
Failure/FutureEitherresults viarunTask()— do not leak rawDioExceptionto UI.
Services & shared conventions
- Services are singletons with
ClassName.instance, returningFutureEither<T>viarunTask(). - Never pass
BuildContextinto services — userootContextfrom the global navigator helper when UI is required. - Logging:
AppLogger; user feedback:showGlobalToast(); dialogs:showAppDialog()/context.showAppDialog(). - Primary import barrel:
package:weatherly/src/imports/imports.dart. - File names:
snake_case.dart; classes:PascalCase; private members:_camelCase. - Prefer
constconstructors where possible; avoiddynamicwithout justification. - No empty
catchblocks — log, map to failure, or rethrow. - Do not add packages that duplicate existing stack choices (routing, state, backend).
Dart / Flutter anti-patterns
-
No business logic in widget
build()methods. -
No direct backend or network calls from presentation widgets.
-
Do not put heavy logic inside bloc event handlers — delegate outward.
Key packages
-
go_router— declarative routing -
flutter_bloc— state management -
dio -
shared_preferences -
flutter_secure_storage -
cached_network_image -
geolocator -
easy_localization -
flutter_screenutil -
flutter_hooks -
flutter_dotenv -
skeletonizer
How to add a new feature
- Create domain entity and repository contract under
lib/src/features/<feature>/domain/. - Add use case(s) in
domain/usecases/(single responsibility). - Add data model, datasource, and repository implementation under
data/. - Wire state (bloc) under
presentation/. - Build screens and widgets under
presentation/. - Register the route in
lib/src/routing/app_router.dart. - Export new public API only through existing barrel files if needed.
Safe to modify
| Path | Guidance |
|---|---|
lib/src/features/** |
Feature screens, widgets, domain/data/presentation code |
| lib/src/shared/widgets/** | Reusable UI components |
| lib/src/shared/helpers/** | App-wide helpers (when not generated-only) |
| test/** | Unit and widget tests |
| README.md | Project documentation |
Modify with caution
| Path | Why |
|---|---|
lib/src/routing/app_router.dart |
Central navigation — breaks deep links if wrong |
lib/main.dart |
Initialization order (Firebase, dotenv, localization, flavors) |
lib/src/config/app_config.dart |
SDK and HTTP client setup |
lib/src/theme/** |
Global visual system |
lib/src/imports/** |
Barrel exports — keep pattern consistent |
pubspec.yaml |
Dependency graph for the whole app |
.env |
Secrets — never commit real values |
Do not touch
| Path | Why |
|---|---|
android/, ios/, web/, desktop folders |
Native project configuration |
.env with real secrets |
Security |
Verification after changes
flutter pub get
flutter analyze
Code generation
No build_runner step is required for the selected stack.
Localization
After editing assets/translations/*.json:
flutter pub run easy_localization:generate -S assets/translations -O lib/src/core/i18n -o locale_keys.g.dart
flutter test
Hard limits
- Do not disable
flutter_lintsrules without an explanatory comment. - Do not call backend or networking code directly from widgets.
- Do not commit
.envfiles containing production secrets. - Do not introduce a second state-management or routing library.
- For platform setup and API keys, use SETUP.md.
- For UI tokens and spacing, use DESIGN.md.