Not in the top 1,000 by GitHub stars
zakariaf/Flutter-Skills
General, reusable Flutter engineering skills for AI coding agents — architecture, Riverpod 3.x, testing, persistence, i18n/RTL, accessibility, navigation & more. Agent Skills open standard; works with Claude Code, Cursor, Codex & 70+ agents.
History
Review weekly changes to SKILL.md before updating. Dates mark the weeks in which we observed each version; checks apply to the recorded commits.
View weekly changes
skills/accessibility-as-code/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Instructions only
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/adaptive-layout/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/ads-and-iap-monetization/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/app-startup-and-bootstrap/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Instructions only
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/async-safety/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Instructions only
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/ci-pipeline-and-gates/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Network or broad shell
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/codegen-and-toolchain/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/custom-canvas-and-gestures/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/dart3-idioms-and-coding-standards/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/dartdoc-conventions/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Instructions only
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/data-export-and-restore/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Instructions only
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/dependency-hygiene/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Network or broad shell
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/design-review-workflow/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Instructions only
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/design-system-structure/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/error-handling-typed-results/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/flutter-architecture/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/flutter-conventions-index/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Instructions only
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/flutter-performance/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Instructions only
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/forms-and-input/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/i18n-rtl-l10n/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Network or broad shell
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/lint-and-style-config/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/local-notifications-scheduler/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/motion-and-haptics/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Instructions only
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/naming-conventions/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Instructions only
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/navigation-and-routing/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/persistence-drift/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/project-structure-and-packages/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/release-and-store-shipping/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Network or broad shell
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/run-codegen/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Instructions only
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/run-goldens-rebaseline/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Instructions only
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/run-migration/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Instructions only
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/scaffold-feature-module/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/seeded-determinism-and-golden-vectors/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/service-boundary-and-native/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/state-management-riverpod/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/testing-strategy/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/ui-states-and-feedback/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Instructions only
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/value-objects-money-and-units/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/widget-composition/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
skills/widget-golden-and-a11y-testing/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Local scripts
First observation → e073e5ea10c9
No earlier version was observed for comparison.
Verified commit e073e5ea10c963d2c52ab1e423bd314c28a56154
git clone --filter=blob:none --no-checkout https://github.com/zakariaf/Flutter-Skills.git .hotskills/zakariaf-flutter-skills && git -C .hotskills/zakariaf-flutter-skills checkout --detach e073e5ea10c963d2c52ab1e423bd314c28a56154
# Copy each selected skill directory from .hotskills/zakariaf-flutter-skills into .claude/skills/<skill-name>/git clone --filter=blob:none --no-checkout https://github.com/zakariaf/Flutter-Skills.git .hotskills/zakariaf-flutter-skills && git -C .hotskills/zakariaf-flutter-skills checkout --detach e073e5ea10c963d2c52ab1e423bd314c28a56154
# Copy each selected skill directory from .hotskills/zakariaf-flutter-skills into .agents/skills/<skill-name>/Heat
2.9- Star growth, last 7 daysNot available
- Star growth, last 24 hoursNot available
- Rank movement, last 7 daysNot available
- Commits, last 30 daysNot available
- Accounts asking about it through MCP, last 7 daysNot available
- Hot votes this weekNot available
Heat never changes the order by stars, and sponsorship never touches it. How heat works
Stars over time
30-day change not yet available: not enough history.
Individual skills in this repository
- accessibility-as-code
skills/accessibility-as-code - adaptive-layout
skills/adaptive-layout - ads-and-iap-monetization
skills/ads-and-iap-monetization - app-startup-and-bootstrap
skills/app-startup-and-bootstrap - async-safety
skills/async-safety - ci-pipeline-and-gates
skills/ci-pipeline-and-gates - codegen-and-toolchain
skills/codegen-and-toolchain - custom-canvas-and-gestures
skills/custom-canvas-and-gestures - dart3-idioms-and-coding-standards
skills/dart3-idioms-and-coding-standards - dartdoc-conventions
skills/dartdoc-conventions - data-export-and-restore
skills/data-export-and-restore - dependency-hygiene
skills/dependency-hygiene - design-review-workflow
skills/design-review-workflow - design-system-structure
skills/design-system-structure - error-handling-typed-results
skills/error-handling-typed-results - flutter-architecture
skills/flutter-architecture - flutter-conventions-index
skills/flutter-conventions-index - flutter-performance
skills/flutter-performance - forms-and-input
skills/forms-and-input - i18n-rtl-l10n
skills/i18n-rtl-l10n - lint-and-style-config
skills/lint-and-style-config - local-notifications-scheduler
skills/local-notifications-scheduler - motion-and-haptics
skills/motion-and-haptics - naming-conventions
skills/naming-conventions - navigation-and-routing
skills/navigation-and-routing - persistence-drift
skills/persistence-drift - project-structure-and-packages
skills/project-structure-and-packages - release-and-store-shipping
skills/release-and-store-shipping - run-codegen
skills/run-codegen - run-goldens-rebaseline
skills/run-goldens-rebaseline - run-migration
skills/run-migration - scaffold-feature-module
skills/scaffold-feature-module - seeded-determinism-and-golden-vectors
skills/seeded-determinism-and-golden-vectors - service-boundary-and-native
skills/service-boundary-and-native - state-management-riverpod
skills/state-management-riverpod - testing-strategy
skills/testing-strategy - ui-states-and-feedback
skills/ui-states-and-feedback - value-objects-money-and-units
skills/value-objects-money-and-units - widget-composition
skills/widget-composition - widget-golden-and-a11y-testing
skills/widget-golden-and-a11y-testing
How it works
accessibility-as-code
When your agent uses it
Enforces accessibility as a correctness property authored into each widget — Semantics(button/label) or ExcludeSemantics on every node, a11y state read from MediaQuery not app state, never MediaQuery.withClampedTextScaling / textScaleFactor / FittedBox / TextOverflow.ellipsis to fit a label, non-color redundant channels (icon+label+shape+text) for every state, contrast against composited backgrounds (4.5:1 body / 3:1 large), 44px single-tap targets, OrdinalSortKey traversal, and honoring boldText / reduce-motion. Use when adding a GestureDetector/InkWell or any tap target, adding an Icon or Image, reaching for withClampedTextScaling/FittedBox/ellipsis/textScaleFactor to make text fit, encoding state via color, sizing type, ordering focus traversal, or reviewing any View for screen-reader/switch/low-vision support.
What it loads into context
Frontmatter
198 tokensAlways available to the agent
SKILL.md
3,743 tokensWhen the skill is activated
Reference documents
0 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- Where a11y state comes from
- The tap target, wrong and right
- Text scale: the instinct is the bug
- Never state through color alone
- Contrast against the composited background
- Traversal order is a design decision
- Anti-patterns
- Definition of done
- Related skills
- References
Files
../../.claude-plugin/marketplace.jsonasset504 bytes../../.claude-plugin/plugin.jsonasset616 bytesSKILL.mdcore16,192 bytesSKILL.mdcore16,192 bytesSKILL.mdcore16,192 bytesSKILL.mdcore16,192 bytes
Read SKILL.md
# Accessibility is a coding standard, not a checklist
Accessibility is authored into the widget as you write it — the same tier as "the button actually works." There is no lint for any of this: `flutter_lints` and `very_good_analysis` ship zero a11y rules. Enforcement is the widget itself, review of your own diff, and widget tests. Applies to every interactive View, every `Icon`/`Image`, every state, and every color choice.
Testing mechanics (guideline matchers, golden lanes, RTL, honest conformance limits) live in `widget-golden-and-a11y-testing`; this skill is the authoring discipline.
## Non-negotiable rules
1. **Every interactive node gets `Semantics(button: true, label: ...)`** — a raw `GestureDetector` with no semantics silently locks out every screen-reader and switch user. Correct semantics make TalkBack, VoiceOver, Switch Access and Switch Control work for free; it is definition-of-done, never a backlog ticket.
2. **Every `Icon`/`Image` gets a `semanticLabel`, or is wrapped in `ExcludeSemantics`** because it is decorative. There is no third option — an unlabelled `Icon` is invisible to a screen reader.
3. **Read a11y state from `MediaQuery` at build time, never from app state.** `MediaQuery` is an `InheritedWidget` with correct-by-construction invalidation; pushing it through a provider trades a compiler-guaranteed rebuild for a frame of staleness in the one area where being wrong is total failure.
4. **Never `MediaQuery.withClampedTextScaling`, never `textScaleFactor`.** Both are clamping hacks that silently defeat the text-scale matrix while contrast and tap-target guidelines still pass green. Enforce with a source grep (see Anti-patterns).
5. **Never `FittedBox`, computed `fontSize`, or `TextOverflow.ellipsis` to make a label fit.** They turn "doesn't fit at 200%" from a loud test failure into truncated or shrunk text on a device. Build flexible heights and let text wrap.
6. **Never encode state through color alone.** Pair every stateful signal with at least one non-color channel — icon + text label + shape/pattern + position. Color-only state is invisible under `invertColors`, grayscale color-correction, and to every screen-reader user.View the complete source on GitHubadaptive-layout
When your agent uses it
Enforces adapting layout by available CONSTRAINTS/size, never device or platform checks — LayoutBuilder + MediaQuery.sizeOf/paddingOf/viewInsetsOf (not .of) for narrow rebuilds, Material 3 window size classes (compact <600, medium 600-840, expanded 840-1200, large >1200) as the breakpoint vocabulary, navigation affordance chosen by width (NavigationBar → NavigationRail → NavigationDrawer), list-detail single-pane-vs-two-pane, readable max-width via ConstrainedBox, Flexible/Expanded/FractionallySizedBox over fixed widths, SafeArea + display cutouts + keyboard insets, never lock orientation, foldable/hinge awareness via MediaQuery.displayFeatures, and golden-matrix verification across sizes. Use when building responsive or adaptive UI, tablet/desktop/foldable support, master-detail or two-pane screens, a NavigationRail-vs-BottomNav shell, breakpoints, LayoutBuilder, MediaQuery sizing, SafeArea/cutouts, or fixing overflow at large widths.
What it loads into context
Frontmatter
218 tokensAlways available to the agent
SKILL.md
2,587 tokensWhen the skill is activated
Reference documents
3,317 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- Size classes as one shared enum
- Readable width and flexible regions
- Insets, cutouts, keyboard, foldables
- Navigation affordance by width
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/check_adaptive.sh
Files
SKILL.mdcore11,036 bytesexamples/adaptive_scaffold.dartasset5,664 bytesexamples/list_detail_pane.dartasset6,040 bytesreferences/list-detail-and-navigation.mddoc6,804 bytesreferences/window-size-classes.mddoc8,185 bytesscripts/check_adaptive.shruns2,190 bytes
Read SKILL.md
# Adaptive Layout
Adapt to the **space you are given**, never to the device you think you are on. A phone in a foldable's front display, a resized desktop window, and a tablet in split-screen all defeat `Platform.isX` checks — but they all report their real constraints. Branch on width, not hardware.
Read the reference for the task at hand:
- `references/window-size-classes.md` — the Material 3 window size-class breakpoints as a shared vocabulary, the `WindowSizeClass` enum pattern, `MediaQuery.sizeOf`/`paddingOf`/`viewInsetsOf` vs `.of`, readable max-width, SafeArea and display cutouts, keyboard insets, orientation, foldable hinge awareness.
- `references/list-detail-and-navigation.md` — single-pane-navigate vs side-by-side two-pane, choosing the navigation affordance by width and coordinating with the go_router shell, keeping selection state in a Notifier so both panes agree.
Run `scripts/check_adaptive.sh` before a PR.
## Non-negotiable rules
1. **Adapt by constraints/size, never by device or platform.** No `Platform.isAndroid`/`Platform.isIOS`/`kIsWeb` to pick a *layout*. Use `LayoutBuilder` (local box constraints) or `MediaQuery.sizeOf(context)` (window size). WHY: a resized window, split-screen, and foldable all break device checks; constraints are always true.View the complete source on GitHubads-and-iap-monetization
When your agent uses it
Enforces opt-in, rewarded-first monetization over the service seam — a rewarded view grants exactly one benefit and only on a genuine reward outcome (a sealed Rewarded/Dismissed/NoFill), earn loops capped per day against an injected Clock, the earn control preloaded and hidden unless an ad is loaded so a fresh account never dead-ends on "no ads available" (a Guideline 2.1 risk), interstitials only at a natural break under a count-and-elapsed cap owned by the service so callers stay dumb, no banner on the primary work surface, one non-consumable unlock plus Restore re-checked each launch and committed through the single write path before the UI reacts, one derived isEntitled provider as the only gate, and the entitlement restored BEFORE the ad SDK initializes so a paying user never starts it, resolves consent, or sees a tracking prompt. Use when adding ads, wiring a rewarded earn loop, placing an interstitial, building a paywall, gating an entitlement, or setting up ad units.
What it loads into context
Frontmatter
242 tokensAlways available to the agent
SKILL.md
3,442 tokensWhen the skill is activated
Reference documents
2,254 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The earn loop, end to end
- Launch order
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/check-release-ad-ids.sh
Files
SKILL.mdcore14,694 bytesexamples/rewarded_credit_economy.dartasset8,446 bytesreferences/ad-unit-setup.mddoc5,092 bytesreferences/entitlement-and-restore.mddoc4,744 bytesscripts/check-release-ad-ids.shruns2,848 bytes
Read SKILL.md
# Ads and IAP monetization
The policy layer over the ads and billing seams: *what* a rewarded view grants, *when* an
interstitial may fire and how often, *how* an entitlement gates both, and *in what order* they
initialize at launch. It assumes the seam already exists — declaring the interface, overriding it per
flavor, and keeping SDK types out of feature code belong to `service-boundary-and-native`.
The model this encodes is **free, opt-in-first**: value is exchanged for attention the user chose to
give, and one non-consumable purchase removes the exchange. It is not the only viable model, but the
rules below are what keep any ad-funded app honest, reviewable, and out of the "feels like adware"
bucket.
## Non-negotiable rules
View the complete source on GitHubapp-startup-and-bootstrap
When your agent uses it
Enforces a fixed main() cold-launch order — crash-log sink + FlutterError.onError + PlatformDispatcher.onError installed BEFORE any code that can throw, settings/theme read before runApp so the first frame paints correct, real infra constructed in a composition-root bootstrap() and injected via ProviderScope overrideWithValue over throwing placeholder providers, non-blocking warm-up deferred to addPostFrameCallback, exactly two error handlers with NO runZonedGuarded, ProviderException unwrapped before logging, and a WidgetsBindingObserver that flushes durable state on background/resume. Use when editing lib/main.dart, main_<flavor>.dart, bootstrap.dart or app.dart, reordering anything in main(), adding a splash/onboarding/permission gate, restoring theme before first paint, wiring a DB or service into ProviderScope, handling app-lifecycle background/resume flushes, or chasing cold-start latency, ANRs, or first-frame jank.
What it loads into context
Frontmatter
197 tokensAlways available to the agent
SKILL.md
3,598 tokensWhen the skill is activated
Reference documents
0 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The sequence
- The two error handlers
- The composition root
- Deferred warm-up
- App lifecycle: flush on background
- The one blocker: opening the DB
- Anti-patterns
- Definition of done
- Related skills
- References
- Provider / ChangeNotifier appendix
Files
SKILL.mdcore16,331 bytesSKILL.mdcore16,331 bytes
Read SKILL.md
# App startup and bootstrap
`main()` has one job: install a crash net, read the little state the first frame needs, wire real dependencies into the tree, and hand off to `runApp` — fast, ordered, and unable to hide a failure. Everything expensive happens after the first frame or off the launch path entirely.
## Non-negotiable rules
1. **Error handlers go first, before anything that can throw.** A crash-log sink, `FlutterError.onError`, and `PlatformDispatcher.instance.onError` are installed immediately after `WidgetsFlutterBinding.ensureInitialized()`. The step most likely to throw is opening the DB; installing handlers after it inverts the whole point.
2. **Exactly two error handlers — no zone.** `FlutterError.onError` (build/layout/paint errors) and `PlatformDispatcher.instance.onError` (uncaught async errors) cover every path. **Never add `runZonedGuarded`.** The "you need all three" advice is crash-SDK advice (Sentry wraps its init in a zone); with no such SDK a zone buys nothing and costs a documented zone-mismatch footgun. Flutter's own fix for that warning is to remove zones.
3. **`PlatformDispatcher.onError` returns `true` unconditionally.** Returning `false` routes to the embedder fallback, where the process may exit or hang. Get debug-console visibility from `debugPrint` under `kDebugMode`, not from `return kReleaseMode`.
4. **Never let an error handler throw.** Wrap its body in a bare `try/catch (_)` and keep the comment explaining why the discarded error is deliberate — otherwise someone "fixes" it into infinite recursion inside the handler.
5. **Read settings/theme before `runApp`.** Palette, text-scale policy, locale, and any first-paint choice are read synchronously (a handful of rows is sub-10ms) so frame one paints correct. A flash of the wrong theme is a visible defect, not a cosmetic one.
6. **Construct real infra in a composition-root `bootstrap()`, inject via overrides.** Feature code depends on **throwing placeholder providers**; `bootstrap()` builds the real DB/services and `overrideWithValue`s them in the root `ProviderScope`. A forgotten wiring fails loudly at startup, never returns null. This is also the test seam.
7. **Defer warm-up to `addPostFrameCallback`; never await it in `main()`.** Any plugin/engine warm-up (audio, TTS, first network handshake) runs its cost synchronously on the main thread and produces ANRs on the cold-start path. Fire it best-effort after the first usable frame.
8. **Do not block the first frame.** The only launch-path `await` is the one unavoidable blocker (opening the DB). Show the UI shell immediately rather than a blank window while a migration runs.View the complete source on GitHubasync-safety
When your agent uses it
Enforces no-silent-failure async discipline in Flutter/Dart — the arrow-callback Future-drop hole no lint catches (`onTap: () => vm.save(x)`), void-returning event handlers, a mounted/ref.mounted guard after EVERY await before touching BuildContext, capturing Navigator/ScaffoldMessenger before the gap, honest `unawaited()` that always ends in catchError, no empty/bare catches, `rethrow` over `throw e`, and disposing every StreamSubscription/StreamController/Timer/sink. Use when writing or reviewing async/await, wiring onTap/onPressed/onSubmitted or any VoidCallback, touching BuildContext after an await, writing initState/dispose/addPostFrameCallback, adding a Timer or Future.delayed, writing a try/catch, or seeing use_build_context_synchronously, cancel_subscriptions, close_sinks, unawaited_futures, or discarded_futures.
What it loads into context
Frontmatter
193 tokensAlways available to the agent
SKILL.md
3,686 tokensWhen the skill is activated
Reference documents
0 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The hole no lint catches
- The async gap and BuildContext
- unawaited, initState, and the first frame
- Subscriptions, controllers, timers
- Catches
- Anti-patterns
- Catalogue your silent-failure modes
- Definition of done
- Related skills
- References
Files
SKILL.mdcore14,815 bytes
Read SKILL.md
# Async safety: no failure may be silent
Async bugs are silence. A dropped `Future` swallows its error; a dead `BuildContext` throws into a void; a leaked subscription fires into a disposed widget. An app with no telemetry has exactly two feedback loops — the analyzer and the test suite — and the analyzer has one hole big enough to drive the product through. Close it structurally, not with discipline. This skill applies whenever you write `async`/`await`, wire a callback, or hold a subscription, timer, or sink.
## Non-negotiable rules
1. **A callback must never touch a `Future`.** Every `onTap`/`onPressed`/`onSubmitted`/`VoidCallback` handler returns `void`. `onTap: () => vm.save(x)` where `save` is async is caught by NO lint (see below) — the fix is shape, not vigilance.
2. **A `mounted` / `ref.mounted` guard goes after EVERY await, immediately before the next `BuildContext` use** — never once at the top, never before the await where it proves nothing. Or capture the object you need before the gap.
3. **Multiple awaits ⇒ the guard sits after the LAST one.** A guard only certifies the interval since the most recent suspension point.
4. **`unawaited(x)` is legal only if `x` provably cannot fail silently** — it ends in a `.catchError(...)` or is total. Bare `unawaited(f)` routes errors to `PlatformDispatcher.onError`, detached from the UI. That is silence with a permission slip.
5. **Every `StreamSubscription`, `StreamController`, `Timer`, and sink is released** in `dispose()` / `ref.onDispose`. Prefer not owning it: a provider gives teardown for free.
6. **Every timer/stream callback that calls `setState` guards `mounted` first.** A `Timer` holds a strong reference to its closure and fires happily after the widget is gone.
7. **No empty catch, no bare catch, no swallow.** Every `catch` has an `on` clause (except the crash logger's own write), logs with its stack, and surfaces the failure. Use `rethrow`, never `throw e` — the latter resets the stack trace.
8. **Never `assert` a platform/plugin return value.** Asserts are stripped in release: green in every test, absent on the device — the perfect silent-failure bug.View the complete source on GitHubci-pipeline-and-gates
When your agent uses it
Enforces a lean GitHub Actions Flutter CI where every gate maps to one named release-blocking contract — pinned runner + subosito/flutter-action@v2 toolchain, dart format --set-exit-if-changed, flutter analyze --fatal-infos, build_runner and drift schema freshness (git diff --exit-code), flutter test --test-randomize-ordering-seed random, static import/banned-string greps that catch what runtime can't, coverage-as-report-never-a-gate with the upward-lie fixed, verify-never-bless goldens (no --update-goldens in CI), and an honest statement of what CI cannot prove (audio, real fonts, on-device behaviour). Use when editing .github/workflows/*.yml, adding or removing a job or step, wiring a codegen/schema/format/analyze/coverage gate, writing a grep-based policy test or gate script under test/policy or tool/, pinning action versions, or claiming CI proves something it can't.
What it loads into context
Frontmatter
214 tokensAlways available to the agent
SKILL.md
3,865 tokensWhen the skill is activated
Reference documents
3,458 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The single workflow (single-package default)
- Freshness gates: run the generator, diff the output
- Static gates: grep the source graph, fail once
- Coverage: measure, publish, do not gate
- Goldens in CI: verify, never bless
- When multi-package (workspace)
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/banned-strings.shscripts/ci-gates.sh
Files
SKILL.mdcore16,310 bytesSKILL.mdcore16,310 bytesSKILL.mdcore16,310 bytesSKILL.mdcore16,310 bytesexamples/policy_grep_test.dartasset5,011 bytesreferences/policy-grep-gate.mddoc6,036 bytesreferences/workflow-skeleton.mddoc8,228 bytesscripts/banned-strings.shruns2,726 bytesscripts/ci-gates.shruns2,267 bytes
Read SKILL.md
# CI Pipeline & Gates
A CI gate is not a decorative green check — it converts one release-blocking contract into a check a build either passes or fails, *without trusting a human*. Keep the pipeline lean: one workflow file for most single-package apps, every job pinned, every gate traceable to a named contract, and an honest note wherever CI cannot prove the thing that actually matters.
Read the reference for the task at hand:
- `references/workflow-skeleton.md` — the copy-paste single-file `ci.yml`: pinned runner + toolchain, freshness gates, format/analyze, randomized tests, host-sqlite, coverage-strip, and the release-build job.
- `references/policy-grep-gate.md` — the grep-based invariant gate: the three-criteria bar, strip-comments-first, anchor-to-structure, accumulate-and-fail-once, write-the-reason-for-a-stranger.
Run `scripts/ci-gates.sh` and `scripts/banned-strings.sh` before a PR to reproduce the static gates locally.
## Non-negotiable rules
1. **Every gate maps to exactly one named contract — name it.** A check that serves no stated contract is not a gate: make it advisory and say so, or don't add it. Never invent a merge-blocker with nothing behind it. This keeps the pipeline auditable and stops gate-sprawl.View the complete source on GitHubcodegen-and-toolchain
When your agent uses it
Enforces a deterministic build_runner codegen discipline: run one pinned `dart run build_runner build --delete-conflicting-outputs` pass BEFORE `flutter analyze` (never after), fence every builder with `generate_for:` globs in a per-package `build.yaml`, make one deliberate commit-vs-gitignore decision for `*.g.dart`/`*.freezed.dart`/`*.drift.dart` and back it with the matching CI gate (freshness diff if committed, codegen-first if gitignored), mirror the generated-file globs into the analyzer AND coverage excludes, pin the SDK, and never hand-edit generated output. Use when editing build.yaml, analysis_options.yaml, pubspec.yaml, .gitignore, .gitattributes, or CI workflows; wiring drift_dev/freezed/json_serializable/riverpod_generator/ gen-l10n/mockito codegen; fixing "missing part file", "undefined class _$Foo", or "conflicting outputs" errors; deciding whether to commit generated code; or scoping builders so one edit does not regenerate everything.
What it loads into context
Frontmatter
251 tokensAlways available to the agent
SKILL.md
2,356 tokensWhen the skill is activated
Reference documents
3,317 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The canonical command
- Scoping builders with build.yaml
- Commit vs gitignore: pick one, wire its gate
- Analyzer and coverage excludes
- When multi-package (workspace)
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/check-codegen-hygiene.shscripts/regen.sh
Files
SKILL.mdcore9,821 bytesSKILL.mdcore9,821 bytesSKILL.mdcore9,821 bytesSKILL.mdcore9,821 bytesSKILL.mdcore9,821 bytesSKILL.mdcore9,821 bytesSKILL.mdcore9,821 bytesSKILL.mdcore9,821 bytesexamples/build.yamlasset1,695 bytesexamples/gitattributes.exampleasset614 bytesreferences/codegen-scoping.mddoc5,225 bytesreferences/commit-vs-gitignore.mddoc3,645 bytesreferences/toolchain-and-workspace.mddoc4,543 bytesscripts/check-codegen-hygiene.shruns3,577 bytesscripts/regen.shruns1,552 bytes
Read SKILL.md
# Codegen and toolchain
One deterministic codegen pass is the source of truth for every generated file;
run it first, scope it tightly, and decide once whether its output lives in git.
Applies whenever a project uses `build_runner` or `gen-l10n`.
Read the reference for the task at hand:
- `references/codegen-scoping.md` — the generator inventory, `generate_for:`
scoping tables, error-to-fix recovery map.
- `references/commit-vs-gitignore.md` — the two committed/gitignored strategies,
their tradeoffs, and the exact CI gate each one requires.
- `references/toolchain-and-workspace.md` — SDK pinning, analyzer/coverage
excludes, and the multi-package workspace layering (fenced, opt-in).
View the complete source on GitHubcustom-canvas-and-gestures
When your agent uses it
Enforces CustomPainter/Canvas discipline — the View/Painter/Scene split with a dumb painter fed one immutable Scene value type, shouldRepaint as a single value compare kept strictly separate from the AnimationController-as-repaint animation path, one shared affine transform read by BOTH painter and hit-tester (toCanvas/toLogical exact inverses, never re-derive scale), geometry hit-testing (integer lattice or rasterized region-ID buffer, never Path.contains), zero-allocation paint(), gesture-as-pure-translator emitting a typed command to a Notifier (never mutating in the handler), ExcludeSemantics + sibling Semantics speaking display values with redundant non-colour encoding, measured TextPainter fitting, first-party RoundedSuperellipseBorder, physical-pixel hairlines, and Directional-only geometry. Use when writing or reviewing a CustomPainter/CustomPaint, gestures on a canvas, tap/drag hit-testing, canvas animation, measured text fitting, or Semantics over custom-drawn pixels.
What it loads into context
Frontmatter
211 tokensAlways available to the agent
SKILL.md
5,110 tokensWhen the skill is activated
Reference documents
4,437 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- View / Painter / Scene
- The shared transform
- Hit-testing by geometry class
- Zero-allocation paint()
- Gesture → typed command
- Semantics over a canvas
- Measured text fitting
- Shapes & hairlines
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/analyze.shscripts/check_painter_hygiene.sh
Files
SKILL.mdcore21,038 bytesSKILL.mdcore21,038 bytesexamples/gesture_translator.dartasset4,468 bytesexamples/scene_painter.dartasset8,021 bytesexamples/text_fitter.dartasset4,486 bytesreferences/gestures-and-semantics.mddoc5,619 bytesreferences/painter-and-scene.mddoc7,227 bytesreferences/text-and-shapes.mddoc5,443 bytesscripts/analyze.shruns688 bytesscripts/check_painter_hygiene.shruns4,156 bytes
Read SKILL.md
# Custom Canvas & Gestures
Hand-painted surfaces (`CustomPainter`/`Canvas`) own every pixel, so they look byte-identical across platforms — but only if the painter stays dumb, the coordinate math is shared, and gestures translate rather than decide. This skill is the contract for that layer: how it splits, how pixels and pointers agree, and how a screen reader hears a canvas.
Read the reference for the task at hand:
- `references/painter-and-scene.md` — the View/Painter/Scene split, the shared transform, hit-testing by geometry class, zero-allocation `paint()`, the two-path repaint pitfall.
- `references/gestures-and-semantics.md` — gesture-as-translator, arena arbitration, clamp-not-collision drags, custom-canvas Semantics, action/gesture parity.
- `references/text-and-shapes.md` — measured `TextPainter` fitting, optical centring, `RoundedSuperellipseBorder`, physical-pixel hairlines, concentric radii, painter-over-image-asset.
Run `scripts/check_painter_hygiene.sh` and `scripts/analyze.sh` before a PR.
## Non-negotiable rules
1. **A canvas surface is three collaborators — a View, a Painter, and an immutable Scene — never one god-widget.** The View watches the ViewModel, builds an immutable `Scene` value type holding *everything the painter needs and nothing more*, and hands it to `CustomPaint`. The `Painter extends CustomPainter` is dumb: no `Notifier`, no `BuildContext`, no `DateTime`, no domain rules — it draws the Scene and never decides state. A dumb painter is testable and re-skinnable.View the complete source on GitHubdart3-idioms-and-coding-standards
When your agent uses it
Enforces which Dart 3 construct each declaration earns — sealed class + exhaustive switch with no `default:`/`case _:`, the three class modifiers (`sealed`/`final`/`abstract interface class`) and skip the rest, records as intra-layer tuples only, immutable value types (`final` fields, `const` ctor, value equality) hand-rolled when trivial and `freezed` when boilerplate dominates, explicit stable identity, total non-throwing domain functions, make-illegal-states-unrepresentable, and firm method/build/file/nesting complexity limits (the single-source-of-truth table other skills cite) — while banning `late`/`!`/`dynamic` honesty dodges. Use when authoring or reviewing any Dart type or declaration: class vs enum vs record vs typedef, hand-rolled vs `freezed`, adding a `switch`/`if-case`, writing `copyWith` or `==`/`hashCode`, deciding identity, keeping a domain function total, or hitting a length/nesting limit.
What it loads into context
Frontmatter
232 tokensAlways available to the agent
SKILL.md
3,780 tokensWhen the skill is activated
Reference documents
3,272 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- Sealed classes: the load-bearing idiom
- Class modifiers: reach for three
- Records: where they win, where they cost
- Enum or sealed
- Switch expressions and if-case
- Immutable value types and identity
- Total domain functions
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/check-dart3-idioms.sh
Files
SKILL.mdcore15,935 bytesSKILL.mdcore15,935 bytesexamples/immutable_value.dartasset1,723 bytesexamples/sealed_outcome.dartasset2,050 bytesexamples/total_domain_function.dartasset1,752 bytesreferences/complexity-and-honesty.mddoc5,066 bytesreferences/construct-verdict-table.mddoc4,323 bytesreferences/immutability-and-equality.mddoc4,655 bytesscripts/check-dart3-idioms.shruns2,542 bytes
Read SKILL.md
# Dart 3 idioms and coding standards
Modern Dart 3.x, value-type-first, total functions for domain logic. A language feature earns its place when it converts a runtime silence into a **compile error**; everything else is decoration. This skill governs how each declaration is *typed, named, kept immutable, and kept total* — the error-handling architecture that rides on top of these mechanics lives in `error-handling-typed-results`.
Read the reference for the task at hand:
- `references/construct-verdict-table.md` — the feature-by-feature verdict table (sealed / enum / record / class modifiers / `extension type` / codegen packages), with the rationale for each Use / Skip.
- `references/immutability-and-equality.md` — immutable value types, `copyWith`, when to hand-write `==`/`hashCode`, and stable-identity vs value-equality.
- `references/complexity-and-honesty.md` — the length/nesting limits with their evidence, and the `late`/`!`/`dynamic` honesty-dodge bans in full.
Run `scripts/check-dart3-idioms.sh` before a PR.
## Non-negotiable rules
View the complete source on GitHubdartdoc-conventions
When your agent uses it
Enforces Effective-Dart documentation on the public surface — a `///` doc on every public class/method/getter/field/typedef, a one-sentence standalone summary that says WHY plus units/ranges/nullability/throws/side-effects (never a restatement of the name), verb-phrase method docs, "Whether…" boolean getters, `[bracket]` cross-links, one `library;` doc per exported barrel, in-body `//` that explains why not what, and the enforced invariant restated at its enforcement point — backed by `public_member_api_docs` and `dangling_library_doc_comments` as analyzer errors. Use when adding or reviewing a public API, a Notifier/provider, a Service interface, a sealed Failure, a value type, or preparing a package's dartdoc.
What it loads into context
Frontmatter
173 tokensAlways available to the agent
SKILL.md
2,530 tokensWhen the skill is activated
Reference documents
0 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- Documenting a value type
- Documenting behavior — throws, async, side effects
- Library docs and the exported barrel
- Restating the invariant at the enforcement point
- Anti-patterns
- Definition of done
- Related skills
- References
Files
SKILL.mdcore10,684 bytesSKILL.mdcore10,684 bytes
Read SKILL.md
# Dartdoc Conventions — the public surface is a contract
Public code is read far more than it is written. A symbol with no leading `_` is a **contract** callers depend on, so it carries a `///` doc a reader understands without opening the body. Doc comments use `///` and follow *Effective Dart: Documentation*. Applies whenever you add or change a public declaration, or write an in-body `//` comment.
## Non-negotiable rules
1. **Every public declaration gets a `///` doc** — public classes, constructors, methods, getters, top-level functions, typedefs, and fields. `public_member_api_docs` is an **error** with no "obvious member" exemption: it flags *every* undocumented public member, so a missing doc fails the build. Making a symbol public "just in case" is a review reject — make it `_`-private instead so it needs no doc and no contract.
2. **`///`, never `/** */`.** Dartdoc only recognizes `///`. A JavaDoc block is silently ignored and the symbol reads as undocumented. `slash_for_doc_comments` flags it.
3. **First line is one standalone sentence ending in a period, in its own paragraph.** Tools show only this sentence in API lists, so it must stand alone; a blank `///` line separates it from the body.
4. **Method/function docs start with a verb phrase** (third person): "Returns…", "Schedules…", "Loads…", "Marks…". A boolean getter or `bool`-returning method starts with "Whether…".
5. **Never restate the name.** `/// The name.` on `String name`, `/// Returns the total.` on `total()` — banned. If a public member has nothing to add beyond its name, that is the signal to make it `_`-private (a private member needs no doc, so the tension disappears). A member that must stay public still needs a real `///` — never leave it public-and-undocumented; add meaning: **units, ranges, nullability, throws, side effects**, and the invariant the symbol enforces.
6. **Cross-link identifiers in `[brackets]`** so dartdoc resolves them: `/// Throws [StateError] if [id] is unknown; see [copyWith].` `comment_references` warns on a broken link.
7. **In-body `//` explains *why*, never *what*.** The code already says what. Narrating comments (`// loop over items`) rot out of sync and become misinformation. Comment the reason, the gotcha, or the invariant.
8. **Restate an enforced invariant at its enforcement point.** Where one line upholds a guarantee — an ordering, a clamp, a persist-before-publish, a canonical-unit conversion — a terse `//` states it so a diff that weakens it gets an unmissable flag. Same for a magic constant: cite where the number comes from.View the complete source on GitHubdata-export-and-restore
When your agent uses it
Enforces user-facing data portability in an offline-first app — backup/restore (exact, machine round-trippable) kept strictly separate from export/report (human, lossy, never a restore source); a versioned envelope carrying formatVersion, schemaVersion, appVersion, exportedAtUtc and a payload checksum so a restore refuses a file from a newer app instead of corrupting the database; restore as an all-or-nothing import into a staging database swapped in only after validation; canonical values in machine formats (integer minor units, SI integers, ISO-8601 UTC, stable ids) and never localized numerals; RFC 4180 CSV quoting plus the =/+/-/@ formula-injection escape; streaming writes published by atomic rename; the share sheet behind an injected Gateway; and an export→import→export round-trip test on a hostile fixture. Use when adding or changing export, backup, import, restore, share, or CSV/JSON/PDF output, writing an import validator or merge-vs-replace policy, or handling a picked file.
What it loads into context
Frontmatter
243 tokensAlways available to the agent
SKILL.md
3,355 tokensWhen the skill is activated
Reference documents
2,024 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The envelope
- Restore: validate, stage, swap
- Choosing a format
- Tests that must exist
- Anti-patterns
- Definition of done
- Related skills
- References
Files
SKILL.mdcore14,254 bytesexamples/backup_envelope.dartasset8,425 bytesexamples/csv_writer.dartasset3,336 bytesreferences/formats-and-encoding.mddoc4,169 bytesreferences/restore-and-merge-policy.mddoc4,446 bytes
Read SKILL.md
# Data export and restore
In an app with no server, the export file is the only copy of a user's data that can
outlive the phone, and restore is the only recovery path they can invoke themselves.
Both are dangerous in opposite directions: a lossy export silently becomes someone's
backup, and a half-applied restore destroys the very database it was meant to protect.
This skill governs the *portable* artifacts; the on-device `VACUUM INTO` snapshot and
WAL rules belong to `persistence-drift`.
Depth lives in `references/formats-and-encoding.md` (CSV/JSON/PDF mechanics) and
`references/restore-and-merge-policy.md` (validation ladder, merge strategies).
## Non-negotiable rules
View the complete source on GitHubdependency-hygiene
When your agent uses it
Enforces pubspec/lock discipline — caret ranges in pubspec.yaml with a committed pubspec.lock as the only pin, a separately-recorded SDK version string, a version-pinned very_good_analysis include (whose missing file fails default analyze, or silently drops the ruleset where warnings are non-fatal), transitive-tree auditing before adding a package, a dependency gate that refuses network/telemetry/crash/ads/heavy-transitive deps by policy, and vendoring any bus-factor-1 native plugin behind an interface into third_party/. Use when running dart pub add/get/upgrade/outdated/deps, editing pubspec.yaml or pubspec.lock, bumping the Flutter/Dart SDK, choosing or rejecting a new dependency, removing a package, or auditing what a dependency drags in.
What it loads into context
Frontmatter
169 tokensAlways available to the agent
SKILL.md
2,849 tokensWhen the skill is activated
Reference documents
3,013 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- Ranges in pubspec, pins in the lock
- The gate every new dependency must pass
- Auditing the transitive tree
- Upgrading
- Vendoring a bus-factor-1 plugin
- Removing a dependency
- When multi-package (workspace)
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/audit-deps.shscripts/audit_deps.py
Files
SKILL.mdcore12,173 bytesSKILL.mdcore12,173 bytesSKILL.mdcore12,173 bytesexamples/vendored_plugin_behind_interface.dartasset3,292 bytesreferences/dependency-gate-and-audit.mddoc5,700 bytesreferences/sdk-pin-and-lint-include.mddoc3,864 bytesreferences/vendoring-behind-an-interface.mddoc3,769 bytesscripts/audit-deps.shruns3,961 bytesscripts/audit_deps.pyruns5,206 bytes
Read SKILL.md
# Dependency hygiene
Every dependency is a permanent liability someone else may have to service. Optimise for *resolves and builds years from now*, not for *latest*. This skill governs pubspec/lock mechanics, the gate a new package must pass, and the escape hatch when a critical package rots.
Read the reference for the task at hand:
- `references/dependency-gate-and-audit.md` — the refuse/accept gate, transitive auditing, licence recording, upgrade discipline.
- `references/sdk-pin-and-lint-include.md` — recording the SDK version and the silent-lint-disable trap on any SDK bump.
- `references/vendoring-behind-an-interface.md` — vendoring a bus-factor-1 native plugin into `third_party/` without touching `lib/`.
Run `scripts/audit-deps.sh` before a PR that changes `pubspec.yaml`.
## Non-negotiable rules
1. **Caret ranges in `pubspec.yaml`, exact pins only in `pubspec.lock`.** `drift: ^2.31.0`, never `drift: 2.31.0`. The lock pins; ranges only keep resolution solvable. Exact pins in a pubspec manufacture unsolvable conflicts on the next SDK bump and buy nothing the lock is not already delivering.View the complete source on GitHubdesign-review-workflow
When your agent uses it
Enforces one structured end-of-build design/QA pass — never per-task — on the release build: a screenshot sweep matrix (every screen × light/dark × LTR+RTL × largest text scale × reduce-motion) plus an on-device pass on real cheap target hardware, findings graded BLOCKER/FIX/NOTE with every accessibility-floor violation a mandatory BLOCKER, exactly one scoped fix round, and a dated sign-off artifact that gates release. Use when a feature's build tasks are done and it needs its design review, tagging or preparing a release, verifying a build on a physical device, running a pre-ship visual/QA sweep, or asking what design and QA cannot be tested automatically.
What it loads into context
Frontmatter
150 tokensAlways available to the agent
SKILL.md
3,102 tokensWhen the skill is activated
Reference documents
0 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The screenshot sweep matrix
- Grading rubric
- The on-device pass
- Turn design rules into a greppable gate (methodology, not a fixed list)
- Anti-patterns
- Definition of done
- Related skills
- References
Files
SKILL.mdcore13,677 bytesSKILL.mdcore13,677 bytesSKILL.mdcore13,677 bytes
Read SKILL.md
# Design review workflow
One structured design/QA pass per app or feature, at the very end, on the release build — never a per-task visual critique. During the build, development speed wins and no task is blocked on aesthetics; when the last build task is done and CI is green, exactly one pass runs: a screenshot sweep + an on-device pass → graded findings → one scoped fix round → a dated sign-off that gates release.
## Non-negotiable rules
1. **Once per app/feature, at the end — never per-task.** Blocking a build task on a visual critique, or demanding review screenshots inside a task's acceptance criteria, is the failure this skill prevents. If something looks broken mid-build, file a note and keep moving; review it in the pass.
2. **Trigger = last build task done AND all CI gates + tests green.** Green gates are a *precondition*, not part of the review — this pass judges only what the eye and ear catch. Never re-litigate what CI already proves (determinism, lint, l10n key parity, layer gates).
3. **Review the release build, not a debug build.** A debug banner, debug-mode jank, or an un-overridden status bar wastes the sweep. Standardize the status bar (fixed clock, full battery) so shots differ only where the UI differs.
4. **Sweep the full matrix — every screen the app can show.** Each screen × {light, dark} × {LTR, RTL} × largest text scale × reduce-motion. Dynamic screens get shot in each meaningful state (empty, mid, full/success). One file per matrix cell, machine-sortable names, all artifacts under one review folder inside the write-set.
5. **Every accessibility-floor violation is a BLOCKER — however beautiful the screen.** Contrast, tap-target size, text-scale reflow, color-never-alone, RTL correctness, and reduce-motion safety are the shared floor. A floor miss always grades BLOCKER; aesthetics never buy it back.
6. **Grade every finding BLOCKER / FIX / NOTE.** BLOCKER = floor violation or a shipping-stopper (must fix now); FIX = clearly below bar, fixable this round; NOTE = recorded, deferred to the backlog. Consolidate into one deduped table before fixing.
7. **Exactly one fix round.** Fix BLOCKERs + FIXes as a single scoped unit, re-run gates/tests, re-shoot *only* affected cells (overwrite — the folder stays one truth), verify each finding against its new shot. Open no new critique during verification — new observations become NOTEs. A surviving BLOCKER means no sign-off and an escalation, not a second round.
8. **Do destructive on-device steps last.** Force-stop, previous-release migration, wipe/reinstall, and a deliberate crash each destroy the state before them. Ordering them last means the audio/reader/scale passes aren't redone.View the complete source on GitHubdesign-system-structure
When your agent uses it
Structures a Flutter design system as tokens→theme→modifiers→shapes with two-tier tokens (primitives named by measured value, semantic slots named by role) exposed through a ThemeExtension read via an asserting of(context); hand-authors both light and dark ColorScheme instead of ColorScheme.fromSeed, keeps every raw color/hex/Colors./Curves./Duration/BorderRadius/fontSize inside lib/theme/ behind a no-raw-values gate, collapses animation to zero under reduced motion, restores the persisted theme before first paint, bundles fonts (never google_fonts/dynamic_color), and derives each stateful meaning's supporting color last so color is never its sole signal. Use when creating or editing ThemeData/ThemeExtension/ColorScheme, adding or renaming a design token, wiring theme injection or theme-mode persistence, reaching for fromSeed/dynamic_color/google_fonts/FontVariation, structuring a theme/ or DesignSystem/ folder, or reviewing any widget that renders a color, radius, duration, or font.
What it loads into context
Frontmatter
215 tokensAlways available to the agent
SKILL.md
4,462 tokensWhen the skill is activated
Reference documents
5,302 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The token layering
- Hand-author `ColorScheme`, keep the M3 role names
- Reduced motion: read the flag, collapse to zero
- Restore the theme before first paint
- Redundant encoding: derive color last
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/check_font_bundling.shscripts/check_raw_values.sh
Files
SKILL.mdcore18,774 bytesSKILL.mdcore18,774 bytesSKILL.mdcore18,774 bytesexamples/app_theme.dartasset8,455 bytesexamples/reduced_motion.dartasset4,065 bytesexamples/status_encoding.dartasset2,791 bytesreferences/contrast-and-redundant-encoding.mddoc4,642 bytesreferences/motion-and-reduced-motion.mddoc4,734 bytesreferences/token-tiers-and-themeextension.mddoc6,676 bytesreferences/typography-and-fonts.mddoc6,615 bytesscripts/check_font_bundling.shruns1,083 bytesscripts/check_raw_values.shruns1,879 bytes
Read SKILL.md
# design-system-structure
A design system is code that is *incapable of holding a stray opinion*: every aesthetic value lives in one directory, and every widget reads it back through a named slot. This skill owns how tokens, themes, components, and shapes are **structured and consumed** — not which colors or radii to pick (that belongs to your design source of truth). Getting the structure right makes a reskin a `diff lib/theme/` and turns a stray `Color(0xFF…)` in feature code into a build failure instead of a style nit.
Read the reference for the task at hand:
- `references/token-tiers-and-themeextension.md` — two-tier token naming, ThemeExtension mechanics, the asserting `of()`, hand-authored `ColorScheme` vs `fromSeed`, honest `lerp`.
- `references/motion-and-reduced-motion.md` — the three animations Material mounts by default, why `NoSplash` is not enough, reduced-motion-means-zero, `pumpAndSettle` bans in tests.
- `references/typography-and-fonts.md` — bundling fonts, `LicenseRegistry`, `FontWeight` drives `wght`, silent `FontVariation` no-ops, subsetting without instancing, per-script fallback cascades.
- `references/contrast-and-redundant-encoding.md` — AA as a unit test, ≥3 grayscale-legible signals per meaning, reading a11y flags from `MediaQuery`.
Run `scripts/check_raw_values.sh` and `scripts/check_font_bundling.sh` before a PR.
## Non-negotiable rules
View the complete source on GitHuberror-handling-typed-results
When your agent uses it
Enforces a typed-error spine — a hand-rolled sealed Result<T,F> plus one per-boundary sealed Failure carrying a stable code and typed params (never a localized string), returned instead of thrown; recoverable failures are values, only bugs throw. Convert-at-boundary catches narrowly with an on-clause and logs the original error+stack BEFORE returning a typed Failure; call sites switch exhaustively with no default:; the taxonomy of what the global error net (FlutterError.onError + PlatformDispatcher.onError, installed by app-startup-and-bootstrap) routes into, plus Isolate.run re-wrapping; mechanism selection (Error vs assert vs Exception vs sealed outcome) and @useResult; and a never-lose-data layer (one-transaction-per-mutation, debounced autosave drafts, optimistic soft-delete/Undo). Use when writing result.dart/failures.dart, a try/catch or sealed-switch default:, wiring bootstrap handlers, a repository/service/DAO boundary, or transactions, drafts, or soft-delete/Undo.
What it loads into context
Frontmatter
220 tokensAlways available to the agent
SKILL.md
3,680 tokensWhen the skill is activated
Reference documents
6,140 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The Result + Failure spine
- Convert at the boundary
- Exhaustive switch at the call site
- The global net routes only thrown bugs
- Isolate error re-wrapping
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/check-softdelete-parity.shscripts/check-swallowed-catch.sh
Files
SKILL.mdcore15,467 bytesexamples/soft_delete_undo.dartasset2,782 bytesexamples/transactional_write.dartasset3,252 bytesexamples/typed_result_boundary.dartasset4,329 bytesreferences/mechanism-selection.mddoc6,338 bytesreferences/never-lose-data.mddoc8,793 bytesreferences/result-failure-spine.mddoc10,541 bytesscripts/check-softdelete-parity.shruns2,189 bytesscripts/check-swallowed-catch.shruns3,496 bytes
Read SKILL.md
# Error Handling — Typed Results
Recoverable failures are typed **values** that flow through the layers and are switched on exhaustively; only genuine bugs and unrecoverable states throw, and those are caught once by a global net. Wrapped around both, never-lose-data — transactions, autosave drafts, soft-delete/Undo — is a first-class subsystem, not plumbing. Two tiers, no middle ground.
Read the reference for the task at hand:
- `references/result-failure-spine.md` — the `Result`/`Failure` source, the per-boundary taxonomy, convert-at-boundary, the global net, isolate re-wrapping, and local logging.
- `references/mechanism-selection.md` — throw vs `assert` vs `Exception` vs sealed outcome, `@useResult`, and the runZonedGuarded decision.
- `references/never-lose-data.md` — one transaction per mutation, debounced autosave drafts, optimistic soft-delete / Trash / Undo behind one filter.
Run `scripts/check-swallowed-catch.sh` and `scripts/check-softdelete-parity.sh` before a PR.
## Non-negotiable rules
1. **Model recoverable failures as values, not exceptions.** Anything that fails for a runtime reason the caller must handle — DB error, file/backup I/O, notification scheduling, an expected not-found, invalid input — returns `Result<T, F extends Failure>` (sealed `Ok`/`Err`). Throwing across a layer for an *expected* failure is a review reject.View the complete source on GitHubflutter-architecture
When your agent uses it
Enforces a right-sized feature-first layered MVVM Flutter architecture — features are folders and cross-cutting foundations become packages only when a compile wall earns it, a strict downward-only dependency DAG, dumb Views over one Notifier/AsyncNotifier ViewModel per feature, repositories as the single source of truth and single write path returning immutable domain values, abstractions only where something genuinely can't run in a test, and Riverpod 3.x as the one context-free DI+state mechanism (no get_it/injectable/package:provider container). Use when creating a Flutter feature or file, deciding folder-vs-package or where a class belongs, naming a Screen/Notifier/Repository/Service, wiring providers or a composition-root/bootstrap.dart, adding a use-case/domain layer, resisting over-engineering on a small app, or reviewing whether a change respects the layer boundaries.
What it loads into context
Frontmatter
180 tokensAlways available to the agent
SKILL.md
4,255 tokensWhen the skill is activated
Reference documents
5,118 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The layered shape (single package, the default)
- The feature slice (Riverpod-first "how")
- The composition root (single write of the object graph)
- Right-sizing: folder vs package, and what to abstract
- Anti-patterns
- Definition of done
- Related skills
- References
- Provider / ChangeNotifier appendix
Scripts executed separately
scripts/check_architecture.sh
Files
SKILL.mdcore18,568 bytesSKILL.mdcore18,568 bytesSKILL.mdcore18,568 bytesSKILL.mdcore18,568 bytesSKILL.mdcore18,568 bytesSKILL.mdcore18,568 bytesSKILL.mdcore18,568 bytesexamples/composition_root.dartasset4,000 bytesexamples/feature_slice.dartasset6,340 bytesreferences/module-and-layers.mddoc7,178 bytesreferences/right-sizing.mddoc5,674 bytesreferences/state-di-riverpod.mddoc9,006 bytesscripts/check_architecture.shruns3,453 bytes
Read SKILL.md
# Flutter Architecture
Structure every Flutter app as a **layered, feature-first MVVM system, sized to the app**. You must
always answer "where does this code belong?" in one second. Based on Flutter's official *Guide to app
architecture*, with Riverpod 3.x as the one mechanism for both state and dependency injection.
Two failure modes kill an architecture: under-structure (a widget touching a database) and
over-structure (a `*UseCase` wrapping one repository call, an interface over code that already runs in
a test). This skill fights both. **Start small; add a layer only when it carries a load you can name.**
Read the reference for the task at hand:
- `references/module-and-layers.md` — the layer model, folder-vs-package continuum, the DAG, barrels, feature-folder anatomy, and the "when multi-package (workspace)" note.
- `references/right-sizing.md` — the reject-over-engineering table, "abstract only what you can't test", and how architecture scales with app size.
- `references/state-di-riverpod.md` — provider graph, keepAlive vs autoDispose, placeholder-override composition root, isolate-safe factories, `ProviderContainer` tests.View the complete source on GitHubflutter-conventions-index
When your agent uses it
The repo front-door for a Flutter/Dart app — the cross-cutting house rules (feature-first layered MVVM, immutable state with a single write path, Riverpod 3.x for state + DI, typed Result/Failure errors, dumb widgets, injected side effects, complexity limits) plus a routing table that sends each task to its deep-dive skill and a recommended feature build order. Use at the start of any Flutter/Dart work, before writing or reviewing a feature, when deciding which layer or package code belongs in, when unsure which skill governs a task (architecture, state, widgets, persistence, testing, i18n, design), or when onboarding to the conventions.
What it loads into context
Frontmatter
147 tokensAlways available to the agent
SKILL.md
4,182 tokensWhen the skill is activated
Reference documents
0 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- Route to the right skill
- Recommended order when building a feature
- Baseline project setup
- The shape every feature repeats
- Anti-patterns
- Definition of done
- Related skills
- References
Files
SKILL.mdcore17,402 bytesSKILL.mdcore17,402 bytesSKILL.mdcore17,402 bytesSKILL.mdcore17,402 bytes
Read SKILL.md
# Flutter Conventions — Index
The front door for this Flutter/Dart app. It states the cross-cutting **house rules** every task obeys, then **routes each concern to a focused skill**. For any non-trivial task: apply the rules here, then open the specialized skill for depth. This is the only skill that names every other skill in the library.
Assumes a **single-package Flutter app** by default. Monorepo / pub-workspace guidance is fenced inside the skills that own it (`project-structure-and-packages`, `codegen-and-toolchain`) — never required for a small app.
## Non-negotiable rules
1. **Feature-first, layered, downward-only.** Group by feature (a folder), then by layer: View → ViewModel → Repository → Service/data. Lower layers never import upward; the dependency graph is a strict DAG. WHY: an acyclic downward graph is the only structural guard against a big ball of mud. *(`flutter-architecture`, `project-structure-and-packages`)*
2. **Widgets are dumb.** No business logic, data access, math, or formatting in a widget — it reads state and renders. WHY: logic in `build()` is untestable and rebuilds unpredictably. *(`widget-composition`)*
3. **One ViewModel per screen, over immutable state.** A single `Notifier`/`AsyncNotifier` owns private mutable state and exposes it as an immutable value with value equality; a transition assigns a new state, never mutates in place. WHY: immutable value + single owner makes every change diffable and testable. *(`state-management-riverpod`)*
4. **Riverpod 3.x is state + DI.** Modern `Notifier`/`AsyncNotifier`/`Future`/`Stream` providers only; providers are the DI container. No `get_it`, no `package:provider`, no legacy `StateProvider`/`StateNotifierProvider`/`ChangeNotifierProvider`. WHY: one composition model, no second DI framework to reconcile. *(`state-management-riverpod`, `app-startup-and-bootstrap`)*
5. **Single write path.** A widget or ViewModel never mutates persisted state directly; every mutation is a repository method that persists first, then republishes via a stream. WHY: one durable, observable route means state is never half-written. *(`state-management-riverpod`, `persistence-drift`)*
6. **Derive, don't store; depend on abstractions.** Compute derived values on read instead of caching a second copy; program against interfaces you inject, not concretes. WHY: a duplicated source of truth drifts out of sync; injected seams keep code testable. *(`flutter-architecture`, `service-boundary-and-native`)*View the complete source on GitHubflutter-performance
When your agent uses it
Enforces Flutter runtime performance — const subtrees, minimal rebuild scope via ref.watch(select), lazy ListView/GridView builders and slivers, sized image decode (cacheWidth/ResizeImage), heavy work off the UI isolate via compute/Isolate, surgical RepaintBoundary, dispose everything, and measurement in profile mode on a floor device. Use when optimizing UI, diagnosing jank or dropped frames, tuning long lists or images, reviewing rebuild/repaint scope, or when the task mentions const, select, ListView.builder, cacheWidth, compute, RepaintBoundary, AnimatedBuilder, DevTools, raster thread, or 60/120fps.
What it loads into context
Frontmatter
137 tokensAlways available to the agent
SKILL.md
2,345 tokensWhen the skill is activated
Reference documents
0 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- Narrow the rebuild scope
- Keep expensive children out of the animation loop
- Lazy lists and sized images
- Heavy work off the UI isolate
- Custom painting
- Profiling workflow
- Anti-patterns
- Definition of done
- Related skills
- References
Files
SKILL.mdcore9,899 bytesSKILL.mdcore9,899 bytesSKILL.mdcore9,899 bytes
Read SKILL.md
# Flutter Performance
Hold a steady 60 fps (<=16 ms/frame; <=8 ms on 120 Hz) on a floor device (low-end Android / older iPhone). Performance is a property you **measure in profile mode**, not one you assert. It comes from rebuilding less, painting cheaply, and keeping both the UI thread and the raster thread free.
## Non-negotiable rules
1. **`const` everything legal.** A `const` subtree is skipped on rebuild — the framework short-circuits it by identity. Keep `prefer_const_constructors` on as an error; a non-const literal that could be const is a lint failure, not a preference.
2. **Shrink the rebuild scope to the smallest changing widget.** Never `ref.watch(provider)` for a whole state object when one field changed — watch `provider.select((s) => s.field)`. A HUD counter tick must never rebuild a heavy sibling. Rebuild scope is the single biggest lever on build-thread cost.
3. **Lazy everything long.** `ListView.builder` / `GridView.builder` / slivers for variable or unbounded content. `ListView(children: items.map(...).toList())` builds every off-screen row up front — refuse it for anything not tiny and fixed.
4. **No expensive work in `build()`.** No `jsonDecode`, sort, regex, `DateTime` math, file/network, or large allocation — `build()` may run every frame. Compute in the Notifier/ViewModel once and cache the result in immutable state.
5. **Heavy CPU off the UI isolate.** Parse large payloads, process images, crunch numbers in `compute()` or a spawned `Isolate`. Blocking the UI thread is guaranteed jank; the raster thread cannot save you.
6. **Size image decode to the display slot.** `cacheWidth`/`cacheHeight` or `ResizeImage`, correct asset resolutions, `precacheImage` for above-the-fold art. Decoding a 4000 px source into a 100 px box spikes memory and OOMs cheap phones.
7. **Prefer the cheapest widget that does the job.** `ColoredBox`/`DecoratedBox` over `Container`, `SizedBox` for spacing, `FadeTransition`/`AnimatedOpacity` over the `Opacity` widget in hot paths. Avoid `ClipPath`/`saveLayer` inside scrolling lists — they force an offscreen buffer on the raster thread.
8. **`RepaintBoundary` around costly, independently-repainting subtrees** (an animation, a chart, a live indicator) so its repaint does not re-raster its neighbours. Do not sprinkle boundaries everywhere — each is a compositor layer that costs memory.View the complete source on GitHubforms-and-input
When your agent uses it
Enforces Form + GlobalKey<FormState> with TextFormField whose sync validator returns a localized String? (never a hardcoded literal), AutovalidateMode.onUserInteraction, async availability checks moved OUT of the sync validator into a debounced Riverpod Notifier that surfaces errors through state, FocusNode/TextInputAction/onFieldSubmitted traversal, keyboardType/textCapitalization/autofillHints/TextInputFormatter, mandatory TextEditingController/FocusNode disposal, submit-enabled derived from validity (not stored), and scoped rebuilds so a keystroke never rebuilds the whole form. Use when building a Form, TextFormField, or FormField; wiring sync or async validation; managing FocusNode, focus traversal, autofocus, TextInputAction, onFieldSubmitted, or onEditingComplete; setting keyboardType, autofillHints, textCapitalization, or InputFormatter; disposing TextEditingController/FocusNode; enabling/disabling a submit button; or handling keyboard-avoidance on submit.
What it loads into context
Frontmatter
207 tokensAlways available to the agent
SKILL.md
2,795 tokensWhen the skill is activated
Reference documents
2,578 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- Form skeleton
- Sync validation
- Async validation (out of the validator)
- Focus and keyboard flow
- Submit button derived from validity
- Keyboard avoidance
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/check_forms.sh
Files
SKILL.mdcore11,863 bytesexamples/async_field_notifier.dartasset4,768 bytesexamples/task_form.dartasset4,920 bytesreferences/focus-and-keyboard.mddoc5,320 bytesreferences/validation-sync-and-async.mddoc5,658 bytesscripts/check_forms.shruns2,979 bytes
Read SKILL.md
# Forms and input
Text input is where most disposal leaks, un-localized strings, and jank enter a Flutter app. A form is a small state machine: fields hold text, a `FormState` validates them, and a ViewModel owns anything that touches the network or the clock. Keep those three responsibilities separate.
Read the reference for the task at hand:
- `references/validation-sync-and-async.md` — sync `validator` returning localized `String?`, `AutovalidateMode` choice, and the debounced-async-in-a-Notifier pattern (why async must NOT live in the sync validator).
- `references/focus-and-keyboard.md` — `FocusNode` lifecycle, traversal order, `autofocus`, `FocusTraversalGroup`, `TextInputAction`, `onFieldSubmitted`/`onEditingComplete`, `keyboardType`, `autofillHints`, `TextInputFormatter`, keyboard-avoidance.
Run `scripts/check_forms.sh` before a PR.
## Non-negotiable rules
1. **Every `TextEditingController` and `FocusNode` created in a `State` is disposed in `dispose()`.** They hold native resources and listeners; a leak survives the widget and fires callbacks against a dead tree. If the value must outlive the widget, hold it in a Notifier instead — see `state-management-riverpod`.View the complete source on GitHubi18n-rtl-l10n
When your agent uses it
Enforces the gen-l10n/ARB localization contract: every string through AppLocalizations from a template app_en.arb, key + placeholder parity, nullable-getter:false so a missing key is a compile error, ICU plural/select over concatenation, Directional-only geometry (EdgeInsetsDirectional, AlignmentDirectional, TextAlign.start, Icons.adaptive), FSI/PDI isolation for mixed-script runs, per-locale NumberFormat with a pinned numbering system, canonical UTC-epoch + ASCII storage projected only at render, normalize-to-ASCII before any parse, and three vendored LocalizationsDelegates ahead of the Global* ones for a locale flutter_localizations lacks. Use when adding or translating an ARB key, building an RTL screen, formatting or parsing dates/numbers/numerals, wiring l10n.yaml, AppLocalizations, or MaterialApp localizationsDelegates, supporting a locale Flutter lacks (ckb), fixing a locale that crashes on Tooltip or renders LTR, checking bundled-font glyph coverage, isolating technical IDs, or touching app_*.arb.
What it loads into context
Frontmatter
252 tokensAlways available to the agent
SKILL.md
4,781 tokensWhen the skill is activated
Reference documents
7,711 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The ARB workflow (add or translate a key)
- Directional geometry — mirror by construction
- Numerals — format at the edge, one formatter everywhere
- Bidi isolation — mixed-script runs
- Calendars & dates
- CustomPainter with a locale-invariant coordinate space
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/check_arb_parity.shscripts/check_i18n_bans.sh
Files
SKILL.mdcore19,182 bytesexamples/directional_widget.dartasset3,925 bytesexamples/numeral_normalizer.dartasset3,847 bytesexamples/unsupported_locale_delegates.dartasset6,858 bytesreferences/arb-and-icu.mddoc6,513 bytesreferences/numerals-and-calendars.mddoc7,214 bytesreferences/rtl-and-bidi.mddoc6,603 bytesreferences/unsupported-locales.mddoc9,898 bytesscripts/check_arb_parity.shruns2,987 bytesscripts/check_i18n_bans.shruns2,489 bytes
Read SKILL.md
# i18n, RTL & Localization
One contract: **store canonical, localize at render.** Every conversion and formatting lives in
one `l10n` layer; feature widgets receive value objects and already-localized strings, never raw
formatting logic. RTL is a layout discipline, not a translation task — author with logical
geometry so it mirrors by construction. Applies to any app that ships more than one locale or any
RTL locale (Arabic, Persian, Hebrew, Sorani Kurdish, Urdu).
Read the reference for the task at hand:
- `references/arb-and-icu.md` — the ARB add/translate workflow, `l10n.yaml`, ICU plural/select, placeholder typing.
- `references/rtl-and-bidi.md` — the directional-geometry allow/ban table, icon mirroring, bidi isolation, CustomPainter pinned LTR, RTL charts.
- `references/numerals-and-calendars.md` — digit systems, separator traps, format/parse, calendar projection.
- `references/unsupported-locales.md` — shipping a locale `flutter_localizations` has no data for: the probe, the vendored delegate trio, delegate ordering, font coverage.View the complete source on GitHublint-and-style-config
When your agent uses it
Enforces a strict analysis_options.yaml built on very_good_analysis with strict-casts/strict-raw-types, a fixed set of silence-producing bug classes promoted to error (unawaited_futures, discarded_futures, empty_catches, use_build_context_synchronously, cancel_subscriptions, close_sinks, avoid_dynamic_calls, exhaustive_cases, avoid_print), dart format as the sole whitespace authority, generated-file excludes mirrored to coverage, and line-scoped-only suppression discipline; teaches the version-pinned-include trap (a missing include silently disables all rules), the errors-only-re-ranks-vs-linter-enables mechanic, and the sealed-switch analyze-vs-compile gap. Use when editing analysis_options.yaml, adding or disabling a lint, writing an `// ignore:`/`// ignore_for_file:`, bumping the Dart SDK or very_good_analysis version, wiring riverpod_lint, or explaining why discarded_futures, use_build_context_synchronously, close_sinks, or missing_provider_scope fires.
What it loads into context
Frontmatter
213 tokensAlways available to the agent
SKILL.md
2,955 tokensWhen the skill is activated
Reference documents
2,941 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The include, and the trap that silently disables everything
- Promote the silence-bugs to error
- `errors:` re-ranks; `linter: rules:` enables
- Sealed exhaustiveness is a compile error, not a lint
- Excludes, mirrored to coverage
- The hole no lint catches
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/lint-gates.shscripts/verify-include-pin.sh
Files
SKILL.mdcore12,040 bytesexamples/analysis_options.yamlasset6,126 bytesexamples/callback_future_hole.dartasset3,203 bytesreferences/config-mechanics.mddoc7,174 bytesreferences/rule-catalog.mddoc4,689 bytesscripts/lint-gates.shruns1,654 bytesscripts/verify-include-pin.shruns1,717 bytes
Read SKILL.md
# Lint & Style Config
Style is not taste; it is toolchain-enforced. `dart format` owns whitespace, the
analyzer owns correctness, and a small set of **silence-producing bug classes**
are promoted to build-failing errors. This skill governs the
`analysis_options.yaml` itself and the mechanics that decide whether it actually
does anything. Applies whenever you edit that file, add or silence a lint, or
bump the SDK/ruleset.
Read the reference for the task at hand:
- `references/rule-catalog.md` — every promoted rule and its bug class, the
deliberate downgrades, the contested `public_member_api_docs` call, and the
complexity-limit table.View the complete source on GitHublocal-notifications-scheduler
When your agent uses it
Enforces an on-device reminder engine where the local database is the only source of truth and the OS pending-notification set is a disposable cache reconciled through one idempotent syncNotifications() entrypoint; keeps flutter_local_notifications behind a single NotificationGateway port, all scheduling math pure and Clock-injected, recurring schedules stored as wall-clock + recurrence rule (never UTC instants) and resolved to a TZDateTime in tz.local for DST correctness, inexact-alarm default with SCHEDULE_EXACT_ALARM as an opt-in, iOS ~64-cap budgeting, isolate-safe @pragma('vm:entry-point') tap handlers, and Android boot re-arm. Use when writing or editing notification_gateway.dart, fln_notification_gateway.dart, reminder_scheduler.dart, recurrence_rule.dart, syncNotifications, zonedSchedule wiring, snooze or mark-done re-anchoring, or diagnosing missed or wrong-hour notifications.
What it loads into context
Frontmatter
213 tokensAlways available to the agent
SKILL.md
3,472 tokensWhen the skill is activated
Reference documents
3,721 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- Package / folder layout
- The canonical reconcile (the backbone)
- The gateway port
- Recurrence & DST
- Background isolate & tap handling
- Localization & backup
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/check-adhoc-schedule-calls.shscripts/check-manifest-permissions.shscripts/check-scheduler-purity.shscripts/check-single-fln-import.sh
Files
SKILL.mdcore15,433 bytesSKILL.mdcore15,433 bytesSKILL.mdcore15,433 bytesSKILL.mdcore15,433 bytesSKILL.mdcore15,433 bytesSKILL.mdcore15,433 bytesexamples/fake_notification_gateway.dartasset1,646 bytesexamples/notification_gateway.dartasset2,309 bytesexamples/sync_notifications.dartasset1,896 bytesreferences/notification-gateway-port.mddoc4,661 bytesreferences/platform-boot-exact-alarms-oem.mddoc5,871 bytesreferences/scheduler-and-recurrence-rules.mddoc5,925 bytesscripts/check-adhoc-schedule-calls.shruns834 bytesscripts/check-manifest-permissions.shruns1,041 bytesscripts/check-scheduler-purity.shruns1,439 bytesscripts/check-single-fln-import.shruns1,090 bytes
Read SKILL.md
# Local Notifications Scheduler
One on-device reminder engine, owned centrally, with a narrow API. The local DB is the source of truth; the OS pending set is a disposable cache. Every scheduling change flows through one pure-then-reconcile path so the whole engine is verifiable off-device. Applies whenever you schedule, cancel, or reason about local notifications.
Read the reference for the task at hand:
- `references/notification-gateway-port.md` — the port contract, the two adapters, channels/grouping/deep-link payload rules.
- `references/scheduler-and-recurrence-rules.md` — pure `ReminderScheduler.compute` diff, recurrence/DST math, deterministic IDs, budgeting, the full test matrix.
- `references/platform-boot-exact-alarms-oem.md` — boot re-arm, exact-alarm degradation, background-isolate safety, Android manifest/Gradle, the OEM survival matrix.
Run `scripts/check-single-fln-import.sh`, `scripts/check-scheduler-purity.sh`, `scripts/check-adhoc-schedule-calls.sh`, and `scripts/check-manifest-permissions.sh` before a PR.
## Non-negotiable rules
1. **The local DB is the ONLY source of truth.** The OS pending-notification set is a disposable cache you reconcile against — never the store of record. Every reminder must be reconstructible from the DB alone after process death, reboot, Doze, or restore.View the complete source on GitHubmotion-and-haptics
When your agent uses it
Enforces designed interaction feedback instead of the framework default — every committing interaction acknowledged in the same frame, motion that decorates state but never IS the state (the end state is identical with animations off), a named catalog of moments each declaring its trigger, duration role, haptic slot and reduced-motion fallback at design time, haptics as a HapticTheme event-to-intensity map fired exactly once on the commit frame (never per animation frame, never per coalesced input, never heavyImpact for an error) behind one central toggle, every animation interruptible so a tap resolves it to its end state, a bounded celebration that plays once and never loops or blocks input, an explicit stop condition on every repeating animation (off-route, backgrounded, reduced motion), and feedback on more than one channel so haptics and sound survive reduced motion. Use when adding or tuning an animation, a success or error state, a haptic, a celebration, or a screen transition.
What it loads into context
Frontmatter
229 tokensAlways available to the agent
SKILL.md
2,979 tokensWhen the skill is activated
Reference documents
1,039 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The moment declaration
- Firing a haptic exactly once
- Anti-patterns
- Definition of done
- Related skills
- References
Files
SKILL.mdcore13,140 bytesreferences/moment-catalog.mddoc4,599 bytes
Read SKILL.md
# Motion and haptics
What fires, when, exactly once, and how it degrades. Feedback is the layer users feel rather than
read — an app whose taps land, whose errors are felt, and whose success is acknowledged reads as
finished; the same app with default Material feedback reads as a prototype.
**Scope boundary.** Motion *tokens* — duration roles, curve slots, the no-raw-values gate, and
`resolveMotion` collapsing to `Duration.zero` under reduced motion — are owned by
`design-system-structure`. Painter/ticker mechanics are owned by `custom-canvas-and-gestures`.
*Which* surface a message uses — loading, empty, error, snackbar, banner, dialog, Undo, and
screen-reader announcements — is owned by `ui-states-and-feedback`. This skill owns the sensory
layer those decisions ride on: which moments exist, what each one commits to, how haptics are
mapped and fired, and what survives when the animation does not.
View the complete source on GitHubnaming-conventions
When your agent uses it
Enforces Effective-Dart casing (UpperCamelCase types, lowerCamelCase members/constants, lowercase_with_underscores files) plus architectural role suffixes so a name or grep reveals the layer — Screen/Notifier/Repository/Dao/Service/Gateway/Failure, file=primary-declaration, units-and-semantics in identifiers, booleans as is/has/can/should assertions, no get-prefix, no Hungarian, no SCREAMING_CAPS, grouped-and-sorted imports. Use when creating a file, naming a class/enum/mixin/extension/typedef/variable/function/getter/constant/parameter, organizing imports, choosing a role suffix, or reviewing a diff for naming and directive ordering.
What it loads into context
Frontmatter
153 tokensAlways available to the agent
SKILL.md
3,385 tokensWhen the skill is activated
Reference documents
0 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The suffix declares the layer
- Value vs. instant, and other name-carried distinctions
- Worked example
- Anti-patterns
- Definition of done
- Related skills
- References
Files
SKILL.mdcore13,560 bytes
Read SKILL.md
# Naming Conventions
Consistent, role-carrying names make code searchable and self-explaining, and the suffix on a type declares which layer it lives in — so a reviewer, a `grep`, and a banned-import gate can all read the layer off the name alone. This skill is the *how*; the normative *what* is [Effective Dart](https://dart.dev/effective-dart). Never invent a house style that contradicts the language's own.
## Non-negotiable rules
1. **Types are `UpperCamelCase`.** Classes, enums, mixins, extensions, typedefs, type parameters: `TaskScreen`, `OrderStatus`, `Predicate<T>`. Consistent shape makes types visually distinct from values.
2. **Members, variables, functions, and parameters are `lowerCamelCase`.** `dueDate`, `loadTasks()`, `itemCount`. It is the language default; deviating costs readers a double-take.
3. **Constants are `lowerCamelCase`, never `SCREAMING_CAPS`.** `const maxItemsPerPage = 50;` — not `const MAX_ITEMS = 50`. Dart dropped the C convention; the analyzer expects `constant_identifier_names`.
4. **Files, folders, libraries, and import prefixes are `lowercase_with_underscores`.** `task_detail_screen.dart`, `features/task_detail/`, `import 'package:app_core/app_core.dart';`. Cross-platform filesystems and pub demand it.
5. **File name = its primary declaration, snake_cased, one primary public type per file.** `TaskNotifier` lives in `task_notifier.dart`. No `utils.dart`/`helpers.dart`/`models.dart` grab-bags and no `utils/`/`common/`/`helpers/`/`misc/` junk-drawer folders — a reader who greps a symbol must land in the file that owns it. `core/` is the *sanctioned* pure-foundation layer (value objects, `Result`/`Failure`, the `Clock` seam, pure calculators), not a junk-drawer — see `project-structure-and-packages`, which owns the layout.
6. **Acronyms longer than two letters are cased like a word.** `Json`, `Http`, `Url`, `Api` → `JsonOrder`, `HttpClient`, `fromJson`, `imageUrl` — not `JSONOrder`, `HTTPClient`. Two-letter caps-in-English acronyms may stay caps as types (`ID`, `UI`). Mixed-case acronyms are unsearchable and inconsistent.
7. **A leading underscore means library-private — use it only when you mean private.** Never prefix a public symbol with `_` to "namespace" it; that makes it unusable from another file. Public (no `_`) is a documented contract — see `dartdoc-conventions`.
8. **No Hungarian / type-encoding in names.** Not `strName`, `iCount`, `lstItems`, `userMap`, `nameString`, `itemsList`. The type system already knows the type; write `name`, `usersById`, `items`.View the complete source on GitHubnavigation-and-routing
When your agent uses it
Enforces one app-wide GoRouter in lib/routing/ wired via MaterialApp.router, deep-linkable identity in path params never state.extra, context.go-vs-context.push discipline, redirect guards as pure functions driven by a Riverpod refreshListenable, StatefulShellRoute.indexedStack for branch-state-preserving BottomNavigationBar/NavigationRail shells, CustomTransitionPage transitions that respect reduced motion, PopScope (canPop/onPopInvokedWithResult) for unsaved-changes interception, and an errorBuilder 404 route. Use when adding routes, GoRoute, redirect, auth/onboarding gates, deep links, ShellRoute or nested navigation, bottom-nav/rail tab shells, page transitions, back-button/unsaved-changes handling, notification-payload-to-location mapping, typed routes, go_router_builder, or wiring go_router into app.dart.
What it loads into context
Frontmatter
179 tokensAlways available to the agent
SKILL.md
2,360 tokensWhen the skill is activated
Reference documents
4,003 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The single router
- Identity in the path, not in extra
- Typed route helpers (constants, not string soup)
- go vs push
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/check_routing.sh
Files
SKILL.mdcore10,057 bytesexamples/app_router.dartasset6,564 bytesexamples/auth_redirect.dartasset2,825 bytesexamples/shell_scaffold.dartasset5,107 bytesreferences/go-router-config.mddoc5,503 bytesreferences/guards-and-redirects.mddoc4,792 bytesreferences/shells-and-deep-links.mddoc6,764 bytesscripts/check_routing.shruns3,217 bytes
Read SKILL.md
# Navigation and routing
This skill owns app navigation with `go_router`. There is exactly ONE `GoRouter` for the app, defined in `lib/routing/`, and every screen is reachable by a URL. Navigation is a data structure (routes + a pure redirect), not a pile of imperative `Navigator.push` calls.
Read the reference for the task at hand:
- `references/go-router-config.md` — the single router, `context.go` vs `context.push`, path params vs `state.extra`, typed route helpers, `errorBuilder`/404.
- `references/guards-and-redirects.md` — pure `redirect` functions, the Riverpod `refreshListenable`, auth + onboarding gates, avoiding redirect loops.
- `references/shells-and-deep-links.md` — `StatefulShellRoute.indexedStack` for bottom-nav/rail shells, `CustomTransitionPage`, `PopScope`, and notification-payload → location mapping.
Run `scripts/check_routing.sh` before a PR.
## Non-negotiable rules
1. **Exactly ONE `GoRouter`, built in `lib/routing/`, wired once via `MaterialApp.router` in `app.dart`.** Multiple routers fragment history, deep links, and back-button behaviour. The router is created behind a provider so guards can watch app state.View the complete source on GitHubpersistence-drift
When your agent uses it
Governs the on-device Drift/SQLite data layer: package:drift and package:sqlite3 confined to lib/data/ behind DAOs that map rows to immutable value objects (no Drift symbol leaks past the repository), invariants pushed into the schema (STRICT tables, CHECK/FK/partial-UNIQUE indexes), foreign_keys/WAL pragmas re-asserted idempotently in beforeOpen, one db.transaction per mutation, persist-before-publish, every query awaited, canonical integer storage, derived state recomputed-on-read never stored, scoped .watch streams, keyset (seek) pagination not OFFSET, and WAL-safe backups (checkpoint + VACUUM INTO, verify-by-reopen, never File.copy a live WAL DB). Use when defining or altering a Drift Table, Companion, DAO, index, or CHECK; writing a repository transaction or scoped watch provider; wiring the connection/beforeOpen pragmas; adding SQLCipher; building or verifying a backup; or reviewing a data-layer diff. Migrations and their tests live in run-migration.
What it loads into context
Frontmatter
237 tokensAlways available to the agent
SKILL.md
4,491 tokensWhen the skill is activated
Reference documents
4,176 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- Confining Drift to one layer
- Schema: invariants in the table
- The connection: pragmas per open
- DAO + repository: one transaction, mapped to value objects
- Riverpod wiring (state + DI)
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/check-drift-confinement.shscripts/check-persistence-bans.sh
Files
SKILL.mdcore18,840 bytesSKILL.mdcore18,840 bytesSKILL.mdcore18,840 bytesSKILL.mdcore18,840 bytesSKILL.mdcore18,840 bytesSKILL.mdcore18,840 bytesexamples/in_memory_dao_test.dartasset2,180 bytesexamples/scoped_watch_repository.dartasset2,628 bytesexamples/transactional_write.dartasset2,705 bytesreferences/backup-and-wal.mddoc5,582 bytesreferences/persistence-without-drift.mddoc3,261 bytesreferences/schema-and-daos.mddoc8,459 bytesscripts/check-drift-confinement.shruns1,387 bytesscripts/check-persistence-bans.shruns2,289 bytes
Read SKILL.md
# Persistence — Drift / SQLite
The on-device store is the single source of truth: with no server, everything must rebuild from this DB alone after
process death, reboot, or restore. Push invariants into the schema, confine Drift to one layer, make every mutation
one durable transaction, and store canonical values only. Applies to any `lib/data/` Drift table, DAO, repository,
connection setup, or backup.
Read the reference for the task at hand:
- `references/schema-and-daos.md` — audit-column mixin, STRICT/CHECK/FK invariants, canonical column types, the index + `EXPLAIN QUERY PLAN` gate, DAO↔repository split, files-on-disk-with-relative-paths for blobs.
- `references/backup-and-wal.md` — the checkpoint→vacuum→verify-by-reopen primitive, WAL rules, the backup-before-anything lesson, optional SQLCipher (key-first, assert-cipher, header-check).
- `references/persistence-without-drift.md` — the same discipline for a small app on plain JSON files (injected base dir, debounce + lifecycle flush, atomic writes, lenient decode).
Run `scripts/check-drift-confinement.sh` and `scripts/check-persistence-bans.sh` before a PR. Migrations and their tests: see `run-migration`.
View the complete source on GitHubproject-structure-and-packages
When your agent uses it
Enforces Flutter/Dart project scaffolding where the layout makes defects greppable — a single-package app by default (feature-first under lib/features/, shared foundation split by role in core/ data/ services/ routing/ theme/ l10n/, a thin main.dart that calls bootstrap(), no lib/src in the app), extracting a generically-named pure-Dart package only when a body of logic earns it (public barrel over private lib/src/ for PACKAGES only, meta-only deps as the compile firewall, resolution:workspace member, downward-only dependency DAG), with pubspec treated as the audit artifact and no utils/helpers/common/misc/grab-bag-shared junk-drawer folders. Use when creating any .dart file or directory, deciding where a repository/Notifier/MethodChannel/value-type/token belongs, authoring or fixing a pubspec.yaml, adding a workspace member, writing an import directive, mirroring a test under test/, or reviewing a diff for organisation.
What it loads into context
Frontmatter
207 tokensAlways available to the agent
SKILL.md
4,104 tokensWhen the skill is activated
Reference documents
4,983 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- Default single-package tree
- Placement decision procedure
- When to extract a package (multi-package / workspace)
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/check_import_boundaries.shscripts/check_structure.sh
Files
SKILL.mdcore17,247 bytesexamples/placement_by_failure.dartasset2,410 bytesexamples/public_api_surface.dartasset2,526 bytesreferences/layering-and-dependencies.mddoc5,789 bytesreferences/single-package-layout.mddoc10,115 bytesreferences/workspace-and-packages.mddoc5,629 bytesscripts/check_import_boundaries.shruns2,906 bytesscripts/check_structure.shruns2,329 bytes
Read SKILL.md
# Project structure & packages
The layout is a feedback loop, not decoration: structure exists so that "what imports Flutter?", "what has no test?", and "does this feature reach into another?" are answerable by `grep` and `ls`, not by trust. Default to **one Flutter package** (the app), organised **feature-first** under `lib/features/` over a shared foundation. Reach for a second, pure-Dart package only when a body of logic earns the isolation. A `pubspec.yaml` is the audit artifact — a package cannot import what it does not declare, so the dependency list *is* the layer boundary.
This skill OWNS the physical directory tree (D1). Other skills reference it rather than drawing their own.
Read the reference for the task at hand:
- `references/single-package-layout.md` — the default one-package feature-first tree, the shared-foundation folders, placement-by-failure, the deliberately-absent list.
- `references/layering-and-dependencies.md` — the downward-only DAG, feature isolation, pubspec-as-audit, the compile-firewall insight.
- `references/workspace-and-packages.md` — when (and how) to extract a pure-Dart package: barrel-over-src, `resolution: workspace`, naming the core generically.
Run `scripts/check_structure.sh` and `scripts/check_import_boundaries.sh` before a PR. The purity check auto-detects only pure roots named `*_core`; a pure package with a plain generic name (`money`, `scheduling`) must be passed explicitly, e.g. `PURE_DIR=packages/money scripts/check_import_boundaries.sh`.
## Non-negotiable rulesView the complete source on GitHubrelease-and-store-shipping
When your agent uses it
Enforces the path from a green CI run to a shipped build — pubspec `version: x.y.z+N` as the single source of versionName/versionCode (monotonic, never reused), the release artifact verified on real hardware, signing and store API keys that never enter the repo, `--obfuscate --split-debug-info` with symbols archived per build or that release's crash reports are permanently unreadable, a permission set audited from the MERGED manifest and asserted whole, store declarations (Data Safety, nutrition labels, privacy manifests) provable in the repo and read back rather than trusted, size and cold-start budgets, and a staged rollout with a halt plan. Use when cutting or tagging a release, editing `android/app/build.gradle(.kts)`, `key.properties`, `AndroidManifest.xml`, `Info.plist` or `PrivacyInfo.xcprivacy`, bumping a version, uploading to Play or TestFlight, writing store-listing or privacy copy, symbolizing a crash, chasing size, or diagnosing an upload rejection or a blocked submission.
What it loads into context
Frontmatter
249 tokensAlways available to the agent
SKILL.md
4,403 tokensWhen the skill is activated
Reference documents
6,760 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The ordered release ritual
- Version and build number mapping
- Symbols and crash symbolization
- What a release proves that CI cannot
- Anti-patterns
- Definition of done
- When multi-flavor
- Related skills
- References
Scripts executed separately
scripts/check-ipa-slices.shscripts/check-release-hygiene.sh
Files
SKILL.mdcore18,855 bytesSKILL.mdcore18,855 bytesSKILL.mdcore18,855 bytesSKILL.mdcore18,855 bytesSKILL.mdcore18,855 bytesSKILL.mdcore18,855 bytesreferences/android-play.mddoc5,598 bytesreferences/app-store-connect-submission.mddoc10,101 bytesreferences/ios-app-store.mddoc6,089 bytesreferences/privacy-permissions-and-claims.mddoc7,247 bytesscripts/check-ipa-slices.shruns2,860 bytesscripts/check-release-hygiene.shruns3,265 bytes
Read SKILL.md
# Release and store shipping
CI proves the *code*; a release proves the *artifact*. Everything here is about the
exact bundle a stranger installs — built with R8, obfuscation, tree-shaking, and
release-mode asserts stripped, signed by a key you must never lose, declaring
things about itself to a store that will pull the app if they are untrue. This
skill starts where `ci-pipeline-and-gates` ends and where `design-review-workflow`
signs off.
**Building, signing, uploading, and tagging are side-effecting and irreversible in
part** (a published build number can never be reused; an iOS build can never be
unshipped). Never run them because a task seemed to imply a release — run them only
when the developer asks for a release by name. Reading and enforcing the *config*
rules below is always in scope.View the complete source on GitHubrun-codegen
When your agent uses it
Runs the deterministic build_runner codegen pass (drift_dev, freezed, json_serializable, riverpod_generator) as one pinned command with --delete-conflicting-outputs, always before flutter analyze, never hand-editing or force-committing generated *.g.dart / *.freezed.dart / *.drift.dart output, watch only in local dev. Use when regenerating codegen, fixing "missing part file" / "conflicting outputs" / undefined generated-class analyzer errors, after editing a drift table or DAO, a freezed value object, a riverpod Notifier or provider, or a json_serializable model, or after a fresh git clone, branch switch, or pull.
What it loads into context
Frontmatter
169 tokensAlways available to the agent
SKILL.md
1,726 tokensWhen the skill is activated
Reference documents
0 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The canonical command
- Standard sequence on a fresh clone, pull, or branch switch
- Dev iteration (optional watch)
- When multi-package (workspace)
- When codegen and the analyzer disagree
- Anti-patterns
- Definition of done
- Related skills
- References
Files
SKILL.mdcore7,351 bytesSKILL.mdcore7,351 bytesSKILL.mdcore7,351 bytesSKILL.mdcore7,351 bytesSKILL.mdcore7,351 bytesSKILL.mdcore7,351 bytesSKILL.mdcore7,351 bytesSKILL.mdcore7,351 bytesSKILL.mdcore7,351 bytes
Read SKILL.md
# Run codegen (build_runner)
A deterministic, low-freedom runbook: regenerate all annotation-driven code in
one pass, then analyze. Run the pinned command exactly as written — do not
modify it, add flags, or hand-edit generated files. Applies whenever a source
file carries a codegen annotation (`@freezed`, `@JsonSerializable`,
`@riverpod`, `@DriftDatabase`, a drift table) and its `*.g.dart` /
`*.freezed.dart` / `*.drift.dart` part is missing or stale.
## Non-negotiable rules
1. **Run codegen BEFORE `flutter analyze`.** A fresh clone, branch switch, or
freshly edited annotated file has no generated part on disk. Analyzing that
tree produces misleading "missing part file" and undefined-class errors thatView the complete source on GitHubrun-goldens-rebaseline
When your agent uses it
Runs the golden re-baselining ritual — the one sanctioned way committed reference images are overwritten. Enforces the order: land and green the non-golden geometry, contrast and a11y tests FIRST, re-baseline only in the pinned blessing environment that produced the committed images, with loadAppFonts() so nothing renders in Ahem, via `flutter test --update-goldens --tags golden` (never in CI, never to make a red pipeline green), then inspect every changed PNG by eye, delete the orphans left by renamed or removed tests, land the images as their own commit naming why they moved, and prove it by re-running the suite WITHOUT the flag. Manual, side-effecting workflow. Use when a deliberate visual change breaks matchesGoldenFile, when adding or renaming a golden test, or when someone reaches for --update-goldens.
What it loads into context
Frontmatter
211 tokensAlways available to the agent
SKILL.md
2,157 tokensWhen the skill is activated
Reference documents
0 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The ordered workflow
- Verification (blocking — must pass before the PR)
- Anti-patterns
- Definition of done
- Related skills
- References
Files
SKILL.mdcore8,895 bytesSKILL.mdcore8,895 bytesSKILL.mdcore8,895 bytesSKILL.mdcore8,895 bytesSKILL.mdcore8,895 bytes
Read SKILL.md
# Run goldens rebaseline
Blessing a golden overwrites the only record of what the UI used to look like. It is
the one operation in the test suite that *destroys* an assertion instead of running it,
so it is a **manual, low-freedom, human-run** workflow: execute the steps in order, do
not improvise, and never run it to make a failure go away.
The two-lane golden strategy, the harness, and why goldens are the *weakest* visual
assertion belong to `widget-golden-and-a11y-testing`. This skill is only the ritual for
changing the baselines.
## Non-negotiable rules
1. **A golden failure is a question, not a chore.** Before anything is regenerated,View the complete source on GitHubrun-migration
When your agent uses it
Runs the forward-only Drift/SQLite schema-migration ritual — the most dangerous deterministic operation in an offline-first app: a bad migration silently destroys on-device rows that exist nowhere else. Enforces the exact ordered sequence: take a pre-migration file snapshot before the database is opened, bump schemaVersion by exactly one, write an append-only stepByStep forward step (never edit a shipped step, never write a down migration), commit the drift_dev make-migrations schema snapshot, regenerate, then prove it with tests covering every from→to path (incl. multi-version jumps), a write-at-v(n)/read-at-v(n+1) content test, PRAGMA integrity_check + foreign_key_check, and a forced mid-migration throw that restores the snapshot. Manual, side-effecting workflow. Use when adding or altering a Drift table, column, index, or CHECK; bumping schemaVersion; editing onUpgrade/stepByStep; or writing migration tests.
What it loads into context
Frontmatter
228 tokensAlways available to the agent
SKILL.md
4,018 tokensWhen the skill is activated
Reference documents
0 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The ordered workflow
- The migration guard
- Snapshot commands (explicit form)
- Verification (blocking — must pass before commit)
- Anti-patterns
- Definition of done
- When multi-package (workspace)
- Related skills
- References
Files
SKILL.mdcore17,083 bytesSKILL.mdcore17,083 bytesSKILL.mdcore17,083 bytesSKILL.mdcore17,083 bytesSKILL.mdcore17,083 bytes
Read SKILL.md
# Run migration (forward-only Drift schema migration)
Apply a schema change to a local Drift/SQLite database by following the exact
ordered ritual below. In an offline-first app there is no server and no re-sync
path, so the on-device DB is the single source of truth: a migration that drops
or corrupts a column permanently destroys hand-entered records that exist
nowhere else, and with no telemetry nobody ever reports it — the user just
uninstalls. This is a **manual, low-freedom, human-run** workflow. Execute the
steps in order; do not improvise, reorder, or skip.
## Non-negotiable rules
1. **Take the pre-migration snapshot FIRST — before the database is opened.**
Do it at the composition boundary that opens `AppDatabase`, never insideView the complete source on GitHubscaffold-feature-module
When your agent uses it
Stands up one navigable feature the same way every time — a fixed lib/features/<feature>/presentation/ folder (dumb View + one 1:1 Notifier/AsyncNotifier ViewModel + widgets/ + scoped <feature>_providers.dart), downward-only dependencies with no cross-feature imports, reactive reads as scoped StreamProviders over a repository .watch(), every mutation through one repository single-write-path method, typed Result/Failure surfaced as AsyncValue, a typed go_router route carrying identity in path params, ARB parity across locales, family+autoDispose keying, and EdgeInsetsDirectional-only geometry. Use when adding a screen, tab, or feature folder; wiring a feature Notifier/ViewModel or a scoped stream provider; registering a route; adding ARB keys for a new screen; splitting an over-grown feature; or adding a persisted record its View reads.
What it loads into context
Frontmatter
184 tokensAlways available to the agent
SKILL.md
4,476 tokensWhen the skill is activated
Reference documents
4,254 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The canonical Notifier + scoped stream
- The dumb View
- The two manual steps the generator can't do
- Optional: the feature reads a brand-new persisted record
- Anti-patterns
- Definition of done
- Related skills
- References
- Provider / ChangeNotifier appendix
Scripts executed separately
scripts/scaffold_feature.shscripts/verify_feature.sh
Files
SKILL.mdcore19,114 bytesSKILL.mdcore19,114 bytesSKILL.mdcore19,114 bytesSKILL.mdcore19,114 bytesexamples/tasks_notifier.dartasset3,339 bytesexamples/tasks_screen.dartasset3,827 bytesreferences/add-persisted-record.mddoc4,870 bytesreferences/anatomy-and-wiring.mddoc7,106 bytesreferences/routing-and-l10n.mddoc5,725 bytesscripts/scaffold_feature.shruns5,361 bytesscripts/verify_feature.shruns3,691 bytes
Read SKILL.md
# Scaffold a feature module
Stand up one feature the **same way every time**: a folder `lib/features/<feature>/` whose
`presentation/` holds a dumb View, its 1:1 Notifier/AsyncNotifier ViewModel, leaf `widgets/`, and
scoped providers (feature-local models live in an optional `domain/`). A feature is a folder, not a
package. It reads shared repositories from `lib/data/` and shared foundation from `lib/core/`, routes
every write through them, and depends only *downward* — never sideways into another feature.
(The single-package tree is owned by `project-structure-and-packages`.)
Agnostic core (holds under any state library): the View is dumb; one ViewModel per feature owns
private mutable state and exposes intent methods that assign a new immutable value; reads derive from
the repository (the single source of truth), writes go through one repository method (the single write
path, persist-before-publish); the feature depends on abstractions and navigates by route ID. The
Riverpod-first "how" below wires that with Notifiers, scoped StreamProviders, and providers-as-DI.View the complete source on GitHubseeded-determinism-and-golden-vectors
When your agent uses it
Enforces reproducible derived content — output every device must compute identically from a key, with no server. The key is injected, never read from a clock; a calendar-day key is a civil date, not an instant, and one day definition serves every comparison; the seed is a specified hash plus a mix step feeding a PRNG you own, never `dart:math`'s `Random`; entropy has exactly one source, so no `DateTime.now()`, no ambient `Random()`, no ordering by `identityHashCode`; content is regenerated from (key, generatorVersion) rather than stored; a shipped generator is frozen and an improvement is a versioned cutover, never an in-place edit that rewrites history; and it is pinned by a committed golden-vector table of fingerprints from an independent oracle, regenerated only by a reviewed command CI verifies but never blesses. Use when generating content from a seed or date, writing or regenerating golden vectors, versioning a generator, or debugging output that differs between devices or runs.
What it loads into context
Frontmatter
246 tokensAlways available to the agent
SKILL.md
3,455 tokensWhen the skill is activated
Reference documents
2,234 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- Deriving the seed
- The golden vector table
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/check-determinism-bans.sh
Files
SKILL.mdcore14,101 bytesSKILL.mdcore14,101 bytesexamples/golden_vectors_test.dartasset4,426 bytesexamples/seeded_generator.dartasset5,565 bytesreferences/golden-vectors.mddoc4,800 bytesreferences/seed-derivation.mddoc4,744 bytesscripts/check-determinism-bans.shruns2,082 bytes
Read SKILL.md
# Seeded determinism and golden vectors
Some output must be a **pure function of a key**: the daily pick every user compares with their
friends, a procedurally generated layout, a shareable result someone else can verify. It has to come
out identical on every device, in every timezone, on the platform build you ship next year — with no
server to arbitrate. That is a stronger property than "the tests pass", and it needs its own
discipline plus a frozen oracle to keep it.
`testing-strategy` owns *how* you test pure logic (seeded fuzz against an independent oracle, injected
`Clock`). This skill owns what makes the output reproducible in the first place, and the committed
vector table that pins it.
**A golden *vector* is not a golden *image*.** Vectors are data fingerprints for a pure generator,
asserted by `dart test` with no widget binding; reference PNGs of rendered UI belong toView the complete source on GitHubservice-boundary-and-native
When your agent uses it
Wires every side effect and native channel as an injectable interface behind a Provider that throws UnimplementedError until the composition root overrides it, with one live impl per flavor, value-typed signatures returning typed results, hand-written contract-honouring fakes over mocks, MethodChannel quarantined to one lib/native/ directory, and versioned cross-language contracts edited on both sides in one commit. Use when adding or changing a ShareService/AnalyticsService/RemoteConfigService or any side-effect port, injecting a Clock (package:clock) via clockProvider, a MethodChannel/platform channel or native widget bridge, a flavor entrypoint (main_*.dart) or per-flavor provider override, a shared-file/JSON contract mirrored in Kotlin/Swift, replacing a stray DateTime.now() or direct SDK call inside a widget/notifier/repository, or wiring a fake via ProviderScope(overrides:) in tests.
What it loads into context
Frontmatter
192 tokensAlways available to the agent
SKILL.md
4,215 tokensWhen the skill is activated
Reference documents
4,736 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The interface and its provider (Riverpod DI)
- One live impl at the composition root
- Fakes over mocks
- The native boundary
- Anti-patterns
- Definition of done
- Related skills
- Provider / ChangeNotifier appendix
- References
Scripts executed separately
scripts/check-flavor-graph.shscripts/check-service-boundaries.sh
Files
SKILL.mdcore18,716 bytesexamples/native_gateway.dartasset5,053 bytesexamples/service_boundary.dartasset6,644 bytesreferences/multi-flavor.mddoc5,226 bytesreferences/native-channels.mddoc7,937 bytesreferences/service-interface.mddoc7,801 bytesscripts/check-flavor-graph.shruns1,388 bytesscripts/check-service-boundaries.shruns2,775 bytes
Read SKILL.md
# Service boundary and native
Every platform capability — reading "now", sharing, logging an event, fetching remote flags, calling a MethodChannel — crosses the app's layers as an **injected interface**. The interface names value types only; the concrete SDK lives in exactly one class; the composition root (`main`) wires one live impl; tests wire a deterministic fake. **Abstract exactly what cannot run in a test — nothing more.** This is the seam that keeps features pure, SDKs swappable, and the whole app testable headlessly.
Read the reference for the task at hand:
- `references/service-interface.md` — typed outcomes vs bool/throw, exhaustiveness, `@useResult`, hand-written env-fakes, the arrow-callback Future-drop hole, single write path.
- `references/native-channels.md` — MethodChannel placement, the cross-language contract ownership table, versioned-file-vs-`shared_preferences` traps, native-fast-path independence, the round-trip `integration_test`.
- `references/multi-flavor.md` — line-for-line composition roots, build flavors over runtime detection, per-flavor plugin pins, the banned-dependency CI graph gate.
Run `scripts/check-service-boundaries.sh` and `scripts/check-flavor-graph.sh` before a PR.
## Non-negotiable rules
1. **Every side effect is an injected interface, never a concrete SDK at the call site.** Features, Notifiers, and repositories depend on the *interface*; the app imports the real SDK in exactly one live-impl class. WHY: one seam to swap, one place to quarantine platform quirks, zero SDK reach into pure code.View the complete source on GitHubstate-management-riverpod
When your agent uses it
Enforces feature state as one Notifier/AsyncNotifier/StreamNotifier ViewModel over an immutable state value with value equality, private mutable state mutated only through intent methods, derive-don't-store, a single write path through a repository, and unidirectional data flow; Riverpod 3.x is DI (providers-as-collaborators, ProviderScope overrides per flavor, throwing seams), reads split ref.watch/.select for display vs ref.read(p.notifier) in callbacks vs ref.listen for side effects, async modeled as AsyncValue, per-entity state family-keyed + autoDispose, and stale-closure captures / legacy StateProvider-StateNotifierProvider-ChangeNotifierProvider / get_it / package:provider are banned. Use when adding state to a screen, writing a feature controller/ViewModel, wiring providers or DI, deriving a read model from a stream, or reviewing rebuild/state-leak/disposal/write-path issues.
What it loads into context
Frontmatter
196 tokensAlways available to the agent
SKILL.md
4,046 tokensWhen the skill is activated
Reference documents
3,176 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- Riverpod: pick the right shape
- Riverpod: providers are DI (throwing seams)
- Riverpod: reads — watch / read / listen
- Riverpod: lifecycle & disposal
- Riverpod: accessibility state does NOT go through providers
- Anti-patterns
- Definition of done
- Related skills
- References
- Provider / ChangeNotifier appendix
Scripts executed separately
scripts/ban-legacy-providers.sh
Files
SKILL.mdcore17,205 bytesSKILL.mdcore17,205 bytesSKILL.mdcore17,205 bytesexamples/composition_root.dartasset3,074 bytesexamples/task_list_feature.dartasset6,367 bytesreferences/ownership-and-lifecycle.mddoc4,746 bytesreferences/reads-and-side-effects.mddoc4,320 bytesreferences/riverpod3-api-and-testing.mddoc4,508 bytesscripts/ban-legacy-providers.shruns2,908 bytes
Read SKILL.md
# State management (Riverpod)
State and dependency injection are one mechanism: Riverpod 3.x. Each feature has one `Notifier`/`AsyncNotifier`/`StreamNotifier` ViewModel that exposes an **immutable** state value; dumb `ConsumerWidget`s read it. Widgets hold only ephemeral UI state; every durable mutation routes through one repository (the single write path). This skill covers the state-agnostic core first, then the Riverpod "how", then a Provider/ChangeNotifier appendix for the official Flutter-guide stack.
Read the reference for the task at hand:
- `references/ownership-and-lifecycle.md` — the ownership table (which provider shape), family/autoDispose/onDispose rules, composition-root DI.
- `references/reads-and-side-effects.md` — watch vs read vs listen vs select, the stale-closure hole, `void` action methods, `ref.mounted`/`BuildContext` guards.
- `references/riverpod3-api-and-testing.md` — Riverpod 3.x API shifts (legacy moves, `overrideWithValue`, retry, `ProviderContainer.test`), what 2023 tutorials get wrong, and testing seams.
Run `scripts/ban-legacy-providers.sh` before a PR.
## Non-negotiable rules
View the complete source on GitHubtesting-strategy
When your agent uses it
Enforces test doctrine where shape follows code not the pyramid: pushes logic into Flutter-free packages tested with pure package:test and an injected Clock; asserts invariants with seeded fuzz tests against an independent oracle plus round-trip and rounding goldens; prefers bare-implements fakes over mocktail for code you own; tests the data layer against a real NativeDatabase.memory Drift engine, never a mocked DAO; drives Notifiers headlessly with ProviderContainer overrides; guards one end-to-end acceptance gate and a runtime invariant tripwire; floors coverage on unrecoverable-bug files not a global percentage; and fixes the coverage-lies-upward gap. Use when writing tests under test/ or integration_test/, choosing unit vs widget vs integration, adding a fuzz or round-trip property, wiring a fake or ProviderContainer test, gating coverage, or triaging a flaky-suite failure.
What it loads into context
Frontmatter
202 tokensAlways available to the agent
SKILL.md
3,599 tokensWhen the skill is activated
Reference documents
3,961 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- Tier the test to the code (`package:test` vs `flutter_test`)
- Inject the clock; pin it in tests
- Seeded fuzz against an independent oracle
- Real in-memory Drift, never a mocked DAO
- Headless Notifier tests with `ProviderContainer`
- Drive timers with `fakeAsync`
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/check_test_hygiene.shscripts/run_tests.sh
Files
SKILL.mdcore14,910 bytesexamples/allocate_property_test.dartasset5,130 bytesexamples/in_memory_drift_test.dartasset2,549 bytesexamples/notifier_container_test.dartasset3,429 bytesreferences/coverage-and-budget.mddoc5,458 bytesreferences/property-and-fakes.mddoc6,559 bytesreferences/test-layers.mddoc5,003 bytesscripts/check_test_hygiene.shruns2,972 bytesscripts/run_tests.shruns1,730 bytes
Read SKILL.md
# Testing Strategy
Tests are the only correctness instrument you control at build time: shape the suite
to the code, not to a decades-old ratio, and make each test assert behaviour a build
either passes or fails. Applies to every test under `test/` and `integration_test/`.
Read the reference for the task at hand:
- `references/test-layers.md` — per-layer harness, imports, teardown, edge tables (pure core, in-memory Drift, headless Notifier, integration).
- `references/property-and-fakes.md` — fakes-over-mocks, enum-driven fake state, seeded fuzz, independent oracles, absence-of-a-failure-class tests.
- `references/coverage-and-budget.md` — file-level floors, the coverage-lies-upward fix, the suite-time budget, and the manual-pass handoff.
Run `scripts/check_test_hygiene.sh` and `scripts/run_tests.sh` before a PR.
Golden, RTL, and a11y widget mechanics live in `widget-golden-and-a11y-testing`; thisView the complete source on GitHubui-states-and-feedback
When your agent uses it
Enforces the non-happy paths every screen owes the user — loading/empty/error/content resolved in ONE switch over an AsyncValue or sealed view state, never an isLoading+error+data bool triple; a delayed skeleton shaped like the result instead of a spinner that flashes; a refresh that keeps stale content on screen; "nothing yet" distinguished from "nothing matches this filter", each with its own action; error text from a typed Failure code (never e.toString()) plus a retry that invalidates the provider; the surface ladder inline, snackbar, banner, dialog, with a modal earned only by a decision that must resolve now; soft-delete + Undo over a confirmation; showDialog's null dismissal handled as its own outcome; ScaffoldMessenger captured before an await; and announcements for eye-only changes. Use when writing loading, empty, error, or offline UI, calling AsyncValue.when, showDialog, showModalBottomSheet, showSnackBar or showMaterialBanner, or adding a confirmation, Undo, or retry.
What it loads into context
Frontmatter
239 tokensAlways available to the agent
SKILL.md
3,699 tokensWhen the skill is activated
Reference documents
0 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The four states — one resolution point
- The surface ladder
- Feedback after a write
- Confirming something irreversible
- Anti-patterns
- Definition of done
- Related skills
- References
Files
SKILL.mdcore15,940 bytesexamples/async_state_view.dartasset7,348 bytes
Read SKILL.md
# UI states and feedback
Most of a screen's code is the happy path; most of its defects are not. This skill
governs everything a screen shows when there is no data yet, no data at all, no data
matching the filter, a failure, or a write that just returned — and which *surface* each
of those is allowed to use. The first-frame/cold-start path belongs to
`app-startup-and-bootstrap`; the error *values* belong to `error-handling-typed-results`.
This skill is only about how they are rendered and announced.
## Non-negotiable rules
1. **One state, resolved in one place.** A screen renders exactly one of
loading / empty / error / content, chosen by a single `switch` over an `AsyncValue`
or a sealed view state. Never a triple of `isLoading`, `error`, `items` booleans.View the complete source on GitHubvalue-objects-money-and-units
When your agent uses it
Enforces a pure-Dart value-object core that stores every quantity canonically — money as integer minor units keyed to each currency's real ISO-4217 exponent (never *100), physical amounts as SI whole units, timestamps as UTC — and converts only at the presentation edge; forbids double/num money, cross-currency arithmetic, and defaulting an unknown currency to two decimals; routes every division of money through one largest-remainder allocate() primitive so parts always sum to the whole to the exact minor unit; derives totals instead of storing them, links entities by stable id, and injects a Clock instead of DateTime.now. Use when defining or changing Money, Currency, or a unit value object; parsing or formatting an amount; splitting, prorating, discounting, tax/tip, or distributing money; adding a currency or FX rate; converting quantities; or fixing float-money, hardcoded-100, cross-currency, off-by-a-cent, or stored-total-drift bugs.
What it loads into context
Frontmatter
233 tokensAlways available to the agent
SKILL.md
4,024 tokensWhen the skill is activated
Reference documents
4,233 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- Canonical storage
- The one division path: `allocate()`
- Parsing input to exact minor units
- Derive, don't store; inject a Clock
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/check-money-violations.shscripts/verify-core.sh
Files
SKILL.mdcore15,672 bytesexamples/allocate.dartasset4,556 bytesexamples/money.dartasset3,846 bytesreferences/allocate-and-splitting.mddoc5,999 bytesreferences/canonical-storage.mddoc5,953 bytesreferences/domain-model.mddoc4,409 bytesscripts/check-money-violations.shruns2,908 bytesscripts/verify-core.shruns1,399 bytes
Read SKILL.md
# Value objects: money & units
Store every quantity **once, in one canonical form, and convert only when shown or
exported**. Money is integer minor units plus a currency; physical quantities are
whole SI base units; time is UTC. This is what lets a user flip any display
preference (currency symbol, unit system, locale) without corrupting one stored
row, and lets "sum of parts == whole" be structural, not hoped-for.
This core is **pure Dart** — no `flutter/*`, no `intl`, no `dart:io`, no plugins.
Formatting and digit normalization happen upstream/downstream, not here. These
value objects live in `lib/core/`, the sanctioned pure-foundation layer (see
`project-structure-and-packages`) — never a `utils/`/`common/`/`shared/` grab-bag.
Read the reference for the task at hand:View the complete source on GitHubwidget-composition
When your agent uses it
Enforces Flutter widget composition — extract named const Widget classes never `Widget _buildX()` methods, lean build() (no I/O/formatting/domain math, precompute in the ViewModel), dumb Views that watch one Notifier and route intents via ref.read, StatelessWidget by default with every controller disposed, lazy `.builder` lists, cheapest-widget choices (SizedBox/ColoredBox/Align over Container), a strict key policy (ValueKey for reorderable lists, never GlobalKey), gesture→visible-focusable-fallback wiring, plus structural layout — full-bleed background vs SafeArea content, computed cell sizing, the GridView cross/main-axis spacing trap, EdgeInsetsDirectional, and resizeToAvoidBottomInset/IME handling. Use when building or refactoring any screen or widget, splitting a large build() into components, writing GridView/ListView/LayoutBuilder/SafeArea/Scaffold, wiring onTap/onLongPress/Draggable, choosing a key or data class, or reviewing widget code in a diff.
What it loads into context
Frontmatter
215 tokensAlways available to the agent
SKILL.md
4,107 tokensWhen the skill is activated
Reference documents
3,974 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- Extract a widget vs. a method
- Keep build() lean — the Notifier precomputes
- Composition guidance
- Keys
- Data classes for view-data
- Structural layout
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/check-widget-composition.sh
Files
SKILL.mdcore17,323 bytesSKILL.mdcore17,323 bytesexamples/feature_view.dartasset4,613 bytesexamples/structural_grid.dartasset3,266 bytesreferences/rebuild-mechanics.mddoc5,615 bytesreferences/structural-layout.mddoc5,513 bytesreferences/widget-and-data-selection.mddoc5,883 bytesscripts/check-widget-composition.shruns2,449 bytes
Read SKILL.md
# Widget Composition
Build every screen from many small, `const`, single-purpose widget **classes**. A widget that does one thing rebuilds cheaply, reads clearly, tests in isolation, and can be lifted into a shared component library. The View is *dumb*: it watches one ViewModel and renders; logic lives in the Notifier, state in immutable value objects, layout in directional structural primitives. Applies to any screen, list, card, or shared component.
Read the reference for the task at hand:
- `references/rebuild-mechanics.md` — why a class beats a method (`Element.updateChild`), `const` canonicalization, the full key policy, and `.select` for narrowed rebuilds.
- `references/structural-layout.md` — edge-to-edge background vs `SafeArea` content, computed cell sizing, the `GridView` cross/main-axis trap, directional insets, and IME/`resizeToAvoidBottomInset`.
- `references/widget-and-data-selection.md` — cheapest-widget table, data-class decision table (drift row vs record vs hand-written vs freezed), and gesture→fallback rules.
Run `scripts/check-widget-composition.sh` before a PR.
## Non-negotiable rules
1. **Extract a `Widget` class, never a `Widget`-returning method.** `Widget _buildHeader()` is *not* a widget — its subtree has no `Element` of its own, so `Element.updateChild` never gets to compare old vs. new and short-circuit; it rebuilds with the parent, cannot be `const`, cannot take a `Key`, and `find.byType` cannot reach it in a test.View the complete source on GitHubwidget-golden-and-a11y-testing
When your agent uses it
Enforces a disciplined widget/layout/golden/a11y test surface — one pumpApp harness that pins tester.view.physicalSize x devicePixelRatio and layers MediaQuery (textScaler/boldText/accessibleNavigation) above MaterialApp, an overflow net that never suppresses (one testWidgets per device x scale x bold tuple because overflow reports once per RenderObject), a computed getSize/getRect fit-and-geometry gate instead of goldens, two golden lanes (Ahem geometry + one pinned-OS real-font) with loadAppFonts and blocked --update-goldens, RTL goldens under Directionality, pure-Dart WCAG/APCA contrast on colour VALUES, and honest limits on meetsGuideline. Use when writing test/support/harness.dart, calling pumpWidget/pumpApp, chasing an "overflowed by N pixels" failure, reaching for takeException/ignoreOverflowErrors/FittedBox/withClampedTextScaling, adding matchesGoldenFile, or writing a11y_test.dart with isSemantics/simulatedAccessibilityTraversal/meetsGuideline.
What it loads into context
Frontmatter
227 tokensAlways available to the agent
SKILL.md
3,900 tokensWhen the skill is activated
Reference documents
7,784 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Non-negotiable rules
- The harness — one file, imported by every test
- The overflow + fit matrix
- The accessibility gate
- Golden lanes
- Anti-patterns
- Definition of done
- Related skills
- References
Scripts executed separately
scripts/check-test-hygiene.sh
Files
SKILL.mdcore15,754 bytesSKILL.mdcore15,754 bytesSKILL.mdcore15,754 bytesSKILL.mdcore15,754 bytesexamples/a11y_test.dartasset5,364 bytesexamples/harness.dartasset3,859 bytesexamples/overflow_matrix_test.dartasset5,347 bytesreferences/a11y-guidelines-and-limits.mddoc11,040 bytesreferences/golden-two-lanes.mddoc5,278 bytesreferences/harness-and-mediaquery.mddoc6,319 bytesreferences/overflow-and-textscale.mddoc8,767 bytesscripts/check-test-hygiene.shruns4,641 bytes
Read SKILL.md
# Widget, golden and accessibility testing
One harness pins the surface; layout and accessibility are asserted by **computed
geometry on the real widget tree**, not by blessed pixels. Goldens are a narrow,
honest safety net for glyph shaping and mirroring — never the layout gate. This
skill covers the widget tier; for the pure-core / Drift / Notifier tiers see
`testing-strategy`.
Read the reference for the task at hand:
- `references/harness-and-mediaquery.md` — pumpApp, Device presets, the four load-bearing lines, driving MediaQuery flags, finder policy.
- `references/overflow-and-textscale.md` — the two overflow classes, the three traps, the matrix, the fit assertion, and the four wrong fixes.
- `references/a11y-guidelines-and-limits.md` — the four built-in guidelines and their defects, the semantics/traversal gate, pure-Dart contrast, and what automation genuinely cannot cover.
- `references/golden-two-lanes.md` — the golden-refusal argument, the Ahem-vs-real-font lanes, RTL goldens, and blocking accidental blessing.
View the complete source on GitHubSkills included
- accessibility-as-code
- adaptive-layout
- ads-and-iap-monetization
- app-startup-and-bootstrap
- async-safety
- ci-pipeline-and-gates
- codegen-and-toolchain
- custom-canvas-and-gestures
- dart3-idioms-and-coding-standards
- dartdoc-conventions
- data-export-and-restore
- dependency-hygiene
- design-review-workflow
- design-system-structure
- error-handling-typed-results
- flutter-architecture
- flutter-conventions-index
- flutter-performance
- forms-and-input
- i18n-rtl-l10n
- lint-and-style-config
- local-notifications-scheduler
- motion-and-haptics
- naming-conventions
- navigation-and-routing
- persistence-drift
- project-structure-and-packages
- release-and-store-shipping
- run-codegen
- run-goldens-rebaseline
- run-migration
- scaffold-feature-module
- seeded-determinism-and-golden-vectors
- service-boundary-and-native
- state-management-riverpod
- testing-strategy
- ui-states-and-feedback
- value-objects-money-and-units
- widget-composition
- widget-golden-and-a11y-testing
Repository facts
- License
- MIT
- Created
- Jul 21, 2026
- Last pushed
- Sep 23, 2026
- Forks
- 15
- Open issues
- 0
- Project activity
- Active
Before you install
Network or broad shellAutomated signals, not a guarantee
Checked Nov 6, 2026
Not fully analyzed: some files were too long, unreadable or missing. This never lowers the level.
Show 75 notes
skills/accessibility-as-code/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/accessibility-as-code/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/accessibility-as-code/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/app-startup-and-bootstrap/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/ci-pipeline-and-gates/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/ci-pipeline-and-gates/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/ci-pipeline-and-gates/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/codegen-and-toolchain/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/codegen-and-toolchain/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/codegen-and-toolchain/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/codegen-and-toolchain/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/codegen-and-toolchain/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/codegen-and-toolchain/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/codegen-and-toolchain/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/custom-canvas-and-gestures/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/dart3-idioms-and-coding-standards/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/dartdoc-conventions/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/dependency-hygiene/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/dependency-hygiene/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/design-review-workflow/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzed
- No broad tool permissions
- 5 dangerous shell commandsin 5 files: ci-pipeline-and-gates/references/workflow-skeleton.md:71 dependency-hygiene/references/sdk-pin-and-lint-include.md:15 dependency-hygiene/scripts/audit-deps.sh:87 and 2 more
- 271 network referencesin 46 files: design-system-structure/SKILL.md:184 i18n-rtl-l10n/SKILL.md:292 custom-canvas-and-gestures/SKILL.md:260 and 43 more
- 12 obfuscation signalsin 5 files: i18n-rtl-l10n/SKILL.md:187 i18n-rtl-l10n/references/rtl-and-bidi.md:61 i18n-rtl-l10n/examples/directional_widget.dart:14 and 2 more
- No instruction overrides
- 44 executable scriptsin 44 files: adaptive-layout/scripts/check_adaptive.sh:1 ads-and-iap-monetization/scripts/check-release-ad-ids.sh:1 ci-pipeline-and-gates/scripts/banned-strings.sh:1 and 41 more
- 1 reference to secretsin 1 file: persistence-drift/references/backup-and-wal.md:112
- No requests to vote in Hot
Show all 333 signals by file
.claude-plugin/plugin.json
- Network accessline 7
"name": "Zakaria Fatahi" }, "homepage": "https://github.com/zakariaf/Flutter-Skills", - Network accessline 8
}, "homepage": "https://github.com/zakariaf/Flutter-Skills", "repository": "https://github.com/zakariaf/Flutter-Skills", - Network accessline 9
"homepage": "https://github.com/zakariaf/Flutter-Skills", - Network accessline 10
"repository": "https://github.com/zakariaf/Flutter-Skills",
skills/accessibility-as-code/SKILL.md
- Network accessline 213
- Flutter accessibility: https://docs.flutter.dev/ui/accessibility-and-internationalization/accessibility - Network accessline 214
- `Semantics` widget: https://api.flutter.dev/flutter/widgets/Semantics-class.html - Network accessline 215
- `MediaQueryData` accessibility flags: https://api.flutter.dev/flutter/widgets/MediaQueryData-class.html - Network accessline 216
- `TextScaler`: https://api.flutter.dev/flutter/painting/TextScaler-class.html - Network accessline 217
- `OrdinalSortKey`: https://api.flutter.dev/flutter/semantics/OrdinalSortKey-class.html - Network accessline 218
- WCAG 2.2 contrast (1.4.3 / 1.4.6): https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html
skills/adaptive-layout/SKILL.md
- Network accessline 163
- Material 3 layout / window size classes: https://m3.material.io/foundations/layout/applying-layout/window-size-classes - Network accessline 164
- Adaptive & responsive design (Flutter): https://docs.flutter.dev/ui/adaptive-responsive - Network accessline 165
- `MediaQuery` API (aspect getters): https://api.flutter.dev/flutter/widgets/MediaQuery-class.html - Network accessline 166
- `LayoutBuilder`: https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html - Network accessline 167
- `NavigationRail`: https://api.flutter.dev/flutter/material/NavigationRail-class.html - Network accessline 168
- `DisplayFeature` / foldables: https://api.flutter.dev/flutter/dart-ui/DisplayFeature-class.html
skills/adaptive-layout/scripts/check_adaptive.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/ads-and-iap-monetization/SKILL.md
- Network accessline 228
- App Store Review Guidelines (2.1 App Completeness, 3.1 Payments): https://developer.apple.com/app-store/review/guidelines/ - Network accessline 229
- `in_app_purchase` (StoreKit / Play Billing): https://pub.dev/packages/in_app_purchase - Network accessline 230
- Flutter — in-app purchases cookbook: https://docs.flutter.dev/cookbook/plugins/in-app-purchases - Network accessline 231
- `google_mobile_ads`: https://pub.dev/packages/google_mobile_ads - Network accessline 232
- AdMob rewarded ads (Flutter): https://developers.google.com/admob/flutter/rewarded - Network accessline 233
- User Messaging Platform / consent: https://developers.google.com/admob/flutter/privacy - Network accessline 234
- App Tracking Transparency: https://developer.apple.com/documentation/apptrackingtransparency
skills/ads-and-iap-monetization/scripts/check-release-ad-ids.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/app-startup-and-bootstrap/SKILL.md
- Network accessline 215
- Flutter — Handling errors: https://docs.flutter.dev/testing/errors - Network accessline 216
- Flutter — App startup / performance best practices: https://docs.flutter.dev/perf/best-practices - Network accessline 217
- API — `PlatformDispatcher.onError`: https://api.flutter.dev/flutter/dart-ui/PlatformDispatcher/onError.html - Network accessline 218
- API — `SchedulerBinding.addPostFrameCallback`: https://api.flutter.dev/flutter/scheduler/SchedulerBinding/addPostFrameCallback.html - Network accessline 219
- Riverpod — Provider overrides & scope: https://riverpod.dev/docs/concepts/scopes
skills/async-safety/SKILL.md
- Network accessline 244
- Async programming: <https://dart.dev/libraries/async/async-await> - Network accessline 245
- `use_build_context_synchronously`: <https://dart.dev/tools/linter-rules/use_build_context_synchronously> - Network accessline 246
- `unawaited` / `discarded_futures`: <https://dart.dev/tools/linter-rules/discarded_futures> - Network accessline 247
- `State.mounted` and `BuildContext.mounted`: <https://api.flutter.dev/flutter/widgets/State/mounted.html> - Network accessline 248
- `PlatformDispatcher.onError`: <https://api.flutter.dev/flutter/dart-ui/PlatformDispatcher/onError.html> - Network accessline 249
- Handling errors in Flutter: <https://docs.flutter.dev/testing/errors>
skills/ci-pipeline-and-gates/SKILL.md
- Network accessline 198
- subosito/flutter-action — Flutter environment for GitHub Actions. https://github.com/subosito/flutter-action - Network accessline 199
- Flutter — build and release an Android app. https://docs.flutter.dev/deployment/android - Network accessline 200
- Flutter API — `matchesGoldenFile` (goldens are OS/font/version-sensitive; `--update-goldens`). https://api.flutter.dev/flutter/flutter_test/matchesGoldenFile.html - Network accessline 201
- Dart — `dart test` runner flags (`--test-randomize-ordering-seed`). https://dart.dev/tools/dart-test - Network accessline 202
- Code With Andrea — Flutter test coverage (`lcov.info`, stripping generated files, the untested-file lie). https://codewithandrea.com/articles/flutter-test-coverage/ - Network accessline 203
- Dart — pub workspaces (monorepo). https://dart.dev/tools/pub/workspaces - Network accessline 204
- GitHub Actions — using concurrency, permissions, and pinned runners. https://docs.github.com/actions
skills/ci-pipeline-and-gates/references/policy-grep-gate.md
skills/ci-pipeline-and-gates/references/workflow-skeleton.md
- Dangerous shell operationline 71
- run: sudo apt-get update -qq && sudo apt-get install -y -qq libsqlite3-dev
skills/ci-pipeline-and-gates/scripts/banned-strings.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/ci-pipeline-and-gates/scripts/ci-gates.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/codegen-and-toolchain/SKILL.md
- Network accessline 185
- build_runner: https://dart.dev/tools/build_runner - Network accessline 186
- Drift codegen & build config: https://drift.simonbinder.eu/docs/advanced-features/builder_options/ - Network accessline 187
- freezed: https://pub.dev/packages/freezed - Network accessline 188
- json_serializable: https://pub.dev/packages/json_serializable - Network accessline 189
- riverpod codegen: https://riverpod.dev/docs/concepts/about_code_generation - Network accessline 190
- Flutter gen-l10n: https://docs.flutter.dev/ui/accessibility-and-internationalization/internationalization - Network accessline 191
- Dart pub workspaces: https://dart.dev/tools/pub/workspaces
skills/codegen-and-toolchain/scripts/check-codegen-hygiene.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/codegen-and-toolchain/scripts/regen.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/custom-canvas-and-gestures/SKILL.md
- Network accessline 260
- Flutter API — `CustomPainter` (`paint`, `shouldRepaint`, `semanticsBuilder`, `repaint`): https://api.flutter.dev/flutter/rendering/CustomPainter-class.html - Network accessline 261
- Flutter API — `CustomPaint` (`isComplex`, `willChange`, `foregroundPainter`): https://api.flutter.dev/flutter/widgets/CustomPaint-class.html - Network accessline 262
- Flutter API — `Canvas`: https://api.flutter.dev/flutter/dart-ui/Canvas-class.html - Network accessline 263
- Flutter API — `PictureRecorder` / `Picture.toImage` (rasterize-once ID buffer): https://api.flutter.dev/flutter/dart-ui/PictureRecorder-class.html - Network accessline 264
- Flutter — Taps, drags, and other gestures (arena, `localPosition`): https://docs.flutter.dev/ui/interactivity/gestures - Network accessline 265
- Flutter — Performance best practices (`RepaintBoundary`, `saveLayer`): https://docs.flutter.dev/perf/best-practices - Network accessline 266
- Flutter API — `RoundedSuperellipseBorder`: https://api.flutter.dev/flutter/painting/RoundedSuperellipseBorder-class.html - Network accessline 267
- Flutter API — `TextPainter`: https://api.flutter.dev/flutter/painting/TextPainter-class.html - Network accessline 268
- Flutter — Accessibility & Semantics (`CustomPainterSemantics`): https://docs.flutter.dev/ui/accessibility-and-internationalization/accessibility - Network accessline 269
- W3C — WCAG 2.2 §1.4.1 Use of Color: https://www.w3.org/WAI/WCAG22/Understanding/use-of-color.html
skills/custom-canvas-and-gestures/scripts/analyze.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/custom-canvas-and-gestures/scripts/check_painter_hygiene.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/dart3-idioms-and-coding-standards/SKILL.md
- Network accessline 207
- Dart team. *Effective Dart* (Style / Documentation / Usage / Design). https://dart.dev/effective-dart - Network accessline 208
- Dart team. *Class modifiers.* https://dart.dev/language/class-modifiers - Network accessline 209
- Dart team. *Patterns & pattern types* (destructuring, `if-case`). https://dart.dev/language/patterns - Network accessline 210
- Dart team. *Branches — exhaustiveness.* https://dart.dev/language/branches#exhaustiveness-checking - Network accessline 211
- Dart team. *Records.* https://dart.dev/language/records - Network accessline 212
- Dart team. *Sound null safety.* https://dart.dev/null-safety
skills/dart3-idioms-and-coding-standards/scripts/check-dart3-idioms.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/dartdoc-conventions/SKILL.md
- Network accessline 166
- [Effective Dart: Documentation](https://dart.dev/effective-dart/documentation) - Network accessline 167
- [`dart doc` tool](https://dart.dev/tools/dart-doc) - Network accessline 168
- [Linter rules](https://dart.dev/tools/linter-rules) — `public_member_api_docs`, `dangling_library_doc_comments`, `comment_references`, `slash_for_doc_comments` - Network accessline 169
- [Developing packages & plugins](https://docs.flutter.dev/packages-and-plugins/developing-packages)
skills/data-export-and-restore/SKILL.md
- Network accessline 229
- RFC 4180 — Common Format and MIME Type for CSV Files: https://www.rfc-editor.org/rfc/rfc4180 - Network accessline 230
- Dart — `dart:io` `IOSink`, `File.rename`: https://api.dart.dev/stable/dart-io/File-class.html - Network accessline 231
- `path_provider` — app directories: https://pub.dev/packages/path_provider - Network accessline 232
- `share_plus` — share sheet (incl. `sharePositionOrigin`): https://pub.dev/packages/share_plus - Network accessline 233
- `file_selector` — save/open dialogs: https://pub.dev/packages/file_selector - Network accessline 234
- `crypto` — SHA-256 for the payload checksum: https://pub.dev/packages/crypto - Network accessline 235
- OWASP — CSV Injection: https://owasp.org/www-community/attacks/CSV_Injection
skills/data-export-and-restore/examples/csv_writer.dart
- Possible obfuscationline 56
if (withBom) sink.write('<U+FEFF>'); - Network accessline 69
// --- What the tests must cover (see SKILL.md "Tests that must exist") -------- // // encodeCsvField('=HYPERLINK("http://x","c")') starts with an apostrophe - Network accessline 70
// // encodeCsvField('=HYPERLINK("http://x","c")') starts with an apostrophe // encodeCsvField('a,b"c\nd') round-trips through a real parser - Network accessline 71
// encodeCsvField('=HYPERLINK("http://x","c")') starts with an apostrophe
skills/data-export-and-restore/references/formats-and-encoding.md
- Network accessline 10
**2. Formula-injection neutralization (safety).** A spreadsheet evaluates a cell starting with `=`, `+`, `-`, `@`, tab, or CR. A field of user text such as `=HYPERLINK("http://…","click")` becomes a live formula in the recipient's spreadshe - Network accessline 11
starting with `=`, `+`, `-`, `@`, tab, or CR. A field of user text such as `=HYPERLINK("http://…","click")` becomes a live formula in the recipient's spreadsheet. Neutralize it *before* quoting — the usual fix is a leading apostrophe or a z - Network accessline 12
`=HYPERLINK("http://…","click")` becomes a live formula in the recipient's spreadsheet.
skills/dependency-hygiene/SKILL.md
- Network accessline 125
- Dart — Package dependencies & version constraints: https://dart.dev/tools/pub/dependencies - Network accessline 126
- Dart — `pubspec.lock` and glossary: https://dart.dev/tools/pub/glossary#lockfile - Network accessline 127
- Dart — `dart pub deps`: https://dart.dev/tools/pub/cmd/pub-deps - Network accessline 128
- Dart — `dart pub outdated`: https://dart.dev/tools/pub/cmd/pub-outdated - Network accessline 129
- Dart — Pub workspaces: https://dart.dev/tools/pub/workspaces - Network accessline 130
- Flutter — Adding plugin packages / path dependencies: https://docs.flutter.dev/packages-and-plugins/using-packages
skills/dependency-hygiene/references/sdk-pin-and-lint-include.md
- Dangerous shell operationline 15
- It is **JSON** — read with `jq -r '.flutter'`. The `flutter: 3.27.1` YAML form that gets copied around is the shape of a `pubspec.yaml` `environment:` block (`yq eval '.environment.flutter'`), and is wrong in `.fvmrc`.
skills/dependency-hygiene/scripts/audit-deps.sh
skills/dependency-hygiene/scripts/audit_deps.py
- Executable scriptline 1
#!/usr/bin/env python3
skills/design-review-workflow/SKILL.md
- Network accessline 130
- Flutter accessibility: https://docs.flutter.dev/ui/accessibility-and-internationalization/accessibility - Network accessline 131
- Testing accessibility on device (screen reader, switch access): https://docs.flutter.dev/ui/accessibility-and-internationalization/accessibility#testing-your-apps-accessibility - Network accessline 132
- Internationalization & RTL: https://docs.flutter.dev/ui/accessibility-and-internationalization/internationalization - Network accessline 133
- Material 3 accessibility guidance: https://m3.material.io/foundations/accessible-design/overview - Network accessline 134
- WCAG 2.2 contrast & target-size: https://www.w3.org/WAI/WCAG22/quickref/ - Network accessline 135
- `flutter build` (release, obfuscation/split-debug-info): https://docs.flutter.dev/deployment/obfuscate
skills/design-system-structure/SKILL.md
- Network accessline 184
- Flutter API — `ThemeExtension`: https://api.flutter.dev/flutter/material/ThemeExtension-class.html - Network accessline 185
- Flutter API — `ThemeData` (`extensions`, component themes, `colorScheme`): https://api.flutter.dev/flutter/material/ThemeData-class.html - Network accessline 186
- Flutter API — `ColorScheme` (roles; `fromSeed` caveats): https://api.flutter.dev/flutter/material/ColorScheme-class.html - Network accessline 187
- Flutter cookbook — Use themes to share colors and font styles: https://docs.flutter.dev/cookbook/design/themes - Network accessline 188
- Flutter cookbook — Use a custom font (bundling, `fontFamilyFallback`): https://docs.flutter.dev/cookbook/design/fonts - Network accessline 189
- Flutter API — `MediaQueryData.disableAnimations` / `textScaler`: https://api.flutter.dev/flutter/widgets/MediaQueryData-class.html - Network accessline 190
- Flutter API — `Color.computeLuminance` (WCAG relative luminance): https://api.flutter.dev/flutter/dart-ui/Color/computeLuminance.html - Network accessline 191
- Flutter API — `LicenseRegistry`: https://api.flutter.dev/flutter/foundation/LicenseRegistry-class.html - Network accessline 192
- Material Design 3 — design tokens: https://m3.material.io/foundations/design-tokens/overview - Network accessline 193
- W3C WAI — WCAG 2.2 SC 1.4.3 Contrast (Minimum): https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html - Network accessline 194
- W3C WAI — WCAG 2.2 SC 1.4.1 Use of Color: https://www.w3.org/WAI/WCAG22/Understanding/use-of-color.html
skills/design-system-structure/scripts/check_font_bundling.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/design-system-structure/scripts/check_raw_values.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/error-handling-typed-results/SKILL.md
- Network accessline 212
- Dart — [Error handling](https://dart.dev/language/error-handling) (exceptions vs errors, `rethrow`, catch specificity) - Network accessline 213
- Dart — [Branches: exhaustive switch](https://dart.dev/language/branches#exhaustiveness-checking) and [class modifiers: `sealed`](https://dart.dev/language/class-modifiers#sealed) - Network accessline 214
- Dart — [Concurrency](https://dart.dev/language/concurrency) (`Isolate.run`, message passing) - Network accessline 215
- Flutter — [Handling errors in Flutter](https://docs.flutter.dev/testing/errors) (`FlutterError.onError`, `PlatformDispatcher.instance.onError`) - Network accessline 216
- Riverpod — [AsyncNotifier / AsyncValue](https://riverpod.dev/docs/concepts/providers) - Network accessline 217
- pub.dev — [result_dart](https://pub.dev/packages/result_dart) · [clock](https://pub.dev/packages/clock) · [meta (`@useResult`)](https://pub.dev/packages/meta)
skills/error-handling-typed-results/scripts/check-softdelete-parity.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/error-handling-typed-results/scripts/check-swallowed-catch.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/flutter-architecture/SKILL.md
- Network accessline 241
- [Flutter — Guide to app architecture](https://docs.flutter.dev/app-architecture/guide) - Network accessline 242
- [Flutter — Architecture recommendations](https://docs.flutter.dev/app-architecture/recommendations) - Network accessline 243
- [Flutter — UI layer case study (what a dumb View may contain)](https://docs.flutter.dev/app-architecture/case-study/ui-layer) - Network accessline 244
- [Flutter — Offline-first support (local store authoritative)](https://docs.flutter.dev/app-architecture/design-patterns/offline-first) - Network accessline 245
- [Riverpod 3 documentation](https://riverpod.dev) - Network accessline 246
- [Dart — Pub workspaces (monorepo support)](https://dart.dev/tools/pub/workspaces)
skills/flutter-architecture/scripts/check_architecture.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/flutter-conventions-index/SKILL.md
- Network accessline 196
- Effective Dart — https://dart.dev/effective-dart - Network accessline 197
- Flutter architecture recommendations — https://docs.flutter.dev/app-architecture - Network accessline 198
- Riverpod — https://riverpod.dev - Network accessline 199
- very_good_analysis — https://pub.dev/packages/very_good_analysis - Network accessline 200
- Flutter internationalization — https://docs.flutter.dev/ui/accessibility-and-internationalization/internationalization
skills/flutter-performance/SKILL.md
- Network accessline 126
- [Flutter — Performance best practices](https://docs.flutter.dev/perf/best-practices) - Network accessline 127
- [Flutter — Performance profiling / UI performance](https://docs.flutter.dev/perf/ui-performance) - Network accessline 128
- [Flutter — Concurrency and isolates / compute](https://docs.flutter.dev/perf/isolates) - Network accessline 129
- [Flutter — Impeller rendering engine](https://docs.flutter.dev/perf/impeller) - Network accessline 130
- [Flutter API — RepaintBoundary](https://api.flutter.dev/flutter/widgets/RepaintBoundary-class.html) - Network accessline 131
- [Flutter API — ResizeImage / cacheWidth](https://api.flutter.dev/flutter/painting/ResizeImage-class.html) - Network accessline 132
- [Riverpod — using select to filter rebuilds](https://riverpod.dev/docs/concepts/reading#using-select-to-filter-rebuilds)
skills/forms-and-input/SKILL.md
- Network accessline 182
- Form: https://api.flutter.dev/flutter/widgets/Form-class.html - Network accessline 183
- TextFormField: https://api.flutter.dev/flutter/material/TextFormField-class.html - Network accessline 184
- FocusNode: https://api.flutter.dev/flutter/widgets/FocusNode-class.html - Network accessline 185
- TextInputAction: https://api.flutter.dev/flutter/services/TextInputAction.html - Network accessline 186
- Autofill: https://api.flutter.dev/flutter/services/AutofillHints-class.html - Network accessline 187
- Forms cookbook: https://docs.flutter.dev/cookbook/forms/validation
skills/forms-and-input/scripts/check_forms.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/i18n-rtl-l10n/SKILL.md
- Possible obfuscationline 187
const _lri = '<U+2066>'; // LEFT-TO-RIGHT ISOLATE - Possible obfuscationline 188
const _rli = '<U+2067>'; // RIGHT-TO-LEFT ISOLATE - Possible obfuscationline 189
const _fsi = '<U+2068>'; // FIRST STRONG ISOLATE (unknown direction) - Possible obfuscationline 190
const _pdi = '<U+2069>'; // POP DIRECTIONAL ISOLATE - Network accessline 292
- Flutter internationalization: https://docs.flutter.dev/ui/accessibility-and-internationalization/internationalization - Network accessline 293
- gen-l10n / `l10n.yaml` options: https://docs.flutter.dev/ui/accessibility-and-internationalization/internationalization#configuring-the-l10nyaml-file - Network accessline 294
- ARB format: https://github.com/google/app-resource-bundle/wiki/ApplicationResourceBundleSpecification - Network accessline 295
- ICU `MessageFormat` (plural/select): https://unicode-org.github.io/icu/userguide/format_parse/messages/ - Network accessline 296
- CLDR plural rules: https://cldr.unicode.org/index/cldr-spec/plural-rules - Network accessline 297
- `intl` package (NumberFormat, DateFormat, Bidi): https://pub.dev/packages/intl - Network accessline 298
- Unicode Bidi Algorithm (UAX #9), isolate controls: https://www.unicode.org/reports/tr9/ - Network accessline 299
- `Directionality`, `EdgeInsetsDirectional`: https://api.flutter.dev/flutter/widgets/Directionality-class.html - Network accessline 300
- `LocalizationsDelegate` (vendoring one): https://api.flutter.dev/flutter/widgets/LocalizationsDelegate-class.html - Network accessline 301
- Supported locale list + adding an unsupported one: https://docs.flutter.dev/ui/accessibility-and-internationalization/internationalization#advanced-locale-definition - Network accessline 302
- OpenType `cmap` table (glyph coverage): https://learn.microsoft.com/en-us/typography/opentype/spec/cmap
skills/i18n-rtl-l10n/examples/directional_widget.dart
skills/i18n-rtl-l10n/references/rtl-and-bidi.md
- Possible obfuscationline 61
const _lri = '<U+2066>'; // U+2066 LEFT-TO-RIGHT ISOLATE - Possible obfuscationline 62
const _rli = '<U+2067>'; // U+2067 RIGHT-TO-LEFT ISOLATE - Possible obfuscationline 63
const _fsi = '<U+2068>'; // U+2068 FIRST STRONG ISOLATE - Possible obfuscationline 64
const _pdi = '<U+2069>'; // U+2069 POP DIRECTIONAL ISOLATE
skills/i18n-rtl-l10n/scripts/check_arb_parity.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/i18n-rtl-l10n/scripts/check_i18n_bans.sh
skills/lint-and-style-config/SKILL.md
- Network accessline 238
- Effective Dart: [Style](https://dart.dev/effective-dart/style) · - Network accessline 239
[Usage](https://dart.dev/effective-dart/usage) · - Network accessline 240
[Documentation](https://dart.dev/effective-dart/documentation) - Network accessline 241
- [Dart linter rules](https://dart.dev/tools/linter-rules) - Network accessline 242
- [`dart format`](https://dart.dev/tools/dart-format) - Network accessline 243
- [`dart analyze` / analysis_options](https://dart.dev/tools/analysis) - Network accessline 244
- [`very_good_analysis`](https://pub.dev/packages/very_good_analysis) · - Network accessline 245
[`flutter_lints`](https://pub.dev/packages/flutter_lints) - Network accessline 246
- [`riverpod_lint`](https://pub.dev/packages/riverpod_lint) · - Network accessline 247
[Riverpod: What's new in 3.0](https://riverpod.dev/docs/whats_new)
skills/lint-and-style-config/scripts/lint-gates.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/lint-and-style-config/scripts/verify-include-pin.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/local-notifications-scheduler/SKILL.md
- Network accessline 177
- flutter_local_notifications: https://pub.dev/packages/flutter_local_notifications - Network accessline 178
- Zoned scheduling & timezones: https://pub.dev/packages/flutter_local_notifications#scheduling-a-notification - Network accessline 179
- timezone package: https://pub.dev/packages/timezone - Network accessline 180
- flutter_timezone: https://pub.dev/packages/flutter_timezone - Network accessline 181
- Android exact alarms: https://developer.android.com/develop/background-work/services/alarms/schedule - Network accessline 182
- Android USE_EXACT_ALARM policy: https://support.google.com/googleplay/android-developer/answer/13161072 - Network accessline 183
- iOS UNUserNotificationCenter 64-notification limit: https://developer.apple.com/documentation/usernotifications/unusernotificationcenter - Network accessline 184
- package:clock: https://pub.dev/packages/clock
skills/local-notifications-scheduler/scripts/check-adhoc-schedule-calls.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/local-notifications-scheduler/scripts/check-manifest-permissions.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/local-notifications-scheduler/scripts/check-scheduler-purity.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/local-notifications-scheduler/scripts/check-single-fln-import.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/motion-and-haptics/SKILL.md
- Network accessline 200
- Flutter API — `HapticFeedback`: https://api.flutter.dev/flutter/services/HapticFeedback-class.html - Network accessline 201
- Flutter API — `SystemSound`: https://api.flutter.dev/flutter/services/SystemSound-class.html - Network accessline 202
- Flutter API — `MediaQueryData.disableAnimations`: https://api.flutter.dev/flutter/widgets/MediaQueryData/disableAnimations.html - Network accessline 203
- Flutter — animations overview: https://docs.flutter.dev/ui/animations - Network accessline 204
- Material 3 — motion: https://m3.material.io/styles/motion/overview - Network accessline 205
- Apple HIG — playing haptics: https://developer.apple.com/design/human-interface-guidelines/playing-haptics - Network accessline 206
- WCAG 2.2 — Animation from Interactions (2.3.3): https://www.w3.org/WAI/WCAG22/Understanding/animation-from-interactions.html
skills/naming-conventions/SKILL.md
- Network accessline 8
Consistent, role-carrying names make code searchable and self-explaining, and the suffix on a type declares which layer it lives in — so a reviewer, a `grep`, and a banned-import gate can all read the layer off the name alone. This skill is - Network accessline 132
- [Effective Dart: Style](https://dart.dev/effective-dart/style) — casing, file names, import ordering (normative). - Network accessline 133
- [Effective Dart: Design — naming](https://dart.dev/effective-dart/design) — booleans, getters vs. methods, verb/noun phrasing. - Network accessline 134
- [Dart linter rules](https://dart.dev/tools/linter-rules) — `constant_identifier_names`, `camel_case_types`, `file_names`, `directives_ordering`, `non_constant_identifier_names`.
skills/navigation-and-routing/SKILL.md
- Network accessline 153
- go_router package: https://pub.dev/packages/go_router - Network accessline 154
- go_router API docs: https://pub.dev/documentation/go_router/latest/ - Network accessline 155
- Flutter navigation & routing: https://docs.flutter.dev/ui/navigation - Network accessline 156
- Deep linking: https://docs.flutter.dev/ui/navigation/deep-linking - Network accessline 157
- PopScope API: https://api.flutter.dev/flutter/widgets/PopScope-class.html
skills/navigation-and-routing/scripts/check_routing.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/persistence-drift/SKILL.md
- Network accessline 218
- Drift docs: https://drift.simonbinder.eu/ - Network accessline 219
- Drift transactions: https://drift.simonbinder.eu/dart_api/transactions/ - Network accessline 220
- Drift migrations: https://drift.simonbinder.eu/Migrations/ - Network accessline 221
- SQLite STRICT tables: https://sqlite.org/stricttables.html - Network accessline 222
- SQLite WAL: https://sqlite.org/wal.html - Network accessline 223
- SQLite `VACUUM INTO`: https://sqlite.org/lang_vacuum.html#vacuuminto - Network accessline 224
- SQLite foreign keys (per-connection pragma): https://sqlite.org/foreignkeys.html - Network accessline 225
- `path_provider`: https://pub.dev/packages/path_provider
skills/persistence-drift/references/backup-and-wal.md
- Access to secretsline 112
[Credential-related source omitted]
skills/persistence-drift/scripts/check-drift-confinement.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/persistence-drift/scripts/check-persistence-bans.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/project-structure-and-packages/SKILL.md
- Network accessline 157
- Dart package layout: https://dart.dev/tools/pub/package-layout - Network accessline 158
- Dart & Flutter workspaces (`resolution: workspace`): https://dart.dev/tools/pub/workspaces - Network accessline 159
- Effective Dart — libraries & imports: https://dart.dev/effective-dart/usage#libraries - Network accessline 160
- pubspec format: https://dart.dev/tools/pub/pubspec - Network accessline 161
- Flutter architecture recommendations: https://docs.flutter.dev/app-architecture
skills/project-structure-and-packages/scripts/check_import_boundaries.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/project-structure-and-packages/scripts/check_structure.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/release-and-store-shipping/SKILL.md
- Network accessline 278
- Flutter — Build and release for Android: https://docs.flutter.dev/deployment/android - Network accessline 279
- Flutter — Build and release for iOS: https://docs.flutter.dev/deployment/ios - Network accessline 280
- Flutter — Obfuscating Dart code / `flutter symbolize`: https://docs.flutter.dev/deployment/obfuscate - Network accessline 281
- Flutter — Measuring your app's size: https://docs.flutter.dev/perf/app-size - Network accessline 282
- Android — Play App Signing: https://developer.android.com/studio/publish/app-signing - Network accessline 283
- Android — Merge multiple manifest files: https://developer.android.com/build/manage-manifests - Network accessline 284
- Google Play — Data safety form: https://support.google.com/googleplay/android-developer/answer/10787469 - Network accessline 285
- Apple — Privacy manifest files: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files
skills/release-and-store-shipping/references/android-play.md
skills/release-and-store-shipping/references/ios-app-store.md
- Dangerous shell operationline 40
flutter clean && rm -rf ~/Library/Developer/Xcode/DerivedData/Runner-*
skills/release-and-store-shipping/scripts/check-ipa-slices.sh
skills/release-and-store-shipping/scripts/check-release-hygiene.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/run-codegen/SKILL.md
- Network accessline 144
- build_runner: https://pub.dev/packages/build_runner - Network accessline 145
- Dart tools — build_runner usage: https://dart.dev/tools/build_runner - Network accessline 146
- drift codegen: https://drift.simonbinder.eu/docs/getting-started/ - Network accessline 147
- freezed: https://pub.dev/packages/freezed - Network accessline 148
- riverpod_generator: https://pub.dev/packages/riverpod_generator
skills/run-goldens-rebaseline/SKILL.md
- Network accessline 152
- Flutter — `matchesGoldenFile`: https://api.flutter.dev/flutter/flutter_test/matchesGoldenFile.html - Network accessline 153
- Flutter — `flutter test` options (`--update-goldens`, `--tags`): https://docs.flutter.dev/reference/flutter-cli - Network accessline 154
- Flutter — `GoldenFileComparator` / `LocalFileComparator`: https://api.flutter.dev/flutter/flutter_test/GoldenFileComparator-class.html - Network accessline 155
- `golden_toolkit` / `alchemist` — `loadAppFonts()`: https://pub.dev/packages/alchemist
skills/run-migration/SKILL.md
- Network accessline 325
- Drift — Migrations: https://drift.simonbinder.eu/Migrations/ - Network accessline 326
- Drift — Migration test API (`SchemaVerifier`, `make-migrations`): https://drift.simonbinder.eu/Migrations/tests/ - Drift — `stepByStep`: https://drift.simonbinder.eu/Migrations/step_by_step/ - Network accessline 327
https://drift.simonbinder.eu/Migrations/tests/ - Network accessline 328
- Drift — `stepByStep`: https://drift.simonbinder.eu/Migrations/step_by_step/ - Network accessline 329
- SQLite — `PRAGMA integrity_check` / `foreign_key_check`: https://sqlite.org/pragma.html - SQLite — Write-Ahead Logging: https://sqlite.org/wal.html - Network accessline 330
https://sqlite.org/pragma.html - Network accessline 331
- SQLite — Write-Ahead Logging: https://sqlite.org/wal.html
skills/scaffold-feature-module/SKILL.md
- Network accessline 242
- Flutter — Guide to app architecture: https://docs.flutter.dev/app-architecture - Network accessline 243
- Riverpod 3.x: https://riverpod.dev - Network accessline 244
- go_router — typed routes: https://pub.dev/documentation/go_router/latest/topics/Type-safe%20routes-topic.html - Network accessline 245
- Flutter — Internationalization (gen-l10n): https://docs.flutter.dev/ui/accessibility-and-internationalization/internationalization
skills/scaffold-feature-module/scripts/scaffold_feature.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/scaffold-feature-module/scripts/verify_feature.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/seeded-determinism-and-golden-vectors/SKILL.md
- Network accessline 226
- Dart API — `dart:math` `Random` (seeded construction): https://api.dart.dev/stable/dart-math/Random-class.html - Network accessline 227
- Dart — numbers on the web (`int` as JS double, `>>>`, overflow): https://dart.dev/guides/language/numbers - Network accessline 228
- Dart API — `identityHashCode`: https://api.dart.dev/stable/dart-core/identityHashCode.html - Network accessline 229
- FNV hash specification: https://datatracker.ietf.org/doc/html/draft-eastlake-fnv - Network accessline 230
- SplitMix64 (Steele, Lea, Flood — "Fast splittable pseudorandom number generators"): https://doi.org/10.1145/2660193.2660195 - Network accessline 231
- `package:test`: https://pub.dev/packages/test
skills/seeded-determinism-and-golden-vectors/scripts/check-determinism-bans.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/service-boundary-and-native/SKILL.md
- Network accessline 223
- Flutter — [Guide to app architecture](https://docs.flutter.dev/app-architecture/guide) and [Architecture recommendations](https://docs.flutter.dev/app-architecture/recommendations) (dependency injection strongly recommended). - Network accessline 224
- Flutter — [Build flavors (Android)](https://docs.flutter.dev/deployment/flavors) and [iOS build flavors](https://docs.flutter.dev/deployment/flavors-ios). - Network accessline 225
- Flutter — [Writing custom platform-specific code (MethodChannel)](https://docs.flutter.dev/platform-integration/platform-channels). - Network accessline 226
- Riverpod — [Testing your providers](https://riverpod.dev/docs/essentials/testing) and [What's new in Riverpod 3.0](https://riverpod.dev/docs/whats_new). - Network accessline 227
- pub.dev — [`clock`](https://pub.dev/packages/clock) (the `Clock`/`withClock` time seam), [`provider`](https://pub.dev/packages/provider), [`mocktail`](https://pub.dev/packages/mocktail) (one-off stubs only), [`home_widget`](https://pub.de
skills/service-boundary-and-native/scripts/check-flavor-graph.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/service-boundary-and-native/scripts/check-service-boundaries.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/state-management-riverpod/SKILL.md
- Network accessline 187
- [Riverpod docs](https://riverpod.dev) - Network accessline 188
- [Riverpod — Migrating to 3.0](https://riverpod.dev/docs/3.0_migration) - Network accessline 189
- [Flutter — App architecture guide (MVVM)](https://docs.flutter.dev/app-architecture/guide) - Network accessline 190
- [Flutter — Simple app state management](https://docs.flutter.dev/data-and-backend/state-mgmt/simple)
skills/state-management-riverpod/scripts/ban-legacy-providers.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/testing-strategy/SKILL.md
- Network accessline 280
- Flutter testing overview — https://docs.flutter.dev/testing/overview - Network accessline 281
- Riverpod testing — https://riverpod.dev/docs/essentials/testing - Network accessline 282
- Drift testing (NativeDatabase.memory) — https://drift.simonbinder.eu/docs/testing/ - Network accessline 283
- `package:clock` — https://pub.dev/packages/clock - Network accessline 284
- `package:fake_async` — https://pub.dev/packages/fake_async - Network accessline 285
- `package:mocktail` — https://pub.dev/packages/mocktail
skills/testing-strategy/scripts/check_test_hygiene.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/testing-strategy/scripts/run_tests.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/ui-states-and-feedback/SKILL.md
- Network accessline 264
- Material 3 — Snackbar: https://m3.material.io/components/snackbar/guidelines - Network accessline 265
- Material 3 — Banner (Material 2 spec, still the Flutter widget's basis): https://m2.material.io/components/banners - Network accessline 266
- Material 3 — Dialogs: https://m3.material.io/components/dialogs/guidelines - Network accessline 267
- Flutter — `ScaffoldMessenger`: https://api.flutter.dev/flutter/material/ScaffoldMessenger-class.html - Network accessline 268
- Flutter — `SemanticsService.announce`: https://api.flutter.dev/flutter/semantics/SemanticsService/announce.html - Network accessline 269
- Riverpod — `AsyncValue` (`when`, `skipLoadingOnRefresh`, `valueOrNull`): https://riverpod.dev/docs/essentials/async_initialization - Network accessline 270
- Nielsen Norman Group — Progress indicators and response times: https://www.nngroup.com/articles/response-times-3-important-limits/
skills/value-objects-money-and-units/SKILL.md
- Network accessline 311
- ISO 4217 currency exponents — https://en.wikipedia.org/wiki/ISO_4217 - Network accessline 312
- `package:decimal` — https://pub.dev/packages/decimal - Network accessline 313
- `package:clock` — https://pub.dev/packages/clock - Network accessline 314
- `fake_async` — https://pub.dev/packages/fake_async - Network accessline 315
- Largest-remainder (Hamilton) method — https://en.wikipedia.org/wiki/Largest_remainder_method - Network accessline 316
- Dart records & patterns — https://dart.dev/language/records
skills/value-objects-money-and-units/scripts/check-money-violations.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/value-objects-money-and-units/scripts/verify-core.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/widget-composition/SKILL.md
- Network accessline 204
- Flutter — [Performance best practices](https://docs.flutter.dev/perf/best-practices) (const constructors, minimize rebuilds, lazy builders) - Network accessline 205
- Flutter — [UI layer case study / dumb views](https://docs.flutter.dev/app-architecture/case-study/ui-layer) - Network accessline 206
- Flutter API — [`StatelessWidget`](https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html) · [`ListView.builder`](https://api.flutter.dev/flutter/widgets/ListView/ListView.builder.html) · [`EdgeInsetsDirectional`](https://api.f - Network accessline 207
- Riverpod — [Reading a provider / `ConsumerWidget`, `select`](https://riverpod.dev/docs/concepts/reading) - Network accessline 208
- Dart — [Effective Dart: Style](https://dart.dev/effective-dart/style) · [Linter rules](https://dart.dev/tools/linter-rules)
skills/widget-composition/scripts/check-widget-composition.sh
- Executable scriptline 1
#!/usr/bin/env bash
skills/widget-golden-and-a11y-testing/SKILL.md
- Network accessline 279
- Flutter — Widget testing introduction: https://docs.flutter.dev/cookbook/testing/widget/introduction - Network accessline 280
- Flutter API — `matchesGoldenFile` (OS/font/version sensitivity, `--update-goldens`): https://api.flutter.dev/flutter/flutter_test/matchesGoldenFile.html - Network accessline 281
- Flutter API — `WidgetTester` / `TestFlutterView`: https://api.flutter.dev/flutter/flutter_test/WidgetTester-class.html - Network accessline 282
- Flutter — Accessibility guidelines / `meetsGuideline`: https://api.flutter.dev/flutter/flutter_test/AccessibilityGuideline-class.html - Network accessline 283
- Flutter — Semantics matchers (`isSemantics`, `matchesSemantics`): https://api.flutter.dev/flutter/flutter_test/matchesSemantics.html - Network accessline 284
- `alchemist` — golden testing (`loadAppFonts`, CI vs platform lanes): https://pub.dev/packages/alchemist - Network accessline 285
- WCAG 2.2 contrast (1.4.3 / 1.4.6) and APCA: https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html
skills/widget-golden-and-a11y-testing/scripts/check-test-hygiene.sh
- Executable scriptline 1
#!/usr/bin/env bash
How the signals fit together
Facts from a static read of the files at the pinned commit. They describe what the code does, not why.
Some files could not be read; the facts below still hold.
Hidden characters: 9 facts
- Text direction control U+2066, in codei18n-rtl-l10n/SKILL.md:187High confidence
- Text direction control U+2067, in codei18n-rtl-l10n/SKILL.md:188High confidence
- Text direction control U+2068, in codei18n-rtl-l10n/SKILL.md:189High confidence
- Text direction control U+2069, in codei18n-rtl-l10n/SKILL.md:190High confidence
- Text direction control U+2066, in codei18n-rtl-l10n/references/rtl-and-bidi.md:61High confidence
- Text direction control U+2067, in codei18n-rtl-l10n/references/rtl-and-bidi.md:62High confidence
- Text direction control U+2068, in codei18n-rtl-l10n/references/rtl-and-bidi.md:63High confidence
- Text direction control U+2069, in codei18n-rtl-l10n/references/rtl-and-bidi.md:64High confidence
- Text direction control U+202A, in codei18n-rtl-l10n/scripts/check_i18n_bans.sh:50High confidence
Signal confidence: 323 facts
- Network access in prose of the SKILL.mdaccessibility-as-code/SKILL.md:213Low confidence
- Network access in prose of the SKILL.mdaccessibility-as-code/SKILL.md:214Low confidence
- Network access in prose of the SKILL.mdaccessibility-as-code/SKILL.md:215Low confidence
- Network access in prose of the SKILL.mdaccessibility-as-code/SKILL.md:216Low confidence
- Network access in prose of the SKILL.mdaccessibility-as-code/SKILL.md:217Low confidence
- Network access in prose of the SKILL.mdaccessibility-as-code/SKILL.md:218Low confidence
- Network access in prose of the SKILL.mdadaptive-layout/SKILL.md:163Low confidence
- Network access in prose of the SKILL.mdadaptive-layout/SKILL.md:164Low confidence
- Network access in prose of the SKILL.mdadaptive-layout/SKILL.md:165Low confidence
- Network access in prose of the SKILL.mdadaptive-layout/SKILL.md:166Low confidence
- Network access in prose of the SKILL.mdadaptive-layout/SKILL.md:167Low confidence
- Network access in prose of the SKILL.mdadaptive-layout/SKILL.md:168Low confidence
- Executable script in code of a file that runsadaptive-layout/scripts/check_adaptive.sh:1High confidence
- Network access in prose of the SKILL.mdads-and-iap-monetization/SKILL.md:228Low confidence
- Network access in prose of the SKILL.mdads-and-iap-monetization/SKILL.md:229Low confidence
- Network access in prose of the SKILL.mdads-and-iap-monetization/SKILL.md:230Low confidence
- Network access in prose of the SKILL.mdads-and-iap-monetization/SKILL.md:231Low confidence
- Network access in prose of the SKILL.mdads-and-iap-monetization/SKILL.md:232Low confidence
- Network access in prose of the SKILL.mdads-and-iap-monetization/SKILL.md:233Low confidence
- Network access in prose of the SKILL.mdads-and-iap-monetization/SKILL.md:234Low confidence
- Executable script in code of a file that runsads-and-iap-monetization/scripts/check-release-ad-ids.sh:1High confidence
- Network access in prose of the SKILL.mdapp-startup-and-bootstrap/SKILL.md:215Low confidence
- Network access in prose of the SKILL.mdapp-startup-and-bootstrap/SKILL.md:216Low confidence
- Network access in prose of the SKILL.mdapp-startup-and-bootstrap/SKILL.md:217Low confidence
- Network access in prose of the SKILL.mdapp-startup-and-bootstrap/SKILL.md:218Low confidence
- Network access in prose of the SKILL.mdapp-startup-and-bootstrap/SKILL.md:219Low confidence
- Network access in prose of the SKILL.mdasync-safety/SKILL.md:244Low confidence
- Network access in prose of the SKILL.mdasync-safety/SKILL.md:245Low confidence
- Network access in prose of the SKILL.mdasync-safety/SKILL.md:246Low confidence
- Network access in prose of the SKILL.mdasync-safety/SKILL.md:247Low confidence
- Network access in prose of the SKILL.mdasync-safety/SKILL.md:248Low confidence
- Network access in prose of the SKILL.mdasync-safety/SKILL.md:249Low confidence
- Network access in prose of the SKILL.mdci-pipeline-and-gates/SKILL.md:198Low confidence
- Network access in prose of the SKILL.mdci-pipeline-and-gates/SKILL.md:199Low confidence
- Network access in prose of the SKILL.mdci-pipeline-and-gates/SKILL.md:200Low confidence
- Network access in prose of the SKILL.mdci-pipeline-and-gates/SKILL.md:201Low confidence
- Network access in prose of the SKILL.mdci-pipeline-and-gates/SKILL.md:202Low confidence
- Network access in prose of the SKILL.mdci-pipeline-and-gates/SKILL.md:203Low confidence
- Network access in prose of the SKILL.mdci-pipeline-and-gates/SKILL.md:204Low confidence
- Network access in prose of documentationci-pipeline-and-gates/references/policy-grep-gate.md:64Low confidence
- Network access in prose of documentationci-pipeline-and-gates/references/policy-grep-gate.md:65Low confidence
- Dangerous shell operation in code of documentationci-pipeline-and-gates/references/workflow-skeleton.md:71Low confidence
- Executable script in code of a file that runsci-pipeline-and-gates/scripts/banned-strings.sh:1High confidence
- Executable script in code of a file that runsci-pipeline-and-gates/scripts/ci-gates.sh:1High confidence
- Network access in prose of the SKILL.mdcodegen-and-toolchain/SKILL.md:185Low confidence
- Network access in prose of the SKILL.mdcodegen-and-toolchain/SKILL.md:186Low confidence
- Network access in prose of the SKILL.mdcodegen-and-toolchain/SKILL.md:187Low confidence
- Network access in prose of the SKILL.mdcodegen-and-toolchain/SKILL.md:188Low confidence
- Network access in prose of the SKILL.mdcodegen-and-toolchain/SKILL.md:189Low confidence
- Network access in prose of the SKILL.mdcodegen-and-toolchain/SKILL.md:190Low confidence
and 273 more
Works with
| Agent | Status | Evidence | Install to |
|---|---|---|---|
| Claude Code | Native | Manifest .claude-plugin/marketplace.json | .claude/skills/<skill-name>/ |
| Codex | Native | Manifest AGENTS.md | .agents/skills/<skill-name>/ |
| Cursor | Compatible | Standard SKILL.md skills/accessibility-as-code/SKILL.md | .cursor/skills/<skill-name>/ |
| Gemini CLI | Compatible | Standard SKILL.md skills/accessibility-as-code/SKILL.md | .gemini/skills/<skill-name>/ |
| GitHub Copilot | Compatible | Standard SKILL.md skills/accessibility-as-code/SKILL.md | .github/skills/<skill-name>/ |
| OpenCode | Compatible | Standard SKILL.md skills/accessibility-as-code/SKILL.md | .opencode/skills/<skill-name>/ |
- Native The repository ships a manifest, folder or frontmatter field for this agent.
- Compatible A standard SKILL.md that this agent can read.
- Unknown No evidence either way.
Derived automatically from paths, manifests and frontmatter. Not tested on each agent.