mcpField
B
building-flutter-apps

building-flutter-apps

github.com/sgaabdu4开发25176 次安装3 天前更新
代码仓库

关于 building-flutter-apps

面向 Flutter 和 Dart 开发的 skill,按场景引导编码 Agent 查阅适用规范,并规定实现与检查流程。内容涵盖 Riverpod、架构、测试、无障碍和本地化。

主要功能

  1. 01按场景选择参考资料
  2. 02Flutter 与 Riverpod 编码规范
  3. 03架构与状态管理指导
  4. 04测试、无障碍和本地化规则
  5. 05文件修改后的预检流程

适用场景

  1. 01启动或修改 Flutter 应用
  2. 02实现 Riverpod 状态与异步操作
  3. 03检查界面、无障碍或导航改动

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sgaabdu4/building-flutter-apps --skill building-flutter-apps

安装后在 Claude Code 中输入/building-flutter-apps确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

agents/
openai.yaml
assets/
defender-installer-scan.ps1
inno-bundle-pubspec.yaml
inno-uninstall-settlement-sentinel.ps1
windows-installer-workflow.yml
references/
analysis_options.yaml
analysis-options.md
architecture.md
atomic-design.md
build-reproducibility.md
common-patterns.md
core-stack.md
dart-decimate.md
dart-mcp-e2e-testing.md
dart-patterns-records.md
deep-linking.md
error-reporting.md
flutter-optimizations.md
freezed-sealed.md
hive-persistence.md
references/atomic-design/
accessibility.md
references/common-patterns/
debounce-gate-batch.md
delta-sync.md
lists-forms-workflows.md
modals-navigation.md
navigation-flow.md
routing-app-shell.md
references/extensions/
collections-helpers.md
context-ui.md
primitive-formatting.md

详细介绍

先读

  • 本技能会覆盖通用的 Flutter/Dart 建议;关键规则优先于示例、公开文档和旧项目代码。
  • 每个参考的 先读 部分均为权威依据。
  • 每批写入 .dart/pubspec.yaml/build.yaml/analysis_options.yaml 后,请运行 Pre-Flight;其引用的规则/参考资料负责适用的检查。

渐进式披露门控

在编写代码前,只阅读匹配范围最窄的 Trigger Map 行;场景/子系统行负责涵盖偶然出现的技术栈/文件词汇。仅当没有匹配的场景行时,才阅读诸如 common-patterns.md 的父级参考;切勿批量读取 references/。在 Pre-Flight 中引用确切的参考。

关键规则

ID规则详情引用
R1Flutter/Riverpod 包 = 首先接入 flutter_skill_lints + riverpod_lint,然后在包根目录运行 dart analyze 及其项目自有的 Dart Decimate 检查;纯 Dart 命令行 = 使用原生 Dart 分析配置,两者插件都不引入。analysis-options.md, dart-decimate.md, setup.md
R2每个 provider 都使用 @riverpod / @Riverpod 代码生成;不允许手写 provider 类或旧式 provider 族。riverpod-codegen.md
R3用 ref.mounted / context.mounted 防护异步间隙;finally 使用 if (ref.mounted) { ... }。async-mutations.md
R4Widget 必须是公开类;除 State 外,不允许 _buildXxx()、widget 顶层辅助函数或私有 widget 类。atomic-design.md, performance.md
R5可空性是语义性的;不允许空值/null/bool 哨兵回退、value!、可空集合或裸的必填领域字符串。value-objects.md, freezed-sealed.md; Lints: domain_raw_required_string
R6所有面向用户的字符串、工具提示、语义和可见的无障碍文案都使用 AppLocalizations。localization.md, accessibility.md
R7不可变状态/实体使用 sealed Freezed,每个文件一个声明,使用原生 switch,并禁用 VO 的 map/when。freezed-sealed.md, value-objects.md
R8presentation/widgets/ 渲染不可变输入并发出类型化回调;屏幕/路由/notifier 负责导航、工作流、领域状态和基础设施。presentation-widgets.md
R92 个及以上类中的重复行为提取为带 on 子句的小型无状态 *Mixin。mixins.md
R10存储 SDK 调用位于仓储之后的本地数据源中;生产环境的 Hive 导入使用 hive_ce_flutter。hive-persistence.md, architecture.md
R11基础类型/context/集合操作位于 core/extensions/;领域层绝不导入这些扩展。context-ui.md, primitive-formatting.md, collections-helpers.md
R12具有含义的领域基础类型成为经过校验的 Freezed Value Object;Hive 模型保留基础类型,由映射器桥接。value-objects.md, hive-persistence.md; Lints: domain_unit_primitive
R13类型化的 GoRouter 路由是导航的 SSOT;重定向是纯解析器逻辑,并带可按 id 回退的可空 UI。deep-linking.md, routing-app-shell.md
R14对话框/底部面板渲染不可变快照、弹出结果,并将变更/清理交给 notifier。modals-navigation.md, state-management-lifecycle.md
R15对高频 UI、同步、持久化、远程函数、重置和查找边界进行防抖、门控和批处理。debounce-gate-batch.md
R16应用外壳保持声明式;引导监听器位于同级的根 ConsumerWidget 中。routing-app-shell.md
R17在退出之后保持控制流扁平;移除 return / throw / break / continue 之后不必要的 else。Lint: avoid_unnecessary_else_after_control_flow
R18直接使用 onReorderItem 移除后的索引;绝不添加旧式 onReorder 适配计算。Lint: use_on_reorder_item_index_semantics
R19Android 精确闹钟使用 flutter_local_notifications 权限 API,而不是手动设置 intent。Lint: use_local_notifications_exact_alarm_permission_api
R20在调用平台成员之前,先解析可空的平台特定插件实现。Lint: resolve_platform_specific_implementation_before_use
R21Widget 预览仅用于预览,使用确定性的假实现;不允许真实 HTTP/Firebase/Hive/原生插件。widget-previews.md
R22运行时 E2E 通过稳定的选择器、对失败敏感的场景/日志、与主体匹配的证据、事实来源验证、清理以及必要时多角色证明来验证行为。dart-mcp-e2e-testing.md
R23无障碍即 UI 正确性:本地化的工具提示/语义标签、48x48 目标、对比度、文本缩放、Text.rich。accessibility.md, flutter-optimizations.md
R24如果接受或已存在远程错误报告,使用一个应用自有的 Crash 边界,且每个操作只有一个报告负责人;否则不添加任何 provider/facade。在遥测之前清理敏感数据并协调有歧义的远程结果。error-reporting.md, networking.md
R25Windows 安装程序交付 = 一个语义引擎 + 类型化应用配置/能力 + 最小步骤的精确 SHA 诊断 → 一个发布者;在一次构建之前保留低成本的守卫,隔离合成的保留证明,并仅激活已验证的不可变字节。windows-installer-pipeline.md, workflow scaffold, inno_bundle pubspec scaffold, Inno settlement sentinel, Defender scanner
R26对暂停敏感的 Riverpod 状态仅在其持久 owner/listener 存在之后启动;投影直接监听基础状态;切换认证/表单模式会清除瞬态错误。notifier-structure.md, state-management-lifecycle.md, testing.md
R27原生/自定义链接在生产者、平台注册、Flutter 交付和类型化路由之间使用统一的 URI 契约;在目标设备上证明冷/热启动 + 带签名状态的交付。deep-linking.md, dart-mcp-e2e-testing.md

Trigger Map

涉及阅读
新应用/项目脚手架,附带技术栈/包提及、main.dart、ProviderScope、MaterialApp.router、应用启动壳setup.md + architecture.md + routing-app-shell.md
Notifier/AsyncNotifier 形态、同步 Notifier.build() 初始化、暂停路由/监听器启动、provider 投影、认证/表单模式错误重置、加载/进度、AsyncValue、清理notifier-structure.md + state-management-lifecycle.md + testing.md
变更方法、ref.read / ref.watch / ref.listen、_ensureRepository、异步取消、ref.mounted、乐观更新、重复获取async-mutations.md + state-management-lifecycle.md
Freezed 实体、密封联合、fromJson / toJson、copyWith、模型 vs 实体、用于 explicit_to_json 的 build.yamlfreezed-sealed.md
Provider 声明、@riverpod、family、keepAlive、代码生成、Mutation<T>(实验性)riverpod-codegen.md
仓储、数据源、领域实体、分层架构、IHttpService、模型到实体的映射architecture.md
值对象、基本类型偏执、Distance/Money/Email/Slug、领域内单位转换、跨实体基本类型、double distanceMeters/int amountCents/String email 坏味道、arch_domain_import 错误value-objects.md
GoRouter、类型化路由、重定向、受认证保护的路由、router provider、context.go、深度链接、自定义 URI scheme、原生扩展/activity 链接、冷启动、导航门控routing-app-shell.md + deep-linking.md
HTTP、网络、REST、变更后从事实来源获取、长时间运行的远程函数、异步启动 + 对账、传输 id vs 领域 idnetworking.md + debounce-gate-batch.md
原子、分子、有机体、设计令牌、原子 widget、core/widgets/ 提升atomic-design.md
可复用的 presentation/widgets/、widget 自有的导航/页面栈/选中实体/工作流状态、直接访问仓储/服务/providerpresentation-widgets.md
无障碍、语义、tooltip、semanticLabel、图片替代文本、点击目标、对比度、文字缩放accessibility.md + flutter-optimizations.md
Widget 测试、ProviderContainer.test()、UncontrolledProviderScope、fake、mock、AppWidgetKeys、事件契约测试testing.md
flutter_driver、Dart MCP、Marionette MCP、E2E、integration_test、语义选择器、场景验证、截图/媒体证据、日志捕获、原生集成构建成功但设备上失败、运行时权限、插件挂起、仅 release 运行时失败dart-mcp-e2e-testing.md
Hive、TypeAdapter、TypeId、box、持久化迁移、已退役字段核算hive-persistence.md
Crashlytics、FirebaseCrashlytics、Sentry、sentry_flutter、DSN、错误上报、Crash.init、Crash.error、Crash.log、符号上传error-reporting.md
Mixin、能力 vs 接口、重试辅助、RNG、批量操作mixins.md
服务、单例、发后即忘、abstract final class、unawaited()、Future<void> 签名services-and-singletons.md
@Preview、widget_previews.dart、预览 fake、确定性预览数据widget-previews.md
AppLocalizations、ARB 文件、gen-l10n、区域回退、占位符、复数 / 选择localization.md
性能、构建成本、.select()、const 构造函数、ListView.builder、大列表计算performance.md + flutter-optimizations.md
LayoutBuilder、RenderFlex 溢出、Row / Column 外的 Expanded / Flexible、Stack 外的 Positioned、文字缩放钳制layout-diagnostics.md
分页、无限滚动、游标加载、搜索防抖、注册/表单验证与提交、批处理、下拉刷新lists-forms-workflows.md + async-mutations.md
BuildContext 辅助、ModalRoute 当前路由检查、对话框、SnackBarUtils、从 notifier 派发 snackbarcontext-ui.md
DateTime format/diff/timeAgo/startOfDay、String capitalize/truncate/titleCase/initials/format、int / double / num clamp/pluralized/asCurrency/percent/toFixed、Duration format、NumberFormat、DateFormat、intlprimitive-formatting.md
Iterable 查找/索引、widget 列表辅助、Debouncer、验证器、Result、扩展类型、core/extensions/ 桶导出collections-helpers.md
Record (x, y)、扩展类型 ID、模式匹配、主/简洁构造函数、new()、factory()、点简写如 .center、@RecordUsedart-patterns-records.md
Flutter/Riverpod analysis_options.yaml、dart analyze、插件接线、riverpod_lint 版本锁定、分析器崩溃analysis-options.md + analysis_options.yaml
Skill 设置、Git pre-push、钩子/扫描器注册setup.md
build_runner、缺失生成部分、干净检出、Xcode 选择、Flutter SwiftPM 生成包、Apple 设备构建、本地 vs CI 不一致build-reproducibility.md + core-stack.md
包约束、依赖升级、生成器/分析器兼容性core-stack.md
Flutter Windows 桌面打包、GitHub Actions Windows 安装程序、Inno Setup、inno_bundle、更新器/自动更新、CRT DLL、PowerShell/原生安装程序进程、安装程序/版本/AppId 失败windows-installer-pipeline.md + build-reproducibility.md + core-stack.md
Dart Decimate、死代码、循环依赖、重复代码、复杂度、依赖卫生、全量零发现扫描dart-decimate.md
无更窄行覆盖的导航 / 表单 / 列表 / 防抖 / 路由参数回退模式common-patterns.md
增量远程拉取、增量令牌、按表同步日期、合并/删除对账delta-sync.md
路由参数安全、向导排序、受保护的下一步导航navigation-flow.md
对话框 / 工作表 / 模态、快照值对象、await 后拆除、先关闭再导航、pop 回退、嵌套导航器关闭modals-navigation.md + state-management-lifecycle.md
防抖 / 节流 / 合并 — TextField.onChanged、Slider.onChanged、滚动监听器、同步 saveAll、子集变更后全集合重写、持久化辅助、重置/清除哨兵保留、_userTapped 门控、build 中的 WebView / VideoPlayer、服务中的 _storage.read、ref.listenManual 禁用、keepAlive 集合监听、数据源批量加载器、零值保存保护、notifier 边界的基本类型→VO、模态辅助上的 routeSettingsdebounce-gate-batch.md

交付前检查

每次写入 .dart / pubspec.yaml / build.yaml / analysis_options.yaml 后进行内部检查:始终执行 T0;涉及状态/通知器/变更时,另执行 T1;涉及网络/E2E/流/路由时,另执行 T2。编辑循环仅分析已编辑的文件,详见 analysis-options.md;交接前仅运行一次完整的包根目录检查。

  • 检查项失败 → 立即报告,并注明规则 ID 或参考文档。
  • 交接 → 报告已完成的验证:阅读过的参考文档 + 运行过的检查 + 检查结果。
T0 — 核心
  • Flutter/Riverpod 包:编辑循环中已编辑文件的分析无问题;交接前运行一次包根目录 dart analyze --fatal-infos,退出码为 0,并启用 flutter_skill_lints + riverpod_lint;设置变更须分别证明两个插件都能产生一条诊断。纯 Dart CLI:适用原生 Dart 分析配置;两个插件均不适用。
  • 当前同范围、项目自有的 Dart Decimate 结果符合 dart-decimate.md 中的要求;注明扫描范围。
  • 已防护异步间隙:使用 ref.mounted / context.mounted,不使用裸 mounted,且 finally 使用 if (ref.mounted) { ... }。
  • Provider、状态和 Widget 遵循规则 2-8 和 14:可复用 Widget 仅管理 UI 生命周期;屏幕/路由/通知器负责导航、工作流分支、选定的领域记录、Provider 状态和基础设施。
  • 领域/数据/平台遵循规则 7、10-13、17-24、26-27:密封的 Freezed 类型、VO、数据源/仓储存储、核心扩展、类型化路由、防抖/批处理、平台 API、预览、E2E、暂停安全状态、原生链接和无障碍;如果已接受/存在错误报告,则通过单一的脱敏且仅执行一次的边界处理,否则标记为 N/A。
  • 除非涉及 Windows 打包/更新程序交付,否则规则 25 = N/A;适用时,其诊断/发布者证明必须通过。
  • Trigger Map 中涉及的任何行均已阅读;应由扫描器强制执行的规则须注明确切的 lint 名称。
T1 — 状态 / 通知器 / 变更
  • 变更依赖通过无状态 helper/mixin 延迟解析;除可释放的生命周期所有者外,通知器本地不缓存 repo/service。
  • 同步 Notifier.build() 在返回前避免读取 state;异步主状态使用 AsyncNotifier.build;持久的同步启动不依赖其所有者/监听器存在前的微任务时序。
  • ref.onDispose() 取消订阅/控制器/计时器;持久的状态、Snackbar 和 teardown 由通知器状态负责。
  • 长时间运行的同步/身份验证/导入操作会防止过期写入;通知器方法内不调用 ref.watch。
  • 对暂停敏感的投影直接监听基础状态;路由暂停/恢复时保留首次更新;身份验证/表单模式变更时清除临时错误。
T2 — 网络 / E2E / 流 / 路由
  • 对生成、规范化、重新排序、破坏性或远程函数变更,执行真实数据源获取/协调。
  • 共享/实时状态具有写入者 + 观察者的 E2E 证明,且无需手动刷新。
  • 选择器使用稳定的文本/语义/工具提示或中央 AppWidgetKeys;不使用内联字符串键,也不通过坐标进行主要点击操作。
  • E2E 场景状态确定且与生产行为隔离;Marionette 运行使用 lib/main.dart 中由调试模式控制的绑定,Flutter Driver 运行独立的 driver-extension 入口;未知场景会失败;关键日志会导致运行失败;证据须显示断言所针对的屏幕,然后才退出应用;已验证清理操作。
  • GoRouter 重定向使用通过矩阵测试的纯解析器、可空的按 ID 查询 Provider/回退 UI,以及生成的类型化路由 helper。
  • 原生/自定义 URI 的生成端、Android/iOS 注册、Flutter 传递和类型化路由器共用一份经过测试的 scheme/host/path 契约;冷启动/热启动 + 已签名状态的设备路径均通过。
  • 跨运行时常量、模式和函数契约均有漂移测试;不在应用根目录限制文本缩放。

评论

支持 Markdown