Code Review
flutter/flutter
Performs a comprehensive, multi-step code review of pull requests or local code changes, using iterative refinement (generation, critique, synthesis) to ensure high-quality, actionable feedback.
How to build screens, widgets, and handle effects in the Unyo Flutter app's presentation layer.
$ npx skills add K3vinb5/unyo-app --skill unyo-ui-presentation -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install K3vinb5/unyo-app unyo-ui-presentation --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/K3vinb5/unyo-app.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/unyo-ui-presentation .claude/skills/unyo-ui-presentation && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "unyo-ui-presentation" agent skill from https://github.com/K3vinb5/unyo-app/tree/rewrite/.agents/skills/unyo-ui-presentation into .claude/skills/unyo-ui-presentation/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "unyo-ui-presentation", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/K3vinb5/unyo-app/tree/rewrite/.agents/skills/unyo-ui-presentationType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add K3vinb5/unyo-app --skill unyo-ui-presentation -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install K3vinb5/unyo-app unyo-ui-presentation --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/K3vinb5/unyo-app.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/unyo-ui-presentation .agents/skills/unyo-ui-presentation && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "unyo-ui-presentation" agent skill from https://github.com/K3vinb5/unyo-app/tree/rewrite/.agents/skills/unyo-ui-presentation into .agents/skills/unyo-ui-presentation/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "unyo-ui-presentation", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add K3vinb5/unyo-app --skill unyo-ui-presentation -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install K3vinb5/unyo-app unyo-ui-presentation --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/K3vinb5/unyo-app.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/unyo-ui-presentation .cursor/skills/unyo-ui-presentation && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "unyo-ui-presentation" agent skill from https://github.com/K3vinb5/unyo-app/tree/rewrite/.agents/skills/unyo-ui-presentation into .cursor/skills/unyo-ui-presentation/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "unyo-ui-presentation", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/K3vinb5/unyo-app.git --path .agents/skills/unyo-ui-presentation--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add K3vinb5/unyo-app --skill unyo-ui-presentation -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install K3vinb5/unyo-app unyo-ui-presentation --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/K3vinb5/unyo-app.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/unyo-ui-presentation .gemini/skills/unyo-ui-presentation && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "unyo-ui-presentation" agent skill from https://github.com/K3vinb5/unyo-app/tree/rewrite/.agents/skills/unyo-ui-presentation into .gemini/skills/unyo-ui-presentation/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "unyo-ui-presentation", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install K3vinb5/unyo-app unyo-ui-presentationInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add K3vinb5/unyo-app --skill unyo-ui-presentation -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/K3vinb5/unyo-app.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/unyo-ui-presentation .github/skills/unyo-ui-presentation && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "unyo-ui-presentation" agent skill from https://github.com/K3vinb5/unyo-app/tree/rewrite/.agents/skills/unyo-ui-presentation into .github/skills/unyo-ui-presentation/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "unyo-ui-presentation", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add K3vinb5/unyo-app --skill unyo-ui-presentation -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install K3vinb5/unyo-app unyo-ui-presentation --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/K3vinb5/unyo-app.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/unyo-ui-presentation .opencode/skills/unyo-ui-presentation && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "unyo-ui-presentation" agent skill from https://github.com/K3vinb5/unyo-app/tree/rewrite/.agents/skills/unyo-ui-presentation into .opencode/skills/unyo-ui-presentation/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "unyo-ui-presentation", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
unyo-ui-presentationHow to build screens, widgets, and handle effects in the Unyo Flutter app's presentation layer.
Unyo UI Presentation is an agent skill from K3vinb5/unyo-app. How to build screens, widgets, and handle effects in the Unyo Flutter app's presentation layer. Use this skill whenever creating new screens, adding BlocProvider/BlocListener/BlocBuilder patterns, building custom styled widgets, handling side effects from cubits in the UI, creating dialogs or drawers, or organizing UI code. Also use when understanding the screen widget structure pattern or troubleshooting UI rendering issues.
Its SKILL.md is about 3k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Development. It works with Flutter. The repository describes itself as: 🐙 Anime streaming and Manga reader desktop app without ads. The licence is BSD-3-Clause.
5 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 0a44722. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
flutterFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Unyo UI Presentation loads about 3k tokens when it runs. Until then it costs about 113 tokens; SKILL.md has 840 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from K3vinb5/unyo-app at commit 0a44722, republished under its BSD-3-Clause licence (© K3vinb5). 840 words, ~2,970 tokens.
.claude/skills/unyo-ui-presentation/SKILL.md (or your agent's skills folder).The presentation layer in Unyo follows a consistent pattern: each screen is a three-layer widget tree that separates concerns of creation, effect handling, and UI building. This skill covers the structure, conventions, and patterns for building UI in Unyo.
lib/presentation/
├── screens/ # Full-page route screens (@RoutePage annotated)
│ ├── home_screen.dart
│ ├── anime_screen.dart
│ ├── anime_details_screen.dart
│ ├── video_screen.dart
│ ├── settings_screen.dart
│ └── ...
├── widgets/
│ ├── styled/ # Reusable styled UI components
│ │ ├── unyo_menu_bar.dart
│ │ ├── media_card.dart
│ │ ├── unyo_textfield.dart
│ │ └── ...
│ └── text/ # Typography components
│ ├── text_display_small.dart
│ ├── text_body_medium.dart
│ └── ...
├── dialogs/ # Modal dialogs
│ ├── warning_dialog.dart
│ ├── textfield_dialog.dart
│ └── anime_details_media_entry_dialog.dart
├── drawers/ # Slide-in drawer dialogs
│ ├── user_options_drawer.dart
│ ├── anime_server_selection_drawer.dart
│ └── episode_list_drawer.dart
└── views/ # Loading/error state views
└── loading_view.dartEvery screen in Unyo follows the same three-widget structure:
Screen (outer) → Listener (middle) → View (inner)@RoutePage()
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => sl<HomeCubit>(),
child: const _HomeListener(),
);
}
}This is the entry point. It:
@RoutePage() annotation for AutoRoute code generationsl<HomeCubit>() (factory, so each screen gets its own)StatelessWidget (never holds state)class _HomeListener extends StatelessWidget {
const _HomeListener();
@override
Widget build(BuildContext context) {
return BlocListener<HomeCubit, HomeState>(
listener: (context, state) {
if (state.effects.isNotEmpty) {
sl<AppEffectHandler>().handleEffects(
context,
state.effects,
context.read<HomeCubit>().clearEffects,
);
}
},
child: BlocBuilder<HomeCubit, HomeState>(
builder: (context, state) => state.isLoading
? const LoadingView()
: const _HomeView(),
),
);
}
}This layer:
BlocListener to process effectslistener callback fires on every state change — when effects are present, it delegates to AppEffectHandlercubit.clearEffects() to remove the processed effectsLoadingView when isLoading)StatelessWidget unless it needs ScrollController lifecycle managementclass _HomeView extends StatefulWidget {
const _HomeView();
@override
State<_HomeView> createState() => _HomeViewState();
}
class _HomeViewState extends State<_HomeView> {
final ScrollController continueWatchingController = ScrollController();
final ScrollController continueReadingController = ScrollController();
@override
void dispose() {
continueWatchingController.dispose();
continueReadingController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return BlocBuilder<HomeCubit, HomeState>(
builder: (context, state) {
return Padding(
padding: EdgeInsets.only(left: 15.0.w),
child: SingleChildScrollView(
child: Column(
children: [
// UI using state properties
AnimeCardList(
listTitle: "Continue Watching",
animeList: state.continueWatching,
controller: continueWatchingController,
onPressed: context.read<HomeCubit>().navigateToAnimeDetails,
),
],
),
),
);
},
);
}
}This layer:
BlocBuilder to rebuild when state changesStatefulWidget (if it needs controllers) or StatelessWidgetcontext.read<HomeCubit>()state.continueWatching, state.isLoading)The AppEffectHandler is a singleton that processes effects emitted by cubits:
// In every screen's BlocListener
if (state.effects.isNotEmpty) {
sl<AppEffectHandler>().handleEffects(
context, // BuildContext for navigation/dialogs
state.effects, // List of effects from state
context.read<HomeCubit>().clearEffects, // Callback to clear effects
);
}The handler processes each effect type:
| Effect Type | Action |
|---|---|
PushRouteEffect | AutoRouter.of(context).pushPath(path) |
ReplaceRouteEffect | AutoRouter.of(context).replacePath(path) |
NavigateRouteEffect | AutoRouter.of(context).navigatePath(path) |
ChangeTabRouteEffect | AutoTabsRouter.of(context).setActiveIndex(index) |
ShowSnackbarEffect | Material banner with AwesomeSnackbarContent |
ShowWidgetDialogEffect | showDialog(context: context, builder: ...) |
ShowDrawerDialogEffect | showGeneralDialog with slide transition |
CloseDialogEffect | Navigator.pop(context) |
Important: clearEffects() must always be called after processing. The handleEffects method calls it automatically as the third parameter.
The AppEffectHandler also has an attachRootContext() method that's used in the tabs screen for tab switching:
// In tabs_screen.dart
sl<AppEffectHandler>().attachRootContext(context);This stores a reference to the root BuildContext for tab navigation, which operates outside the scope of an individual screen's BlocListener. Most effects don't need this — they use the context passed from the BlocListener.
These screens live inside AutoTabsRouter and have a sidebar menu:
// Tab screens follow the standard 3-layer pattern
// They access TabsCubit for menu state and tab switchingThese screens are pushed on top of the tab navigator:
The login screen is special — it's the initial: true route and replaces itself with TabsRoute on success.
widgets/styled/)Reusable UI components follow a naming convention:
Unyo prefix for custom components: UnyoMenuBar, UnyoTextField, UnyoSliderMediaCard, AnimeCardList, ImageCardwidgets/text/)Text widgets are thin wrappers around Flutter's Text widget with consistent styling:
TextDisplaySmall, TextDisplayMedium, TextDisplayLargeTextHeadlineSmall, TextHeadlineMedium, TextHeadlineLargeTextTitleSmall, TextTitleMedium, TextTitleLargeTextBodySmall, TextBodyMedium, TextBodyLargeTextLabelSmall, TextLabelMedium, TextLabelLargeThese correspond to Material Design 3 type scale.
The app uses flutter_screenutil for responsive sizing:
.w for width-based sizing: SizedBox(width: 15.0.w).h for height-based sizing: SizedBox(height: 50.0.h).sp for font sizing: TextStyle(fontSize: 14.0.sp).r for border radius: BorderRadius.circular(8.0.r)Design base size is 1280x720 (set in main.dart).
Styled widgets and text components export through barrel files:
lib/presentation/widgets/styled/styled.dartlib/presentation/widgets/text/texts.dartDialogs are shown via the Effect system:
// In a cubit
showWidgetDialogEffect(
dialog: WarningDialog(
title: "Delete?",
message: "This action cannot be undone.",
onConfirm: () => _deleteItem(),
),
);Custom dialogs should be created in lib/presentation/dialogs/ and can accept callbacks for actions.
Drawer dialogs slide in from a specified direction:
// In a cubit
showDrawerDialogEffect(
drawerDialog: AnimeServerSelectionDrawer(anime: anime),
backgroundColor: Colors.black54,
startPosition: AxisDirection.right,
);Drawers are in lib/presentation/drawers/ and use showGeneralDialog with slide transitions.
Create the screen file at lib/presentation/screens/<feature>_screen.dart:
@RoutePage() annotation to the outer widgetBlocProvider(create: (context) => sl<FeatureCubit>()) in the Screen layerAdd the route in lib/core/router/app_router.dart — see unyo-routing-navigation skill
Register the cubit in lib/core/di/locator.dart — see unyo-dependency-injection skill
Run code generation:
flutter pub run build_runner build --delete-conflicting-outputsImport the cubit and state in the screen file
initState, no state holders, no business logic.cubit.clearEffects as the third argument to handleEffects(). Without this, effects fire on every rebuild.context.watch<>() instead of context.read<>(): In callbacks and event handlers, use read (no rebuild). In build methods, the BlocBuilder handles rebuilds.ScrollController or TextEditingController, the View must be a StatefulWidget with proper dispose() cleanup.BlocBuilder where BlocListener is needed: BlocBuilder is for UI that changes based on state. BlocListener is for one-time actions (effects, navigation). Use both when you need both — wrap BlocListener outside BlocBuilder.unyo-bloc-state-management skill for how cubits emit effectsunyo-routing-navigation skill for route configurationunyo-reactive-notifiers skillunyo-dependency-injection skill© K3vinb5, BSD-3-Clause. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .agents/skills/unyo-ui-presentation of K3vinb5/unyo-app.
Open the folder on GitHubat commit 0a44722
Unyo UI Presentation next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Unyo UI Presentation this skillK3vinb5/unyo-app | 662 | — | ~3k | Automated safety check: Pass | BSD-3-Clause | |
| Code Reviewflutter/flutter | 179k | — | ~1.4k | Automated safety check: Pass | BSD-3-Clause | |
| Senior Architect Toolkitmaslennikov-ig/claude-code-orchestrator-kit | 260 | 8 repos | ~1.2k | Automated safety check: Notes | Custom licence | |
| Code Review Skillawesome-skills/code-review-skill | 2.1k | — | ~2.8k | Automated safety check: Notes | MIT | |
| Adding Release Notesflutter/devtools | 1.7k | — | ~1k | Automated safety check: Pass | BSD-3-Clause | |
| Code Guidelinesgetsentry/sentry-dart | 873 | — | ~2.2k | Automated safety check: Pass | MIT |
flutter/flutter
Performs a comprehensive, multi-step code review of pull requests or local code changes, using iterative refinement (generation, critique, synthesis) to ensure high-quality, actionable feedback.
maslennikov-ig/claude-code-orchestrator-kit
Comprehensive software architecture skill for designing scalable, maintainable systems using ReactJS, NextJS, NodeJS, Express, React Native, Swift, Kotlin…
awesome-skills/code-review-skill
Provides comprehensive code review guidance for React 19, Vue 3, Angular 17+, Svelte 5, Rust, TypeScript, Java, Java 8, PHP, Ruby, Rails, Python, Django, FastAPI, Go, C/.NET, Kotlin, Swift, Dart…
flutter/devtools
Adds user-facing change descriptions to DevTools release notes.
getsentry/sentry-dart
Enforce Sentry Dart/Flutter SDK code guidelines for implementation, refactoring, and review.
k8zdev/k8z
Automate git worktree creation and copy private files (not tracked in git) to new workdirs.
K3vinb5/unyo-app
Generate Dart bean classes from JSON and regenerate serialization helpers using the fjson CLI.
K3vinb5/unyo-app
How to create cubits, define states, use the EffectMixin pattern, and handle side effects in the Unyo Flutter app.
K3vinb5/unyo-app
How to register and resolve dependencies using GetIt in the Unyo Flutter app.
K3vinb5/unyo-app
How to create domain entities, data models, and repositories in the Unyo Flutter app.
K3vinb5/unyo-app
How to create and use RxDart BehaviorSubject notifiers for cross-cubit communication in the Unyo Flutter app.
K3vinb5/unyo-app
How to add routes, configure navigation, and use AutoRoute in the Unyo Flutter app.
Works with
Categories
How to build screens, widgets, and handle effects in the Unyo Flutter app's presentation layer. Unyo UI Presentation is an agent skill from K3vinb5/unyo-app. How to build screens, widgets, and handle effects in the Unyo Flutter app's presentation layer.
Unyo UI Presentation fits situations like: creating new screens; adding BlocProvider/BlocListener/BlocBuilder patterns; building custom styled widgets; handling side effects from cubits in the UI.
Run `npx skills add K3vinb5/unyo-app --skill unyo-ui-presentation -a claude-code`. Or copy the skill folder (.agents/skills/unyo-ui-presentation in K3vinb5/unyo-app) into .claude/skills/unyo-ui-presentation in your project. Claude Code loads it when a task matches its description.
Run `npx skills add K3vinb5/unyo-app --skill unyo-ui-presentation -a codex`. Or copy the skill folder (.agents/skills/unyo-ui-presentation in K3vinb5/unyo-app) into .agents/skills/unyo-ui-presentation in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add K3vinb5/unyo-app --skill unyo-ui-presentation -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/unyo-ui-presentation, .gemini/skills/unyo-ui-presentation, .github/skills/unyo-ui-presentation and .opencode/skills/unyo-ui-presentation in your project.
Going by SKILL.md and its folder, Unyo UI Presentation needs the command-line tools its instructions call (flutter).
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Unyo UI Presentation is published under the BSD-3-Clause licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Unyo UI Presentation: Code Review (flutter/flutter, 179k stars), Senior Architect Toolkit (maslennikov-ig/claude-code-orchestrator-kit, 260 stars), Code Review Skill (awesome-skills/code-review-skill, 2.1k stars) and Adding Release Notes (flutter/devtools, 1.7k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
K3vinb5 (a GitHub user) maintains it in K3vinb5/unyo-app, which has 662 GitHub stars. The repository holds 7 skills in this directory. The repository was last updated on June 12, 2026.
Source: K3vinb5/unyo-app on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.