# Flutter Agent Kit

> This skill provides general Flutter/Dart development guidance - implementing features, fixing bugs, managing pubspec dependencies and version constraints, following effective_dart, structuring lib/ (feature-first architecture, state management selection), writing platform channels for plugins across Android/iOS/Linux/macOS/Windows/Web/OpenHarmony, running flutter analyze/flutter test, and publish…

- **Type:** Skill
- **Install:** `agentstack add skill-zero-labsco-flutter-agent-kit-flutter-agent-kit`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [zero-labsco](https://agentstack.voostack.com/s/zero-labsco)
- **Installs:** 0
- **Category:** [Developer Tools](https://agentstack.voostack.com/c/developer-tools)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [zero-labsco](https://github.com/zero-labsco)
- **Source:** https://github.com/zero-labsco/flutter-agent-kit
- **Website:** https://flutter-agent-kit.vercel.app

## Install

```sh
agentstack add skill-zero-labsco-flutter-agent-kit-flutter-agent-kit
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Flutter Agent Kit

> **Self-contained bundle (v1.0.0).** This `SKILL.md` is an auto-generated, complete copy
> of the guidance from [`AGENTS.md`](https://github.com/zero-labsco/flutter-agent-kit/blob/main/AGENTS.md) and the docs
> in `references/` (the canonical sources in this kit's repository root). It is
> bundled so the skill works on its own even when a marketplace (e.g. skills.sh)
> downloads only `SKILL.md`. The helper scripts (`scripts/`) are NOT included in
> this download — clone the repo at https://github.com/zero-labsco/flutter-agent-kit to run them.
>
> **Tool-agnostic.** This skill loads via `SKILL.md` in any agent that supports
> the format — Claude Code, Cursor, Codex, GitHub Copilot, CodeBuddy, OpenCode,
> Aider, and any other tool skills.sh or a compatible marketplace targets.
> Follow the guidance below for any Flutter / Dart task regardless of which tool
> you use.

## Overview
This skill activates for any Flutter / Dart project work. The guidance below is
the tool-agnostic, bundled core: architecture, coding conventions, dependency
and version rules, plugin platform-channel patterns, verification commands, and
the deep-dive reference appendices.

## General guidance (bundled from AGENTS.md)

## Scope
Applies to **any** Flutter / Dart project, covering two scenarios:
- **Application projects** — UI apps with `lib/`, state management, networking, persistence.
- **Plugin projects** — packages exposing a platform channel for Android/iOS (and beyond).

**In scope (this kit owns these):** general Flutter / Dart conventions, `lib/`
structure, architecture pattern selection, dependency and version rules,
platform-channel patterns, verification commands, and the anti-AI-smell /
anti-hallucination discipline. These are tool-agnostic and apply to every project.

**Out of scope (this kit does NOT own these):** project-specific decisions and
facts — exact package names and versions, business/domain logic, directory depth
and folder naming beyond the recommended layouts, CI/CD configs, secrets, and any
rule that is unique to one repo. Those belong in the **project's own `AGENTS.md`**
(or its team docs), which should override this kit when they conflict. When a
project already has an established convention, follow it (see *Match the existing
codebase, not a template*) and do not impose this kit's defaults.

## Uncertainty handling (say so instead of guessing)
When you are **not certain** about a fact — an API's existence or signature, a
package's export, the project's intended behavior, a version's compatibility — do
**not** fabricate a plausible-looking answer. Instead:
- **State the uncertainty explicitly.** Say "I can't verify X from the available
  context" rather than emitting a confident-but-unchecked symbol or snippet.
- **Point to where to verify.** Name the source to check: `dart doc`, the package
  source in `pubspec.lock`, `pub.dev`, the project's own code/docs, or
  `flutter analyze` to surface errors. See *API truthfulness*.
- **Prefer a safe, minimal stub over a wrong implementation.** If you must
  proceed, write the smallest correct shape you can defend and flag what needs
  confirmation, instead of guessing parameters or methods.
- **Ask when the cost of being wrong is high** (data loss, breaking changes,
  auth/security). A short clarifying question beats a silent wrong assumption.

## Coding conventions
- Follow `effective_dart`. Enforce with `flutter analyze` and `flutter_lints`.
- Use null safety; avoid `!` unless proven safe. Prefer `final` and immutable models.
- Name files `snake_case.dart`, classes `PascalCase`, constants `lowerCamelCase` or `kConstant`.
- Keep `lib/` free of business logic leakage into UI; separate data / domain / presentation.
- Do not write hardcoded secrets; use `--dart-define` or a `.env` excluded from VCS.
- Do not **hardcode theme values**. Do **not** create a color-constants file
  (e.g. `app_colors.dart` with `static const brand = Color(0xFF2E5BFF)`) — that
  only relocates hardcoded colors and still can't adapt to light/dark or brand
  swaps. Instead:
  - Define the palette **once** in the app's `ThemeData`, derived from a single
    seed color via `ColorScheme.fromSeed(seedColor: ...)`. Let Flutter generate
    the shades (primary, surface, error, …) for you.
  - In widgets, read everything from the theme at runtime — `Theme.of(context)
    .colorScheme.primary`, `.textTheme.titleLarge`, `.colorScheme.error` — never
    literal `Color(0xFF...)`, `Colors.x`, or magic pixel numbers inline.
  - The only acceptable exception is a project that already ships its own
    design-token system wired into the theme (light/dark aware); then import those
    tokens, don't invent new hardcoded ones. This keeps the look consistent and
    themeable. See the UI guidance.

## Dependencies and versioning
- Prefer the caret (`^`) constraint on pub dependencies; do not pin exact versions without reason.
- Keep `sdk` constraints realistic (e.g. `>=3.0.0 /{data,domain,presentation}/`.
- Or a **layer-first** layout for small apps: `lib/data/`, `lib/domain/`, `lib/presentation/`.
- Choose state management deliberately: `Provider`/`Riverpod` for scoped DI, `Bloc`/`Cubit` for event-driven flows, `GetIt` for service locators. Document the choice in the project README.
- **Default when unchosen:** if the project has no established state-management
  approach, recommend **Riverpod** (or `Provider` for very small apps) as the
  default — low boilerplate, scoped DI, and strong testability. Only pick
  `Bloc`/`Cubit` when the flow is genuinely event-driven and benefits from
  explicit states. Pick ONE primary approach and document it.
- Never import `lib/src/` of a dependency directly; use its public API only.
- **Read existing code before generating.** Imitate the project's established
  patterns (file layout, naming, error handling, state shape) rather than emitting
  a generic template. Code that looks identical across every project is the
  tell-tale sign of an LLM — match the repo's voice.
- **Verify APIs before using them** (see *API truthfulness*). Never assume a
  method/constructor/parameter or package export exists — confirm it in the
  pinned SDK/package version.

## Componentization & reuse (reduce duplication)
Prefer **composable, reusable components** over copy-pasted UI and logic. Aim to
remove duplication wherever the same markup or behavior appears more than once:
- **Extract before repeating.** The first time you write a block of UI, leave it
  inline. The **second** time the same structure appears, extract it into a
  named widget / helper / function. Three or more repetitions of near-identical
  code is a strong signal to refactor into a shared component.
- **Build a small shared component set.** Colocate genuinely reusable widgets
  (buttons, cards, inputs, headers, empty/error states, list rows) in
  `lib//presentation/widgets/` or a cross-feature `lib/shared/`
  (or `lib/common/`, `lib/components/`) following the project's existing
  convention. Give them clear, single-purpose names — not `MyWidget`.
- **Parameterize, don't fork.** When two usages differ only by data, color, or
  callback, pass them as parameters instead of duplicating the widget with
  hardcoded variants. Prefer `const` constructors and a small set of named
  arguments over long positional lists.
- **Prefer composition over inheritance.** Compose small widgets (a `Card` +
  `ListTile` + `Icon`) rather than subclassing to reuse a look. Flutter widgets
  are cheap to nest; levers like `Builder`, `LayoutBuilder`, and `InheritedWidget`
  / provider reads share behavior without copying code.
- **Reuse logic, not just markup.** Lift repeated business rules, formatting,
  validation, and parsing into services / extensions / free functions in
  `domain` or `core/utils`; don't re-implement the same `if` chain in three
  screens. Share state via the chosen state-management container instead of
  duplicating fetches.
- **Match the project's existing components first.** Before adding a new shared
  widget, check whether one already exists (search `lib/shared`, `lib/common`,
  existing `*_widget.dart`). Reuse the repo's own building blocks so the UI stays
  consistent — do not introduce a second, parallel component library.
- **Keep components self-contained and dependency-light.** A shared widget should
  not reach into a specific feature's state or data layer; pass what it needs via
  the constructor. That keeps it reusable and avoids accidental coupling.
- **Don't over-abstract.** Extract a component only when it earns its place (two+
  real call sites, or a genuinely shared cross-feature need). A one-off widget
  pulled into `shared/` prematurely adds indirection with no payoff.

## Navigation & routing (avoid inline routes)
- **Don't inline `Navigator.push(MaterialPageRoute(...))` blocks** inside widgets.
  That scatters destinations and the page-construction logic across the codebase.
- **Use a centralized router** when the project has one — `go_router`,
  `auto_route`, or the project's own `RouteGenerator`. If the project has no
  convention, recommend `go_router` (declarative, typed routes, deep-linking) as
  the default for new apps.
- **Keep routes in one module, not scattered.** Define the router in a dedicated
  location rather than inside `main.dart` or individual pages:
  - Small apps: a single `lib/router.dart` (or `lib/app_router.dart`) holding the
    `GoRouter`/`RouterConfig` instance.
  - Larger / multi-feature apps: a `lib/router/` (or `lib/routing/`) folder with
    the router, route table, and guards split out (e.g. `app_router.dart`,
    `routes.dart`, `guards.dart`).
- **Define path strings as constants.** Don't write magic route strings like
  `context.go('/users/123')` across widgets — centralize them (e.g.
  `route_paths.dart` with `static const users = '/users';` and a typed
  `usersDetail(String id)` helper) so destinations have one source of truth.
- **Pass typed arguments, not raw Maps/strings.** Route params should be typed
  (e.g. `GoRouterState.pathParameters['id']` parsed to the real type), not a
  loosely-typed `Map` passed through constructors.
- **Match the project's existing navigation** before introducing a new approach.
  If screens currently use named routes or a specific package, stay consistent.

## Architecture (plugin)
- Define the abstract API once in `lib/_platform_interface.dart` (`Platform`).
- Provide a concrete impl per target platform: `MethodChannel` for Android / iOS / macOS / Linux / Windows / OpenHarmony (鸿蒙), and pure-Dart `dart:js_interop` for Web (no MethodChannel).
- Register the right impl conditionally (use `kIsWeb` + `dart:io` `Platform.isX`) in the public barrel; re-export public symbols only. Consumers call the abstract API and never change when a platform is added.
- Keep native changes minimal and matching the method-channel contract. Android lives under `android/src/main/kotlin/...`, iOS/macOS under `ios/Classes` / `macos/Classes`, Linux/Windows under `linux/` / `windows/` (C++), OHOS under `ohos/` (ArkTS).
- See the **Plugin Platform Channel Reference** appendix below for a full multi-platform template.

## Testing discipline
Generated code should be **accompanied by tests**, not shipped alone:
- **Write a test for every non-trivial change.** A new use case, repository
  method, formatter, or validation rule gets a unit test. A new screen or flow
  gets at least one widget/integration test covering the critical path.
- **Test by layer** (see *Testing layering* in the Architecture Reference):
  `domain` as pure unit tests; `data` with mocked sources (verify mapping and
  error handling); `presentation` with widget tests for key flows and
  integration tests for end-to-end.
- **Make it runnable and green.** After generating, the project must pass
  `flutter analyze` and `flutter test` (or `dart analyze` / `dart test` for
  non-Flutter packages). Do not leave failing or commented-out tests behind.
- **Prefer meaningful assertions** over "does not throw". Assert behavior and
  state, not just that the code executed.
- **Match the project's existing test style** (test framework, mocking library,
  file location `test/` vs `*/test/`) before introducing a new pattern.

## Dependency discipline
Adding a package is a decision, not a reflex:
- **Confirm the need first.** Before adding a dependency, check whether the SDK
  or an existing package already covers the use case (e.g. `dart:convert`,
  `dart:async`, `flutter/material.dart`). Prefer the standard library over a
  third-party package.
- **Audit the package before adding.** On `pub.dev`, check the **popularity +
  health + maintenance** scores, last published date, open issues, and null-safety
  / SDK compatibility. Avoid unmaintained or single-maintainer packages for
  critical functionality.
- **Avoid overlapping packages.** Don't add two packages that do the same thing
  (e.g. multiple HTTP clients, multiple state libraries). One chosen approach per
  concern.
- **Scope correctly.** Runtime needs go in `dependencies`; test/build tooling
  goes in `dev_dependencies`. Never commit a permanent `dependency_overrides`.
- **Pin with care** (see *Dependencies and versioning*): prefer caret (`^`)
  constraints; don't pin exact versions without reason.

## Error handling (fail loudly, recover gracefully)
Generated code should treat failures as first-class, not an afterthought:
- **Don't swallow exceptions.** Avoid bare `catch (e) {}` or `try { … } catch (_)`
  that discards the error. At minimum log it; rethrow or surface it when the
  caller can act on it.
- **Represent failure explicitly.** For operations that can fail, prefer throwing
  a typed exception or returning a `Result`/sealed type over returning `null` to
  mean "it broke". A `null` success/failure ambiguity is a common source of
  downstream crashes.
- **Use `async`/`await` + `try`/`catch`** for async work rather than nested
  `.then().catchError()` chains, which are harder to read and easy to leave
  unhandled.
- **Show the user a recoverable message, not a stack trace.** Map errors to a
  human-readable, localized string (see *Internationalization*) and offer a retry
  where it makes sense — using the project's existing error/empty-state pattern,
  not a generic dialog.
- **Catch at the right boundary.** Let lower layers (`data`/`domain`) throw and
  let the presentation layer decide how to present the failure, rather than
  catching and hiding it deep inside a repository.

## Internationalization (i18n)
- **Don't hardcode user-facing strings.** Extract them to `arb` files
  (`lib/l10n/app_en.arb`, `app_zh.arb`, …) via `flutter_localizations` +
  `intl` (or `slang`/`easy_localization` if the project already uses one).
- **Generate the delegate** (`flutter gen-l10n`) and wire `localizationsDelegates`
  + `supportedLocales` in `MaterialApp`/`CupertinoApp`. Follow the project's
  chosen i18n tool, not a new one.
- **Keep plurals/formatting in the arb**, not in Dart string concatenation, so
  translators and locale rules are respected.
- **Never convey meaning by UI text alone** for accessibility — pair labels with
  icons/semantics as noted in the UI guidance.

## Verification commands (run locally before pushing)
- `dart format --line-length 80 .` (or `flutter format`) — must report no
  unformatted files. Run formatting before analyze; never hand-format around the
  formatter.
- `flutter analyze` — must pass with no errors.
- `flutter test` — all unit tests green.
- `flutter pub publish --dry-run` — confirm `pana` score and no excluded files.

## Helper scripts
Located in `scripts/dart/` (Dart, cross-platform, runs on the Dart SDK every Flutter
dev already has) and `scripts/python/` (Python, for environments without the Dart
SDK). Both implement the same behavior and CLI; pick whichever fits your environment.

Run Dart with `dart run scripts/dart/.dart [args]`, or Python with
`python scripts/python/.py [args]` (o

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [zero-labsco](https://github.com/zero-labsco)
- **Source:** [zero-labsco/flutter-agent-kit](https://github.com/zero-labsco/flutter-agent-kit)
- **License:** MIT
- **Homepage:** https://flutter-agent-kit.vercel.app

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-zero-labsco-flutter-agent-kit-flutter-agent-kit
- Seller: https://agentstack.voostack.com/s/zero-labsco
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
