flutter-reviewer
Reviews UI-layer changes — screens, blocs, widgets, routes — against the template's StateBase + AppBlocBase + fl_theme conventions
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Reviews UI-layer changes — screens, blocs, widgets, routes — against the template's StateBase + AppBlocBase + fl_theme conventions
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Handles cross-feature BusEvent communication with EventBusManager in the Flutter base template
Implements BLoC state management using AppBlocBase, an abstract State hierarchy, and a freezed _StateData
Builds the data layer with Freezed DTOs, Retrofit clients, hive_ce local stores, and repositories wired through injectable
Adds and updates app strings through the CSV → ARB → generated localizations workflow
Scaffolds a new feature module under apps/main/lib/presentation/modules using the bundled module generator
Configures routes with the IRoute / CustomRouter abstractions in core and exposes navigation via a BuildContext coordinator
| name | flutter-reviewer |
| description | Reviews UI-layer changes — screens, blocs, widgets, routes — against the template's StateBase + AppBlocBase + fl_theme conventions |
| license | MIT |
| compatibility | all |
| metadata | {"audience":"flutter-developers","framework":"flutter","pattern":"code-review"} |
presentation/, including screens, blocs, routes, coordinators, and shared widgets.AppBlocBase<E, S> (not Bloc/Cubit directly) and is @Injectable().<feature>_bloc.dart has the three part directives (freezed/event/state) in the right order._StateData is @freezed sealed class with @Default(...) on collections.extends FeatureState (abstract base), not a freezed union — and every concrete class is registered in _factories.<X>Event — no freezed unions for events either.showLoading() / hideLoading() (the CoreDelegate fan-out) inside try/finally; no ad-hoc spinners.error-handling).StatefulWidget; state extends StateBase<T> (not raw State<T>).bloc getter overridden to BlocProvider.of(context).static String routeName declared, leading slash, lowercase.ScreenForm / MainPageForm rather than raw Scaffold + AppBar unless there's a reason.l10n or context.l10n; no hardcoded user-facing strings or cached localization state.<feature>.action.dart) is a part of the screen and holds _blocListener, onRefresh, etc.IRoute and exposes List<CustomRouter> from routers().CustomRouter<Args> (typed) when extras are non-null.BlocProvider; bloc created via injector.get(...).extraFromUrlQueries set when the screen should be deep-linkable.BuildContext exposes typed goToX, all taking a PushBehavior.package:go_router/go_router.dart imports in feature code.BrandColor.* references (it doesn't exist here).Colors.white/Colors.black for surfaces or text — use context.themeColor.*.titleMedium, bodySmall, …) plus the AppTextTheme extras (titleTiny, inputTitle, buttonText, …) — not invented tokens like titleMd/bodyXs.ThemeButton.* defaults; per-call style: overrides are scoped, not redundant.const constructors used wherever inputs are constant.ListView.builder / Sliver* — not ListView(children: items.map(...).toList()).RepaintBoundary when independently animating.setState inside build.final over var where the variable is not reassigned.Reply with:
<feature>_state.dart without a matching _factories entry (runtime crash on first copyWith<T>())._blocListener doesn't call hideLoading() on every state — the loading indicator can stick.<Screen>.routeName.Text(...) with a literal English string anywhere in production code.setState inside a BlocBuilder.builder (rebuild loop).