Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
94 changes: 94 additions & 0 deletions ai/skills/layout-debug/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
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

## Error Signatures
Map console/stack-trace error strings directly to fixes before broader diagnosis:

- **"Vertical viewport was given unbounded height"** — a scrollable (`ListView`, `GridView`)
sits inside an unconstrained vertical parent (usually a `Column`). Wrap the scrollable in
`Expanded`, or give it an explicit height via `SizedBox`/`ConstrainedBox`.
- **"An InputDecorator...cannot have an unbounded width"** — a `TextField`/`TextFormField` sits
inside an unconstrained horizontal parent (usually a `Row`). Wrap it in `Expanded` or `Flexible`.
- **"RenderFlex overflowed by N pixels"** — a `Row`/`Column` child requests more space than the
parent allows (yellow/black stripes). Wrap the overflowing child in `Expanded` or `Flexible`,
or let text wrap.
- **"Incorrect use of ParentData widget"** — `Expanded`/`Flexible` is not a direct child of a
`Row`/`Column`/`Flex`, or `Positioned` is not a direct child of a `Stack`. Move it so it is.
- **"RenderBox was not laid out"** — cascading side effect, not the root cause. Ignore it and
look further up the output for the primary constraint violation above.

## 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
42 changes: 42 additions & 0 deletions ai/skills/upgrade/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,48 @@ 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. After minor/patch upgrades, run `fvm flutter pub upgrade --tighten` to raise the lower bounds
in `pubspec.yaml` to the versions actually resolved, keeping constraints honest.
7. If `pubspec.lock` changes after resolution, review whether the churn matches the intended
upgrade scope. Do not hand-edit the lockfile, with one exception: when a single package is
retracted or stuck in a conflict, delete only that package's block from `pubspec.lock` and
rerun `fvm flutter pub get` so pub re-resolves just that package. Never delete the whole
lockfile to force a clean resolve — that causes uncontrolled upgrades across the entire graph.
8. 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
102 changes: 102 additions & 0 deletions ai/skills/widget-test/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
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
Call `Configuration.setup(flavor: Flavor.develop)` at the top of `main()` before any test runs —
existing tests in `test/common/` do this and widgets that read configuration fail without it.

Build the smallest wrapper that gives the widget the dependencies it expects:

```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.
Loading
Loading