SkillAtlasSkill 详情

dart-3-updates

36 Flutter and Dart skills your coding agent loads by itself, sourced only from official documen...

审核状态:已审核Quality 80Security 88

复制安装命令

用 Codex 或 Claude 安装复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它先审查 Skill 页面再帮你安装。

复制前请先查看来源、License 和安全提示。

项目 README

来源文件:README.md

抓取于 2026年8月25日

Flutter AI Skills for Claude Code, Codex, Cursor, Antigravity, and Other AI Coding Agents

An agent prompt reading "Add Google sign-in to the profile screen" on the left; on the right, the firebase-auth and flutter-app-architecture skills are auto-selected from a list of dozens

36 Flutter and Dart skills your coding agent loads by itself, sourced only from official documentation.

A skill is a folder with a SKILL.md file. Your agent reads the description, decides a task matches, and pulls in the guidance — you don't paste anything into a rules file or remember to @-mention a doc. Install once, and Firebase Auth guidance shows up when you touch auth, Riverpod guidance when you touch providers.

A comprehensive, (almost) non-opinionated collection: everything here is derived from official Flutter, Dart, Firebase, and package documentation. No personal preferences, no invented conventions.

⚡ Quick start

npx skills add evanca/flutter-ai-rules

That's it. The Skills CLI discovers the packages under skills/ and installs them for supported agents.

Browse before installing, or take just one:

npx skills add evanca/flutter-ai-rules --list
npx skills add evanca/flutter-ai-rules --skill flutter-best-practices

Install as a plugin

This repo is also a plugin marketplace, so agents that support plugins can install the whole set and keep it updated in place. The manifests live at .claude-plugin/, .codex-plugin/, .cursor-plugin/, .agents/plugins/, and plugin.json — all pointing at the same skills/ directory.

Claude Code — plugin marketplaces:

/plugin marketplace add evanca/flutter-ai-rules
/plugin install flutter-ai-skills@flutter-ai-rules

Skills then load as flutter-ai-skills:bloc, flutter-ai-skills:riverpod, and so on.

Codex — plugins:

codex plugin marketplace add evanca/flutter-ai-rules
codex plugin install flutter-ai-skills@flutter-ai-rules

Cursor — plugins: in Cursor, run /add-plugin, or add the repo as a team marketplace under Dashboard → Settings → Plugins → Import from Repo:

https://github.com/evanca/flutter-ai-rules

Antigravity — plugins:

git clone --depth 1 https://github.com/evanca/flutter-ai-rules.git
agy plugin install ./flutter-ai-rules

Windsurf / Devin has no plugin manifest, but Cascade already scans .agents/skills/ and ~/.agents/skills/, so the manual copy below is the install path. GitHub Copilot doesn't read SKILL.md at all — see Rules and combined sets for what to use instead.

Prefer to do it by hand? Copy or symlink any skill folder into your agent's skills directory — .claude/skills/, .cursor/skills/, .codex/skills/, .agents/skills/ (Antigravity, Codex, Windsurf), .windsurf/skills/. Or vendor the whole set into your project:

git clone --depth 1 https://github.com/evanca/flutter-ai-rules.git temp_repo && mkdir -p .skills && cp -r temp_repo/skills/* .skills && rm -rf temp_repo

With a .skills/ folder you can also reference a skill explicitly when you want it: "Read @.skills/bloc/SKILL.md and create test coverage for the new methods."

🧠 What's in the box

Flutter and Dart foundations

SkillLoads when you're…
flutter-best-practicesWriting, reviewing, or planning Flutter code
effective-dartWriting Dart, naming things, adding doc comments
dart-3-updatesUsing records, patterns, sealed classes, switch expressions
flutter-app-architectureScaffolding a project or refactoring into layers
architecture-feature-firstDesigning folder structure for a new feature
flutter-errorsHitting RenderFlex overflows, unbounded constraints, layout errors
flutter-use-column-row-firstBuilding responsive layouts with Row, Column, Expanded, Flexible
flutter-pre-cachingPreloading fonts, images, animations, or config

State management

SkillLoads when you're…
blocCreating a Cubit or Bloc, modeling state, wiring providers
riverpodSetting up providers, combining requests, managing disposal
providerConsuming state, optimizing rebuilds, using ProxyProvider
flutter-change-notifierSetting up ChangeNotifier models and consuming them

Testing and review

SkillLoads when you're…
testingWriting unit, widget, or golden tests; fixing flaky tests
mockitoGenerating mocks, stubbing, verifying interactions
mocktailMocking without codegen, registering fallback values
patrol-e2e-testingWriting E2E tests that touch native permissions or dialogs
code-reviewReviewing a PR, branch, or diff

Firebase

SkillLoads when you're…
flutterfire-configureAdding Firebase to a project, running flutterfire configure
firebase-authSetting up auth, managing auth state, social sign-in
firebase-cloud-firestoreDesigning schemas, CRUD, listeners, pagination
firebase-databaseSyncing real-time data, structuring JSON trees
firebase-storageUploading and downloading files, managing metadata
firebase-analyticsLogging events, setting user properties
firebase-crashlyticsCapturing fatal and non-fatal errors
firebase-messagingSetting up FCM, handling background messages
firebase-in-app-messagingRunning in-app campaigns
firebase-remote-configImplementing feature flags or A/B tests
firebase-app-checkConfiguring attestation and debug tokens
firebase-cloud-functionsCalling callable functions, handling errors
firebase-aiGenerating text or chat with Gemini via firebase_ai
generate-images-with-firebase-aiGenerating or editing images with a Gemini image model (Nano Banana)
firebase-data-connectWriting GraphQL queries against Data Connect

Shipping and product

SkillLoads when you're…
accessibilityWorking on a11y, WCAG, screen readers, focus order
inclusive-designHandling i18n, global name/address forms, low-end devices
store-listing-assetsWriting store copy to character limits
revenuecat-testingTesting purchases, subscriptions, sandbox flows
developing-genkit-dartBuilding AI agents in Dart with Genkit

🗂️ Rules and combined sets (legacy)

Before skills existed, this repo shipped rule files you pasted into a config, plus pre-merged bundles squeezed under Windsurf's character cap. Both still work and both are still updated, but skills are the recommended path — they load contextually instead of consuming your context window on every request.

Reach for these only if your tool has no skills support, or you want one static file you fully control:

  • rules/ — six broad foundation files: effective_dart.md, flutter_app_architecture.md, flutter_errors.md, dart_3_updates.md, testing.md, code_review.md. Drop them in your project and reference them by name: "Read @rules/effective_dart.md and follow its conventions." Package-specific guidance (Bloc, Riverpod, Firebase, Mockito…) is skills-only now.
  • combined/ — seven topic bundles, each in a full and an __under_6K variant. Paste one into your global or local rules config and you're done. The trimmed variants stay under 6,000 characters to fit Windsurf's global_rules.md hard limit.

GitHub Copilot lives here rather than in the skills section, because it has no SKILL.md support. Three options, in the order Copilot documents them:

  • Copy a combined/ bundle to .github/copilot-instructions.md for repo-wide guidance.
  • Copy rules/ files into .github/instructions/ as <name>.instructions.md, each with applyTo: "**/*.dart" frontmatter, so they only load for Dart files.
  • Copilot also reads a root AGENTS.md, so a bundle pasted there works for Copilot, Codex, and Antigravity at once.

📏 Recommended file sizes by tool

Size guidance from each tool's own official documentation, for rule/instruction files and for SKILL.md files (accessed 2026-07-11).

ToolRule file — recommended sizeSKILL.md — recommended size
Claude CodeCLAUDE.md: under 200 lines (soft)Under 500 lines (soft); description 1,536 chars (hard)
Cursor.mdc rule: under 500 lines (soft)No numeric limit — "keep focused, move detail to separate files"
OpenAI CodexAGENTS.md: no limit statedSkill bundle: zip ≤ 50 MB, uncompressed file ≤ 25 MB, ≤ 500 files/version (no per-SKILL.md text limit)
Google Antigravityrule file: 12,000 chars each (hard)No numeric limit stated
Windsurfglobal_rules.md: 6,000 chars; .windsurf/rules/*.md: 12,000 chars/file (hard)No numeric limit — "keeps your context window lean"
GitHub Copilotcopilot-instructions.md: ≤ 2 pages (soft, approx.)Not supported — no repo-level SKILL.md

Notes:

  • Hard = enforced/truncated at the limit; soft = a documented quality recommendation.
  • Only Claude Code publishes a numeric SKILL.md length recommendation (under 500 lines). Cursor, Windsurf, and Antigravity just say "keep it focused/lean" with no figure; OpenAI documents skill-bundle limits (50 MB zip / 25 MB per file / 500 files) rather than a text length; and GitHub Copilot has no repo-level SKILL.md — it uses copilot-instructions.md plus path-specific *.instructions.md (no size limit stated for the latter).
  • Claude Code loads CLAUDE.md in full regardless of length, but notes files over 200 lines "consume more context and reduce adherence"; its auto-memory MEMORY.md loads only the "first 200 lines or 25KB, whichever comes first."
  • Windsurf is still named Windsurf; its docs are served through Cognition (docs.windsurf.com → docs.devin.ai) and reference .windsurf/rules and .windsurf/skills.
  • This repo keeps the combined/ sets under 6,000 characters to satisfy the strictest hard limit above (Windsurf global_rules.md).

Official sources: Claude Code — memory · skills | Cursor — rules · skills | OpenAI Codex — AGENTS.md · skills | Google Antigravity — rules · skills | Windsurf — rules & skills | GitHub Copilot — instructions

📌 No opinions, just documentation

Every skill is sourced from official documentation — no personal preferences or subjective interpretations. That's intentional. You're free to alter them to taste, but this repo stays objective by sticking to the source.

One consequence worth knowing: skills can contradict each other, because their sources do. If one package recommends a folder layout and another recommends a different one, you'll see both.

Content is re-fetched from upstream docs on a schedule, so skills track the official guidance as it changes rather than freezing at whatever was true when they were written.

🛠️ Contributing

Contributions are welcome:

  1. Fork this repository.
  2. Add or modify a skill in skills/, or a rule in rules/.
  3. Open a pull request explaining the change.

Include an official documentation link for anything you add or change. That's the one hard requirement — it's what keeps the repo objective and reviewable. If your source isn't already listed in ATTRIBUTION.md, add it there with its license — and if that license isn't a permissive one, restate the guidance instead of quoting it.

📚 Sources

Official documentation these skills are built from:

Flutter — App Architecture · Common Errors · Simple State Management

Dart — Effective Dart · Language tour · Records · Patterns · Pattern types · Branches

State management — Bloc · Riverpod · Provider

Testing — Mockito · Mocktail · Patrol

Firebase — Firebase for Flutter · FlutterFire · Multiple flavors with the FlutterFire CLI

📄 License

MIT — for this repository's own content: the choice of topics, the trigger descriptions, and the wording and structure of every skill.

The underlying documentation keeps its own terms. Most of it is CC BY 4.0 (Flutter, Dart, Firebase), with code samples under BSD-3 or Apache 2.0, package READMEs under MIT or Apache 2.0, and a few sources — Apple, Google Play, RevenueCat — that aren't openly licensed and are therefore restated as fact rather than copied. ATTRIBUTION.md maps every source to its license and to the skills built on it.

If you redistribute this repo or lift a single skill out of it, keep the source links — that's what the CC BY attribution requirement actually asks for.

开发与工程数据与 AI内容与创作

中风险

  • 来源需自行核对维护者身份。
  • 未检测到明显脚本安装指令。
  • 未检测到明显外部权限要求。
  • 未检测到高风险命令。
  • 扫描发现:1 条。

Codex — Git Clone 安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 克隆仓库:git clone https://github.com/evanca/flutter-ai-rules.git
  3. 将 "skills/dart-3-updates" 文件夹复制到 Codex 的 skills 目录中。
  4. 重启 Codex 让新的 skill 生效。

Codex — 手动复制安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 从源仓库下载 SKILL.md 及相关文件。
  3. 在 Codex 的 skills 目录中创建新文件夹。
  4. 将所有 skill 文件复制到新文件夹中。
  5. 重启 Codex 让新的 skill 生效。

Claude Code — Git Clone 安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 克隆仓库:git clone https://github.com/evanca/flutter-ai-rules.git
  3. 将 "skills/dart-3-updates" 文件夹复制到 Claude Code 的 skills 目录中。
  4. 重启 Claude Code 让新的 skill 生效。

Claude Code — 手动复制安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 从源仓库下载 SKILL.md 及相关文件。
  3. 在 Claude Code 的 skills 目录中创建新文件夹。
  4. 将所有 skill 文件复制到新文件夹中。
  5. 重启 Claude Code 让新的 skill 生效。

Cursor — Git Clone 安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 克隆仓库:git clone https://github.com/evanca/flutter-ai-rules.git
  3. 将 "skills/dart-3-updates" 文件夹复制到 Cursor 的 skills 目录中。
  4. 重启 Cursor 让新的 skill 生效。

Cursor — 手动复制安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 从源仓库下载 SKILL.md 及相关文件。
  3. 在 Cursor 的 skills 目录中创建新文件夹。
  4. 将所有 skill 文件复制到新文件夹中。
  5. 重启 Cursor 让新的 skill 生效。

GitHub Copilot — Git Clone 安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 克隆仓库:git clone https://github.com/evanca/flutter-ai-rules.git
  3. 将 "skills/dart-3-updates" 文件夹复制到 GitHub Copilot 的 skills 目录中。
  4. 重启 GitHub Copilot 让新的 skill 生效。

GitHub Copilot — 手动复制安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 从源仓库下载 SKILL.md 及相关文件。
  3. 在 GitHub Copilot 的 skills 目录中创建新文件夹。
  4. 将所有 skill 文件复制到新文件夹中。
  5. 重启 GitHub Copilot 让新的 skill 生效。

Windsurf — Git Clone 安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 克隆仓库:git clone https://github.com/evanca/flutter-ai-rules.git
  3. 将 "skills/dart-3-updates" 文件夹复制到 Windsurf 的 skills 目录中。
  4. 重启 Windsurf 让新的 skill 生效。

Windsurf — 手动复制安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 从源仓库下载 SKILL.md 及相关文件。
  3. 在 Windsurf 的 skills 目录中创建新文件夹。
  4. 将所有 skill 文件复制到新文件夹中。
  5. 重启 Windsurf 让新的 skill 生效。
查看 SKILL.md 原文
name: dart-3-updates
description: "Use when writing switch statements, refactoring if-else chains, creating data classes, choosing records vs classes, destructuring values, or modernizing pre-Dart-3 code."
license: MIT

Dart 3 Updates Skill

Apply Dart 3 language features — branches, patterns, pattern types, and records — correctly and idiomatically.

When to Use

Use this skill when:

  • Writing or refactoring switch statements or if-else chains.
  • Creating new data-holding classes and deciding between sealed classes, records, or plain classes.
  • Destructuring values from maps, lists, records, or objects.
  • Modernizing pre-Dart-3 code to use patterns, exhaustiveness checks, or switch expressions.

1. Branches

if / if-case

// Standard if
if (score >= 90) {
  grade = 'A';
} else if (score >= 80) {
  grade = 'B';
} else {
  grade = 'C';
}

// if-case: match and destructure against a single pattern
if (pair case [int x, int y]) {
  print('$x, $y');
}
  • if conditions must evaluate to a bool.
  • In if-case, variables declared in the pattern are scoped to the matching branch.
  • If the pattern does not match, control flows to the else branch (if present).

switch statements

switch (command) {
  case 'quit':
    quit();
  case 'start' || 'begin': // logical-or pattern
    startGame();
  default:
    print('Unknown command');
}
  • Each matched case body executes and jumps to the end — break is not required.
  • Non-empty cases can end with continue, throw, or return.
  • Use default or _ to handle unmatched values.
  • Empty cases fall through; use break to prevent fallthrough in an empty case.
  • Use continue with a label for non-sequential fallthrough.
  • Use logical-or patterns (case a || b) to share a body between cases.

switch expressions

final color = switch (shape) {
  Circle() => 'red',
  Square() => 'blue',
  _ => 'unknown',
};
  • Omit case; use => for bodies; separate cases with commas.
  • Default must use _ (not default).
  • Produces a value.

Exhaustiveness

  • Dart checks exhaustiveness in switch statements and expressions at compile time.
  • Use default/_, enums, or sealed types to satisfy exhaustiveness.
sealed class Shape {}
class Circle extends Shape {}
class Square extends Shape {}

// Dart knows all subtypes — no default needed:
String describe(Shape s) => switch (s) {
  Circle() => 'circle',
  Square() => 'square',
};

Guard clauses

switch (point) {
  case (int x, int y) when x == y:
    print('Diagonal: $x');
  case (int x, int y):
    print('$x, $y');
}
  • Add when condition after a pattern to further constrain matching.
  • Usable in if-case, switch statements, and switch expressions.
  • If the guard is false, execution proceeds to the next case.

2. Patterns

Patterns represent the shape of a value for matching and destructuring.

Uses

// Variable declaration
var (a, [b, c]) = ('str', [1, 2]);

// Variable assignment (swap)
(b, a) = (a, b);

// for-in loop destructuring
for (final MapEntry(:key, :value) in map.entries) { ... }

// switch / if-case (see Branches section)
  • Wildcard _ ignores parts of a matched value.
  • Rest elements (...) in list patterns ignore remaining elements.
  • Case patterns are refutable: if no match, execution continues to the next case.
  • Destructured values in a case become local variables scoped to that case body.

Object patterns

var Foo(:one, :two) = myFoo;

JSON / nested data validation

if (data case {'user': [String name, int age]}) {
  print('$name, $age');
}

3. Pattern Types

PatternSyntaxDescription
Logical-orp1 || p2Matches if any branch matches. All branches must bind the same variables.
Logical-andp1 && p2Matches if both match. Variable names must not overlap.
Relational== c, < c, >= cCompares value to a constant. Combine with && for ranges.
Castsubpattern as TypeAsserts type, then matches inner pattern. Throws if type mismatch.
Null-checksubpattern?Matches non-null; binds non-nullable type.
Null-assertsubpattern!Matches non-null or throws. Use in declarations to eliminate nulls.
Constant42, 'str', const Foo()Matches if value equals the constant.
Variablevar name, final Type nameBinds matched value to a new variable. Typed form only matches the declared type.
Wildcard_, Type _Matches any value without binding.
Parenthesized(subpattern)Controls precedence.
List[p1, p2]Matches lists by position. Length must match unless a rest element is used.
Rest element..., ...restMatches arbitrary-length tails or collects remaining elements.
Map{'key': subpattern}Matches maps by key. Missing keys throw StateError.
Record(p1, p2), (x: p1, y: p2)Matches records by shape; field names can be omitted if inferred.
ObjectClassName(field: p)Matches by type and destructures via getters. Extra fields ignored.
  • Use parentheses to group lower-precedence patterns.
  • All pattern types can be nested and combined.

4. Records

// Create
var record = ('first', a: 2, b: true, 'last');

// Type annotation
({int a, bool b}) namedRecord;

// Access
print(record.$1);   // positional: 'first'
print(record.a);    // named: 2
  • Records are anonymous, immutable, fixed-size aggregates.
  • Each field can have a different type (heterogeneous).
  • Fields are accessed via built-in getters ($1, $2, .name); no setters.
  • Two records are equal if they have the same shape and equal field values.
  • hashCode and == are automatically defined.

Multiple return values

(String name, int age) userInfo(Map<String, dynamic> json) {
  return (json['name'] as String, json['age'] as int);
}

var (name, age) = userInfo(json);
// Named fields:
final (:name, :age) = userInfo(json);

Records vs. data classes

Use a record when:

  • Returning multiple values from a single function (small, one-time use).
  • Grouping a few values locally with no reuse across the codebase.
  • You need structural equality with no additional behavior.

Use a class when:

  • The type is reused across multiple files or features.
  • You need methods, encapsulation, inheritance, or copyWith.
  • The type is part of a public API or long-lived data model.
  • Changing the shape must be caught by the type system across the codebase.

Other best practices

  • Use typedef for record types to improve readability and maintainability.
  • Changing a record type alias does not guarantee type safety across the codebase — only classes provide full abstraction.

5. Migration Workflow

When modernizing pre-Dart-3 code, follow these steps:

Step 1 — Replace if-else chains with switch expressions

// Before (pre-Dart 3)
String label;
if (status == Status.loading) {
  label = 'Loading...';
} else if (status == Status.success) {
  label = 'Done';
} else {
  label = 'Error';
}

// After (Dart 3)
final label = switch (status) {
  Status.loading => 'Loading...',
  Status.success => 'Done',
  Status.error => 'Error',
};

Step 2 — Convert abstract class hierarchies to sealed classes

// Before
abstract class Result {}
class Success extends Result { final String data; Success(this.data); }
class Failure extends Result { final String error; Failure(this.error); }

// After — enables exhaustive switch
sealed class Result {}
final class Success extends Result { const Success(this.data); final String data; }
final class Failure extends Result { const Failure(this.error); final String error; }

Step 3 — Use destructuring for multiple return values

Replace wrapper classes used solely for returning multiple values with records.

Step 4 — Validate

Run dart analyze to confirm exhaustiveness and type safety after each change.


发现问题?提交给管理员复核

评分:

评论 (0)

暂无评论,成为第一个评论者吧!