Install
$ agentstack add skill-draz26648-flutter-claude-skills-review-gate ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Review Gate
> Profile first. check.sh reads .claude/flutter-profile.yaml on its own and prints > which profile it applied. You do not need to pass anything — but read the file too, so > the judgement calls at the end of this skill are made against the same conventions the > script enforced. Field list: > ${CLAUDE_PLUGIN_ROOT}/skills/architecture/references/flutter-profile.md.
This skill audits and reports. It does not fix. That restriction is deliberate: a gate with write access eventually satisfies its own checks by deleting the assertion that failed, and a quality gate that can edit code to make itself pass is not a gate. Edit and Write are absent from allowed-tools for that reason — do not reach for them from inside this skill, and do not "helpfully" fix a finding on the way past.
Report findings, then let the developer decide.
Running it
Run from the project root — the script reads pubspec.yaml and git diff there.
bash "${CLAUDE_PLUGIN_ROOT}/skills/review-gate/scripts/check.sh"
CLAUDE_PLUGIN_ROOT is set by Claude Code and expands on its own; it does not need resolving by hand. If the skill was vendored by install.sh rather than installed as a plugin, that variable is unset — use whichever copy exists:
bash "$HOME/.claude/skills/review-gate/scripts/check.sh" # --personal / --all-personal
bash .claude/skills/review-gate/scripts/check.sh # --project
Options: --skip-tests when you only want lint feedback, --all to audit all of lib/ and test/ instead of just what changed.
Exit codes: 0 nothing blocking, 1 at least one blocking finding, 2 the gate could not run. A 2 is not a pass. It means a precondition failed or a check itself broke, and the result carries no information about the code.
Read the script's output rather than re-running the individual commands — it already separates blocking from non-blocking, and re-running by hand loses that.
What is checked
Formatting. dart format --set-exit-if-changed over the files in scope. Unformatted code produces noisy diffs that hide real changes in review.
Static analysis. flutter analyze --fatal-infos, whole project. Infos are fatal on purpose; tolerated infos accumulate until nobody reads the output at all. This one is deliberately not scoped to the diff — a change in one file breaks analysis in another, and scoping to the diff hides exactly that.
Forbidden patterns. Blocking:
print(— use a logger. Print statements ship to production and leak data.- Hardcoded colors —
Color(0x...)orColors.— see the design-tokens skill. - Numeric
EdgeInsets— see the design-tokens skill. EdgeInsets.only(left:orright:— see the a11y-and-rtl skill.- API keys, tokens, or URLs with embedded credentials.
Non-blocking:
debugPrint(in shipped code.TODOorFIXMEwithout a ticket reference.TODO(WAL-42)passes; a bareTODOdoes
not. An untracked TODO is a note to nobody.
- Commented-out code.
BorderRadius.circular().!force-unwrap on a nullable — every one is a potential crash. Acceptable with a
comment explaining why null is impossible, which is why this warns rather than blocks.
- Hardcoded user-facing strings in
Text(...)— see a11y-and-rtl. - Inline
TextStyle(...)in widget code — see codebase-conventions. - An asset path that does not resolve to a file on disk. This one is a fact rather than a
convention: it throws at runtime, in the widget, on the device, and neither the analyzer nor a test that skips that screen will say a word about it. It warns only because promoting it to blocking would fail projects that pass today.
- A widget class defined in more than one file, when the current change is part of the
duplication. The second PrimaryButton is correct, tested, redundant, and invisible in review because the diff is all additions.
Where these are not enforced. Generated files (*.g.dart, *.freezed.dart, *.mocks.dart, and similar), tests, and the token layer (theme/, tokens/, design_system/, app_colors.dart, app_theme.dart) are excluded from the literal-value checks. Raw colors and numbers are exactly what belongs in the token file. A gate that fails on correct code gets switched off, so the carve-out is load-bearing rather than a convenience.
What the profile changes. With no .claude/flutter-profile.yaml the list above is exactly what runs, so nothing changes for a project that never writes one. With a profile:
| Setting | Effect | |---|---| | tokens: none | The colour, EdgeInsets, radius, and inline-TextStyle checks are skipped entirely — there is no token layer for them to point at | | tokens: theme_only or constants | Those drop to warnings; the values still ought to be centralised, but not through AppTokens | | l10n: none | The hardcoded-string check is skipped | | locales contains no RTL language | The directional-inset check drops to a warning | | strictness: warn | Every convention finding drops to a warning |
strictness: warn never touches formatting, static analysis, failing tests, or committed credentials. Those block under every profile — they are not house style, and a project that wants them off wants a different tool.
A skipped check is reported as skipped, with the profile setting that caused it. It is never silently omitted: a check that vanishes without explanation is indistinguishable from a check that passed, which is the failure mode 2.0.0 existed to fix.
Tests. flutter test passes, and failures are named in the report. New public methods on a Cubit have tests covering both the success and the failure path. Changed golden PNGs are flagged explicitly, since they are the easiest thing to approve without looking.
Dependencies. New entries in pubspec.yaml are flagged. Each needs a note on why, and a check that the functionality does not already exist in the codebase or the SDK.
Judgement the script cannot make
The script finds mechanical violations. These need reading the diff:
- Whether a new Cubit method's tests cover the failure path, not just that tests exist.
- Whether a changed golden was actually reviewed, or just regenerated until green.
- Whether a force-unwrap's justifying comment is true.
- Whether a new dependency was necessary.
Report on these alongside the script's output. They are the findings a human reviewer would have caught and the script never will.
Report format
Report as three groups, in this order:
BLOCKING — must fix before merge
- [file:line] what is wrong, and why it matters
WORTH FIXING — should fix, will not break anything today
- [file:line] ...
NOTES — observations, no action required
- ...
If nothing is blocking, say so plainly rather than manufacturing findings to look thorough. A gate that always reports problems teaches people to ignore it.
Scope
The pattern checks confine themselves to Dart files changed against HEAD, so the report tracks the current change rather than the whole codebase. Analysis and tests are whole-project because they have to be. When the report cites a file the change did not touch, that is analysis or tests talking, and it still needs fixing.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: draz26648
- Source: draz26648/flutterclaude_skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.