Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .claude/commands/layout-debug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
description: Diagnose and fix Flutter layout, overflow, and responsive UI issues.
argument-hint: [screen, widget, or layout issue]
---

Use the `layout-debug` skill to fix Flutter layout or responsive rendering issues.

$ARGUMENTS
8 changes: 8 additions & 0 deletions .claude/commands/widget-test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
description: Add or update Flutter widget tests using this template's test harness patterns.
argument-hint: [widget, screen, or behavior to cover]
---

Use the `widget-test` skill to add or update focused Flutter widget tests.

$ARGUMENTS
1 change: 1 addition & 0 deletions .claude/skills/layout-debug
1 change: 1 addition & 0 deletions .claude/skills/widget-test
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ Existing skills:
- `review-pr-comments` — triage and resolve AI or human GitHub PR feedback
- `create-pr` — verify, commit, push, and create or update a GitHub PR
- `lint-format` — run Flutter/Dart formatting and analyzer checks
- `widget-test` — add or update focused widget tests using this template's Riverpod, localization, theme, and route patterns
- `layout-debug` — diagnose and fix Flutter overflow, constraints, scroll, and responsive layout issues
- `build-verify` — full build/test/analyze/format pass (codegen + analyze + test, then iOS + Android builds in parallel, then `dart format`); auto-scopes to the diff and leaves the working tree dirty for review
- `start-job` — run the post-spec implementation pipeline (`tasks` → `implement-tasks-sequence` → `build-verify` → `pr-review`)
- `prd` — create a Flutter feature Product Requirements Document under `.claude/tasks/<feature>/prd.md`
Expand Down
4 changes: 4 additions & 0 deletions ai/skills/feature-data-flow/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,15 @@ Feature UI
- Use `@freezed` and generated `fromJson` when the DTO is serialized.
- Keep DTO fields aligned with backend payload names and types.
- When backend enums are involved, prefer resilient parsing patterns such as explicit unknown cases where needed.
- Use Dart pattern matching or guarded switches for backend variants, nullable fields, and enum-like
strings when that makes parsing more exhaustive and easier to audit.

## Entity Guidance
- Put UI-facing or domain-facing models in `lib/common/data/entity/`.
- Entities may differ from DTOs if the UI needs a cleaner or safer shape.
- Prefer exposing entities to the rest of the app instead of leaking DTOs into widgets.
- Prefer explicit, exhaustive handling when mapping DTOs into entities. If an unknown backend value
is accepted, make the fallback visible in the mapper rather than burying it in UI code.

## Mapping Guidance
- Put mapping in an extension on the DTO when the conversion is straightforward.
Expand Down
7 changes: 6 additions & 1 deletion ai/skills/feature-screen/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ For simple static screens, `*_state.dart` and `*_event.dart` may be unnecessary.
7. Register the route in `lib/app/navigation/app_router.dart`.
8. Use shared widgets and extensions before adding new abstractions.
9. If data is needed, add DTOs, entities, and use cases in the shared locations instead of doing IO in widgets.
10. Run `make gen`, then `fvm flutter analyze`, then relevant tests.
10. Check narrow and wide layout behavior for the page content. Use `LayoutBuilder` for parent
constraint-driven layouts, wrap flexible `Row` content in `Expanded`/`Flexible`, and avoid
fixed dimensions that can overflow localized text.
11. Run `make gen`, then `fvm flutter analyze`, then relevant tests.

## Conventions To Keep
- Keep `*_page.dart` thin.
Expand All @@ -63,3 +66,5 @@ For simple static screens, `*_state.dart` and `*_event.dart` may be unnecessary.
- This template mixes fully-wired code with scaffolded placeholders. Check `lib/app/setup/setup_app.dart` before assuming a service is active.
- Do not invent a `CustomScaffold`; current template screens use `Scaffold` directly.
- Localization currently starts from `assets/localization/app_en.arb`. Add keys there and regenerate.
- If a screen overflows or needs meaningful responsive behavior, use the `layout-debug` skill before
final verification.
2 changes: 2 additions & 0 deletions ai/skills/implement/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ You are responsible for implementing one task from a Flutter feature plan while
## Applicable Skills
- `feature-screen` — when the task adds or changes a screen, route, page split, UI state, or navigation.
- `feature-data-flow` — when the task adds backend/storage data flow, DTOs, entities, use cases, or state that loads real data.
- `widget-test` — when the task changes shared UI, provider-driven visual states, or user-visible behavior that can be covered by a focused widget test.
- `layout-debug` — when the task involves overflow fixes, responsive behavior, scroll/constraint issues, or text clipping.
- `lint-format` — when running standalone and the change does not need the broader `build-verify` suite.
- `build-verify` — when running standalone and the task changed behavior, generated-code inputs, routes, platform setup, dependencies, tests, or other shared behavior.
- `pr-review` — optional standalone final check when the user asks for a review after implementation.
Expand Down
78 changes: 78 additions & 0 deletions ai/skills/layout-debug/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
name: layout-debug
description: >
Diagnose and fix Flutter layout, overflow, unbounded constraint, scroll, and responsive
rendering issues in this repository while preserving the template's existing feature,
theme, localization, and shared widget patterns. Use when UI overflows, text clips,
widgets disappear, layouts fail on mobile/tablet/desktop, or a feature needs responsive
behavior.
allowed-tools: Bash, Read, Grep, Glob, Edit, Write
model: claude-sonnet-4-6
---

# Flutter Template Layout Debug

Use this skill for UI fixes and responsive layout work in this Flutter template.

## Read First
- `AGENTS.md`
- `docs/PROJECT_OVERVIEW.md`
- `docs/PROJECT_GUIDELINES.md`
- The affected `*_page.dart` and `*_page_content.dart`
- Shared widgets in `lib/common/component/` or `lib/common/composition/` used by the screen

## Diagnosis Checklist
1. Reproduce or identify the failing viewport, text scale, platform, and state.
2. Inspect the nearest `Row`, `Column`, `Stack`, `ListView`, `SingleChildScrollView`,
`Expanded`, `Flexible`, and fixed-size widget.
3. Find whether the problem is:
- missing constraints
- conflicting constraints
- unbounded scrollable content
- fixed dimensions where content is dynamic
- text that cannot wrap or scale within its parent
- a `Stack` or overlay that visually collides with later content
4. Fix the closest layout cause instead of papering over the symptom with arbitrary sizes.

## Responsive Guidance
- Prefer `LayoutBuilder` when a widget must adapt to the actual space its parent gives it.
- Prefer `MediaQuery.sizeOf(context)` only when the whole screen size matters.
- Use constrained widths for readable desktop/tablet content, but keep page sections unframed
unless an existing shared composition already frames that content.
- Use breakpoints only when the UI meaningfully changes. Avoid sprinkling one-off magic numbers
through child widgets.
- Keep page widgets thin; place responsive branching in `*_page_content.dart` or a small local
helper widget.

## Constraint Patterns
- In a `Row`, wrap long text or flexible content with `Expanded` or `Flexible`.
- In a `Column`, avoid placing unconstrained scrollables directly inside another unbounded parent.
- Give grids and fixed-format controls stable dimensions with `aspectRatio`, `SliverGridDelegate`,
`ConstrainedBox`, or `SizedBox` when dynamic content would otherwise shift layout.
- Use `SingleChildScrollView` for small form-like pages that can overflow vertically.
- Use `CustomScrollView` or slivers for larger composed screens with independently sized sections.
- Use `SafeArea` or existing system-bar helpers when content collides with system UI.

## Text And Accessibility
- Let user-facing strings wrap unless truncation is clearly intended.
- Use `maxLines` and `overflow` only when the design has a real truncation rule.
- Verify button labels, tab labels, and card text at narrow widths.
- Do not solve text overflow by scaling font size with viewport width.

## Workflow
1. Read the affected widgets and shared components.
2. Identify the smallest widget that owns the broken constraints.
3. Patch the layout using existing theme/context extensions and shared widgets.
4. Add or update a widget test when the issue can be captured deterministically.
5. Run a narrow test when available:
```bash
fvm flutter test test/path/to/file_test.dart
```
6. Run `fvm flutter analyze` when the fix touches source code.

## Completion Criteria
- No overflow or unbounded-constraint failure remains for the reported state.
- The fix works for narrow mobile and wider tablet/desktop constraints when the screen supports
those platforms.
- Text remains readable, wraps or truncates intentionally, and does not overlap neighboring UI.
- The solution follows existing feature and shared-widget boundaries.
2 changes: 2 additions & 0 deletions ai/skills/techspec/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ Ask the user about any ambiguities:
- State boundary: a single `@riverpod` notifier or multiple cooperating providers? Sync
`Notifier` or `AsyncNotifier`?
- Navigation: new `@RoutePage` route(s), modal vs. full-screen, deep-link entry?
- Layout: mobile-only or responsive across tablet/desktop/web? Any scroll, grid, or text-wrapping
constraints that should be specified before implementation?
- Codegen scope: which generated inputs are involved (`@freezed` models with `fromJson`,
`@riverpod`, `@RoutePage`, localization, assets) — this drives when `make gen` needs to run.
- Testing strategy: which providers / use cases warrant unit tests; any widget tests required?
Expand Down
37 changes: 37 additions & 0 deletions ai/skills/upgrade/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,43 @@ Use this skill for SDK and dependency upgrades in this repository.
- generated native plugin files
12. Review GitHub Actions to ensure they still use the pinned project SDK.

## Dependency Conflict Workflow

When `pub get`, `pub upgrade`, or code generation fails because of version solving:

1. Read the full solver message and identify the smallest incompatible package chain.
2. Run:
```
fvm flutter pub outdated
```
3. Prefer changing direct dependencies in `pubspec.yaml` over editing transitive constraints.
4. Keep versioned pairs aligned, especially:
- `freezed` and `freezed_annotation`
- `json_serializable` and `json_annotation`
- `riverpod_generator`, `riverpod_annotation`, `flutter_riverpod`, and `riverpod_lint`
- `auto_route_generator` and `auto_route`
5. If a single direct dependency is blocking resolution, try the narrowest compatible constraint
first rather than a broad major-version sweep.
6. If `pubspec.lock` changes after resolution, review whether the churn matches the intended
upgrade scope. Do not hand-edit the lockfile.
7. After dependency resolution succeeds, rerun `make gen` before judging analyzer errors. Generated
code and analyzer failures are often stale until codegen completes.

## Static Analysis Fixes During Upgrades

Analyzer and lint changes are expected after SDK or package upgrades. Handle them in this order:

1. Run `fvm flutter analyze` and group failures by root cause.
2. Use mechanical fixes only when they are clearly safe:
```
fvm dart fix --dry-run
fvm dart fix --apply
```
3. Review the resulting diff carefully. Revert or adjust mechanical changes that weaken template
conventions, generated-code boundaries, or readability.
4. Fix remaining analyzer issues by following `docs/PROJECT_GUIDELINES.md` and nearby code.
5. Run `fvm dart format` only after source changes settle.

## Common SDK Resolution Failure
If `pub get` or the IDE package update reports an error like:

Expand Down
99 changes: 99 additions & 0 deletions ai/skills/widget-test/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
---
name: widget-test
description: >
Add or update Flutter widget tests in this repository using the existing test layout,
Riverpod provider overrides, generated localization, shared theme setup, and FVM test
commands. Use when a task asks for widget tests, UI regression coverage, test coverage for
a screen/component, or when implementation work changes visible Flutter behavior.
allowed-tools: Bash, Read, Grep, Glob, Edit, Write
model: claude-sonnet-4-6
---

# Flutter Template Widget Tests

Use this skill when adding focused widget coverage for a screen, shared component, or UI state in
this Flutter template.

## Read First
- `AGENTS.md`
- `docs/PROJECT_OVERVIEW.md`
- `docs/PROJECT_GUIDELINES.md`
- Nearby tests under `test/`
- The widget, provider, and state files being covered

## When To Add Widget Tests
- A shared widget gets new behavior, styling states, callbacks, or accessibility expectations.
- A feature screen adds meaningful loading, empty, error, or success states.
- A bug fix changes what the user sees or can tap.
- A regression would be cheap to catch with a `pumpWidget` test.

Do not add broad snapshot-style tests that only restate the widget tree. Prefer behavior and
contract checks: visible text, enabled/disabled states, callbacks, navigation events, empty/error
rendering, and provider-driven state transitions.

## Test Location
- Shared UI: `test/common/<widget_name>_test.dart`
- Feature UI: `test/features/<feature>/<feature>_page_content_test.dart`
- Provider-heavy feature states may also need focused provider tests; keep them near the feature
test folder unless the repo already has a stronger local pattern.

## Harness Pattern
Build the smallest wrapper that gives the widget the dependencies it expects:

Comment thread
michalurbanek marked this conversation as resolved.
```dart
Widget buildSubject({
List<Override> overrides = const [],
}) {
return ProviderScope(
overrides: overrides,
child: MaterialApp(
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
theme: AppTheme.getThemeData(brightness: Brightness.light),
home: const Scaffold(
body: SubjectWidget(),
),
),
);
}
```

Adapt imports to the current code. If the existing nearby tests use `patrolWidgetTest`,
`pumpWidgetAndSettle`, or another helper, reuse that style instead of creating a parallel harness.

## Riverpod Guidance
- Wrap provider-dependent widgets in `ProviderScope`.
- Override IO, auth, storage, and notifier providers rather than hitting real services.
- Keep overrides explicit in each test group so state does not leak between tests.
- For one-off event flows, assert the visible side effect when possible. If navigation/snackbars
are difficult to observe directly, test the notifier event separately and keep the page listener
thin.

## Route And Localization Guidance
- If the widget uses `context.router`, prefer an AutoRoute-aware harness or test the lower-level
content widget instead of the route page.
- If the widget reads `context.locale`, include generated localization delegates.
- Add localization keys in `assets/localization/app_en.arb` and run `make gen` before relying on
generated getters.

## Workflow
1. Read the widget and the closest existing tests.
2. Pick the smallest test subject that still covers the behavior.
3. Add or update test files under `test/`.
4. Use `tester.pumpWidget(...)`, `tester.pump()`, and `tester.pumpAndSettle()` intentionally;
avoid arbitrary waits.
5. Assert user-observable behavior with `find`, callback counters, and provider state.
6. Run the narrow test file first:
```bash
fvm flutter test test/path/to/file_test.dart
```
7. Run the full test suite when the change touches shared UI or state:
```bash
fvm flutter test
```

## Completion Criteria
- Tests are deterministic and isolated.
- No real network, Firebase, storage, or platform side effects run during widget tests.
- Test names describe behavior, not implementation details.
- `fvm flutter test` or the relevant narrowed test command passes.
5 changes: 5 additions & 0 deletions docs/PROJECT_GUIDELINES.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Not every feature needs every file. Simple screens in the template only use `*_p
- `CustomAppBar` is a common default for top bars.
- `Scaffold` is used directly in the current template. Do not assume a `CustomScaffold` exists.
- Edge-to-edge behavior is coordinated through `CustomSystemBarsTheme` in `lib/app/theme/custom_system_bars_theme.dart`.
- Use `LayoutBuilder` when a widget must adapt to parent constraints, and use `MediaQuery.sizeOf(context)` only when the whole screen size matters. Prefer stable constraints (`Expanded`, `Flexible`, `ConstrainedBox`, grid delegates, or aspect ratios) over fixed dimensions that can overflow with localized text or narrow viewports.

## Shared UI: Components vs Compositions
- Use `lib/common/component/` for smaller reusable building blocks such as buttons, app bars, inputs, tabs, avatars, and low-level display widgets.
Expand All @@ -44,6 +45,7 @@ Not every feature needs every file. Simple screens in the template only use `*_p
- Stateful feature providers commonly use `@riverpod` classes ending in `StateNotifier`.
- Shared notifier helpers live in `lib/core/riverpod/state_handler.dart`.
- `AsyncValueExtension.mapState` and `mapContentState` from `lib/common/extension/async_value.dart` are the standard loading, error, and empty-state helpers.
- Prefer Dart pattern matching and sealed/freezed exhaustiveness when handling union states, events, and small branching models. Keep branches explicit when missing a case would change user-visible behavior.
- Keep `@Riverpod(keepAlive: true)` for app-scoped state or long-lived services, not one-shot command providers.
- For async use-case providers, prefer reading dependencies before the first `await` and continuing with captured objects instead of calling `ref` again later.
- If an auto-dispose use-case truly must access `ref` after an async gap, keep it alive only for that operation with `final link = ref.keepAlive(); try { ... } finally { link.close(); }`.
Expand All @@ -67,6 +69,7 @@ Not every feature needs every file. Simple screens in the template only use `*_p
- Keep request and response payloads in `lib/common/data/dto/`.
- Keep app-facing models in `lib/common/data/entity/`.
- Map DTOs to entities close to the data layer instead of leaking transport models into widgets.
- When parsing backend variants, nullable fields, or enum-like strings, use explicit Dart pattern matching or guarded branches so unknown values are intentional rather than accidental.
- Keep IO-oriented logic in Riverpod use cases under `lib/common/usecase/`.
- Use `Flogger` when extra diagnostics are useful in service or integration code.

Expand Down Expand Up @@ -120,6 +123,7 @@ Not every feature needs every file. Simple screens in the template only use `*_p
- Treat `.fvmrc` and `pubspec.yaml` as the source of truth for SDK and package versions.
- When upgrading Flutter, align the Flutter version in `pubspec.yaml` with `.fvmrc`.
- After SDK or dependency upgrades, run `fvm flutter pub get`, `make gen`, `fvm flutter analyze`, and `fvm flutter test`.
- Resolve package conflicts from the smallest incompatible dependency chain first. Prefer updating direct constraints in `pubspec.yaml`, keep generator/runtime annotation pairs aligned, and let `pub` regenerate `pubspec.lock` instead of editing it by hand.
- Re-check generator compatibility when touching versioned pairs such as:
- `freezed` and `freezed_annotation`
- `json_serializable` and `json_annotation`
Expand All @@ -134,6 +138,7 @@ Not every feature needs every file. Simple screens in the template only use `*_p
- `make integration_test` runs `patrol test --flavor develop`.
- For Android integration tests, ensure `adb` is already available on your shell `PATH`.
- Add or update tests when the task calls for behavior changes, bug fixes, or new features. Do not assume tests are off-limits.
- Prefer focused widget tests for shared UI, provider-driven visual states, and user-visible bug fixes. Wrap provider-dependent widgets in `ProviderScope`, override IO-facing providers, include generated localization delegates when using `context.locale`, and avoid real network, Firebase, storage, or platform side effects in widget tests.
Comment thread
michalurbanek marked this conversation as resolved.
Outdated

## Release And Versioning Notes
- The repo contains release-oriented files and commands such as `release_notes.txt`, Android app bundle generation, and iOS IPA generation.
Expand Down
Loading