flutter_skill_gen 0.4.0
flutter_skill_gen: ^0.4.0 copied to clipboard
A CLI tool that scans Flutter projects and generates SKILL.md context files for AI coding assistants like Claude Code, Cursor, Copilot, and Windsurf.
Changelog #
0.4.0 #
Claude Code Best-Practice Alignment #
Generated skills now follow the patterns the Claude Code team has published for agentic engineering — lazy-loading, tight line budgets, gotchas, and data-flow diagrams. All changes are additive on the output side; existing AI and template paths still produce valid SKILL.md files.
paths:frontmatter for lazy loading. Every generatedSKILL.md/SKILL_<feature>.md/CLAUDE_<feature>.mdnow emits apaths:YAML block so Claude Code only loads a skill when a file matching one of its globs is touched. The core skill is scoped topubspec.yaml,lib/main.dart, and anylib/core/,lib/shared/,lib/common/,lib/config/, orlib/app/tree that actually exists; in single-file mode it also getslib/**/*.dart. Per-feature skills getlib/<feature-path>/**/*.dartderived from the evidence bundle.- Per-skill line budget. All three system prompts (single, core, domain) now carry a hard line ceiling (180 / 150 / 120 lines respectively, with lower aim targets) replacing the old word budgets.
DraftVerifiergained a newViolationKind.overLineBudgetthat flags drafts over 200 lines — Claude Code's published degradation threshold. The new check is draft-level rather than line-scoped, soannotate/stripmodes don't munge the file; the signal surfaces via the verifier warning log. - Deterministic Gotchas + Data Flow sections. Two new trusted-source modules,
GotchasLibraryandAsciiDiagrams, emit a## Gotchasbullet list and a## Data FlowASCII diagram for every skill. Rules are keyed by detected stack (bloc, riverpod, go_router, auto_route, get_it+injectable, freezed+hive pairs, clean-arch missing-layer, feature-first-no-shared, and more) and feature-scoped variants. Because both sections are generated from grounded detection — never from AI output — they bypass the hallucination surface and are spliced onto every draft after verification. The prompts now explicitly tell Claude not to write these sections. - Description fields are loading triggers, not summaries. The
description:YAML field is what Claude Code matches against the current task to decide when to surface a skill. Previous descriptions read like human project summaries ("Core architecture, conventions, and dependencies for <project>"); 0.4.0 rewrites them as load-trigger clauses ("Load when working in the Flutter + clean architecture + bloc app "<project>" — architecture, conventions, and project-specific rules."). Domain skills get"Load when editing the <feature> feature (<layers>) in <project>". - No-boilerplate prompt discipline. All three prompts now carry an explicit
Do NOT state the obviousclause — no "this is a Flutter project", no generic BLoC/Riverpod/Clean Architecture primer content, only project-specific rules that would surprise a mid-level Flutter engineer who just cloned the repo. - Split threshold lowered.
_recommendSkillFilespreviously held single-file output up to 50 files / 3 features; with a 200-line skill budget that threshold produced overflow. The cut now sits at 30 files / 2 features, so medium projects split sooner and each file stays lean.
0.3.1 #
Bug Fixes — Audit-Driven Accuracy #
Three issues surfaced by a real-world tng_laws_ai_mobile audit against 0.3.0:
- Feature cap silently dropped beyond the first 5.
_recommendSkillFileswas doingstructure.featureDirs.take(5), so any project with more than five features had its 6th+ feature quietly omitted from bothrecommended_skill_filesand the split plan. Projects like moneypal and tng_laws_ai_mobile were missingprofile,onboarding,shared, andnavigationskills even though the features were correctly detected. The cap is gone — every detected feature now produces a per-feature skill. - Dev dependencies were silently dropped.
PubspecAnalyzer.analyzeDependenciesonly routed dev deps intocode_generation/testingbuckets and discarded everything else (flutter_lints,flutter_launcher_icons,flutter_native_splash, etc.), so generated skill files had no signal that a project was, for instance, using stock Flutter lints.DependencyInfonow carries a newdev_dependencieslist (exposed in.skill_facts.jsonasdev_dependencies) that preserves every dev dep minusflutter/flutter_localizations. - Stock
flutter createwidget test was counted as real coverage._analyzeTestsflaggedhasWidgetTests=truewhenever any file containedtestWidgets(orpumpWidget(— including the untouchedtest/widget_test.dartcounter-increment stub that ships withflutter create. The scanner now recognizes the stock template (referencesMyApp(, tapsIcons.add, asserts the'0'→'1'transition) and excludes it from the widget-test signal.
0.3.0 #
Bug Fixes — Multi-File Output & Per-Feature Evidence #
Two regressions surfaced by a real-world audit of a complex Riverpod app using this package:
- Per-feature evidence was empty in layer-first projects.
feature_evidence[].file_countwas0under every feature in.skill_facts.jsonwhen features sat directly underlib/ui/<feature>(orlib/presentation/<feature>) with no intermediatepages/,features/, orscreens/container. Root cause:DomainAnalyzer._findDomainDirectorywas missing the direct-layer-container tier thatStructureAnalyzer._findFeatureDirgained in 0.1.2.ProjectScannernow threads the already-resolved feature path fromStructureAnalyzer.analyzeFeatureBreakdownintoDomainAnalyzer.analyze(..., resolvedPath: ...), and the analyzer's own lookup also mirrors the structure analyzer's full priority order as belt-and-suspenders. - Split mode generated one concatenated SKILL.md, not per-feature files. The default
genericandclaude_codewriters hadsupportsMultiFile=false, soTargetWriter.writeMultiSkillconcatenated every skill into a single file whileManifestGeneratorsimultaneously promisedSKILL_<feature>.mdsiblings that never landed on disk. Both writers nowsupportsMultiFile=trueand produceSKILL_<feature>.md/CLAUDE_<feature>.mdsiblings at the project root — matching the layout the manifest already advertises. - Forced split now expands to every detected feature.
SplitPlanner.plan(..., forceSplit: true)previously only iteratedrecommendedSkillFiles(which caps at 5 features and skips the "core-only" threshold). Explicit--splitnow unions instructure.featureDirsso small-but-multi-feature projects produce one skill per feature as expected. - Manifest is grounded in the plan.
ManifestGenerator.write(..., plan: plan)(wired intoanalyze,sync, andwatch) references only the skill files the plan will actually produce, eliminating the phantomSKILL_data.md-style entries when a recommended domain turns out to have nolib/directory.
Regression tests in test/regression/multi_file_and_evidence_test.dart lock in both fixes, and a new sample_layer_first_project fixture exercises the moneypal-style lib/ui/<feature> pattern end-to-end.
0.2.1 #
Model Defaults #
- Bumped the built-in default model from
claude-sonnet-4-20250514toclaude-sonnet-4-6(Sonnet 4.6), and refreshed theopusalias target toclaude-opus-4-7(Opus 4.7). The alias map anddefaultModelare now consistent —--model sonnet, an unset global config, and a missing--modelflag all resolve to the same model. Users withclaude-sonnet-4-20250514pinned in their~/.flutter_skill_gen/config.yamlcontinue to call that exact model (unmapped IDs pass through unchanged).
0.2.0 #
Hallucination-Proof Generation #
- EvidenceBundle — new ground-truth payload emitted by
ProjectScannerthat enumerates everylib/file path, every declared class name, per-feature layer/state/widget evidence, known file-name glob patterns, and DI registration style (centralizedvsper-feature). Serialized into.skill_facts.jsonand spliced into every Claude prompt. - Grounding rules — every system prompt (single, core, domain) now carries a
CRITICAL — grounding rulesblock instructing the model to draw class names, file paths, globs, and DI claims exclusively fromevidence.*fields. Available asPromptBuilder.groundingRulesfor reuse. - DraftVerifier — post-generation pass that cross-checks AI drafts against the evidence bundle. Flags four violation kinds:
unknownFilePath,unknownClassName,unknownGlobPattern, andfalseDiPerFeatureClaim. Configurable viaVerifierMode.annotate(default — inline<!-- [UNVERIFIED: …] -->markers),VerifierMode.strip(delete offending lines), orVerifierMode.fatal(raiseDraftVerificationFailedException). - Env-var configuration — the
FLUTTER_SKILL_VERIFIER_MODEenvironment variable selects the verifier mode globally (annotate|strip|fatal; case-insensitive; unknown values fall back toannotate). An explicitverifierModeconstructor argument overrides the env var. - Domain-scoped prompts now include a trimmed evidence slice containing the relevant
feature_evidenceentry plus project-wide DI and file manifest — keeps per-feature drafts grounded without bloating the prompt.
0.1.2 #
Bug Fixes #
- Fixed feature detection for layer-first projects where features sit directly under
lib/ui/orlib/presentation/without an intermediatepages/,features/, orscreens/container. Previously these projects were detected as having 0–2 features and always fell back to single-file output; they now produce proper multi-skill splits.
0.1.1 #
Documentation #
- Added
example/README.mdwith end-to-end CLI usage scenarios covering analyze, multi-target sync, watch mode, project scaffolding, API key config, and git hooks. - Documented the implicit
FormatWriterdefault constructor so 100% of the public API is covered by dartdoc.
0.1.0 #
Initial release.
Static Analysis #
- PubspecAnalyzer — parses
pubspec.yamlfor dependencies, SDK constraints, and package metadata. - StructureAnalyzer — detects folder organization (feature-first, layer-first, hybrid), monorepo structure, and project complexity.
- PatternDetector — identifies architecture patterns (Clean Architecture, MVVM, MVC), state management (BLoC, Riverpod, Provider, GetX, MobX, Cubit), navigation, DI, networking, storage, code generation, and internationalization.
- CodeSampler — extracts representative code samples (widgets, BLoC/state classes, repositories, models, route configs, DI setup) with context-aware classification.
- DomainAnalyzer — scans individual feature directories to produce domain-scoped analysis (state classes, entities, layer breakdown, code samples).
- ProjectScanner — orchestrates all analyzers into a unified
ProjectFactsmodel. - FactsWriter — writes
.skill_facts.jsonwith full project analysis data.
AI-Powered Generation #
- ClaudeClient — HTTP client for the Claude Messages API.
- PromptBuilder — constructs system and user prompts for core, domain, and single-file skill generation.
- SkillGenerator — generates skill content via Claude API with automatic template fallback when no API key is configured.
- TemplateGenerator — produces skill files from raw facts without an API call (core, domain, and single-file modes).
- ManifestGenerator — writes
.skill_manifest.yamlwith machine-readable project metadata.
Multi-File Skill Splitting #
- SplitPlanner — decides whether to generate a single skill file or split into core + domain files based on project complexity.
- DomainFacts model — domain-scoped analysis data (files, samples, layers, state classes, entities) for per-feature skill generation.
- Auto-detection based on project complexity; controllable via
--split/--no-splitflags. - Formats that support multi-file write separate files per skill; formats that support concatenation join skills with section separators; others receive core-only output.
Model Selection #
- Choose between Claude Sonnet (default) and Claude Opus via
--modelflag or global config. - Supports shortcut aliases (
sonnet,opus) and full model IDs. - Priority chain: CLI flag > global config > built-in default (Sonnet).
CLI Commands #
analyze— scan a project and generate.skill_facts.json,SKILL.md, and.skill_manifest.yaml. Supports--split,--facts-only,--model,--output, and--verbose.sync— re-analyze and regenerate all skill files with change detection to skip unnecessary regeneration. Supports--force,--ci,--split, and--model.watch— monitorlib/andpubspec.yamlfor changes and regenerate skill files automatically with configurable debounce. Supports--debounceand--model.init— scaffold a new project from a built-in template (clean_bloc,clean_riverpod) or clone a GitHub repository, then generate skill files. Supports--arch,--from-repo,--name,--output, and--model.config— manage global config (API key, model) and project config (output targets,.skillrc.yaml). Supports--set-key,--set-model,--remove-key,--init-skillrc,--add-target,--remove-target, and--show.hooks— install/remove pre-commit and post-merge git hooks, generate GitHub Actions workflow. Supports--install,--remove,--github-action,--dart-only, and--status.
Output Targets #
- 8 output formats:
generic(SKILL.md),claude_code(CLAUDE.md),cursor(.cursorrules),copilot(.github/copilot-instructions.md),windsurf(.windsurfrules),antigravity(.agents/skills/<name>/SKILL.md),antigravity_rules(.gemini/GEMINI.md),agents_md(AGENTS.md). - Multi-target support via
.skillrc.yaml— write to multiple AI tools simultaneously. - TargetWriter dispatches to format-specific writers with multi-file, concatenation, and core-only strategies.
Configuration #
- Global config at
~/.flutter_skill_gen/config.yamlfor API key and model preference. - Project config at
.skillrc.yamlfor output targets and watch settings. - Environment variable support (
FLUTTER_SKILL_API_KEY).
CI & Automation #
- GitHooksInstaller — pre-commit and post-merge hooks that run
flutter_skill_gen sync. - GitHubActionGenerator — generates
.github/workflows/skill_sync.ymlwith Flutter or Dart-only SDK setup.
VS Code Extension #
- Command palette integration (Analyze, Sync, Watch, Preview).
- Status bar indicator (idle, syncing, watching, error).
- Skill file preview in markdown.
- Git hooks and GitHub Action generation from the editor.