From feature-flag-cleanup
Clean up feature flags from codebases. Removes flag checks, makes conditional code unconditional (graduate = keep enabled code, drop = remove enabled code), handles cascade cleanup via static analysis, cleans tests/config/docs. Use when the user wants to clean up, remove, graduate, drop, retire, or sunset a feature flag. Triggers on: "clean up feature flag", "remove feature flag", "graduate feature flag", "drop feature flag", "flag cleanup", "retire flag", "sunset flag".
How this skill is triggered — by the user, by Claude, or both
Slash command
/feature-flag-cleanup:cleanup-feature-flag <flag-name> <graduate|drop> <repository-path><flag-name> <graduate|drop> <repository-path>The summary Claude sees in its skill listing — used to decide when to auto-load this skill
> *"A proper cleanup leaves no trace of the old regime."*
"A proper cleanup leaves no trace of the old regime."
Before starting, collect these inputs from the user:
| Input | Required | Description |
|---|---|---|
| Flag name | Yes | The string identifier (e.g., flag_mod_xpm_travel) |
| Action | Yes | graduate or drop |
| Repository path | Yes | Absolute path to the repository to clean |
true/enabled branch. Delete the false/disabled branch.true/enabled branch. Keep the false/disabled/fallback branch.Discovery is reliable because flags are ALWAYS defined as string constants in a dedicated constants file per module. No confirmation checkpoint needed — proceed directly to transformation.
Find the flag constant definition
grep for the flag name string literal (e.g., "flag_mod_xpm_travel") across the repositoryFlagConstants.dart, FeatureFlags.kt, FeatureFlags.swift)kFlagModXpmTravel, FLAG_MOD_XPM_TRAVEL)Trace all references via the constant name
grep for the constant variable name across the entire repo (including android/ and ios/ directories for Flutter projects)Categorize usages (for transformation routing)
Proceed immediately — no user confirmation needed. Results shown in summary.
For each code conditional usage, apply the correct transformation based on the action:
true/enabled branch, remove the false/disabled branchfalse/disabled branch, remove the true/enabled branchSee cleanup-patterns.md for detailed transformation examples covering all 10 patterns: simple if/else, no-else blocks, collection-if, entire file/class, nested conditions, early returns, ternary expressions, variable assignments, Kotlin when expressions, and SwiftUI conditional views. Also includes boolean simplification rules and edge cases.
Key principles:
Strategy: Leverage static analysis tools (not manual reasoning) to find cascade issues. Iterate until the analyzer reports no new warnings.
Approach: Analyzer-Driven Iterative Cleanup
loop:
1. Run static analysis (`dart analyze`, Kotlin compiler, Swift build)
2. Parse warnings/errors related to files already modified:
- Unused imports
- Unused variables/fields
- Unused parameters
- Unreachable code
- Empty bodies/blocks
3. If new warnings found → fix them
4. If warnings create MORE orphaned code → repeat from step 1
5. If no new warnings → exit loop (clean state achieved)
What to fix in each iteration:
import lines that are no longer referencedStopping conditions:
Critical: Ignore pre-existing warnings. Before starting cleanup, capture the baseline analyzer output. Only act on NEW warnings that appeared after the flag removal. Never fix unrelated pre-existing issues — that's scope creep.
Important: Only fix warnings in files already touched or that are DIRECTLY related to the flag removal. Do not go on a codebase-wide cleanup spree.
Reason about what each test is ACTUALLY testing, not just whether it references the flag.
Decision framework for each test that references the flag:
Is the flag the SOLE subject of the test?
graduate → DELETE the "flag OFF" test case, KEEP the "flag ON" test (unwrap it — it's now the default)drop → DELETE the "flag ON" test case, KEEP the "flag OFF" test (unwrap it — it's now the default)Is the flag just part of the test setup (testing something else)?
setUp() then tests travel booking flowgraduate → Remove the flag mock from setup, keep the test intactdrop → DELETE the entire test (the feature no longer exists)Is it a group/describe wrapper based on flag state?
group('when travel flag is enabled', () { ... })graduate → Unwrap the group: keep all inner tests, remove the group wrapperdrop → DELETE the entire groupIs the flag mocked alongside other setup?
setUp() { mockFlag(ON); mockUser(admin); mockNetwork(online); }mockFlag(ON) line, leave everything elseGeneral rules:
import of the flag constant from test files when no longer referenced// TODO(flag-cleanup): manual review needed - {reason} comment above the uncertain code block| Scenario | Behavior |
|---|---|
| Flag name not found anywhere | Stop immediately. Report "flag not found" to user. |
| Ambiguous transformation (unsure which branch) | Skip that usage. Add TODO comment. Continue with other usages. |
| Build fails after transformation | Report build errors to user. Do not undo. User decides. |
| Tests fail after transformation | Stash changes, run tests on original code to establish baseline. Report pre-existing vs new failures. Do not undo. |
| Cascade loop exceeds 10 iterations | Stop cascade. Report remaining warnings. Proceed to next phase. |
| Analyzer unavailable (tool not installed) | Warn user that cascade cleanup is best-effort without analyzer. Proceed with manual reasoning. |
| File permission / read-only issue | Skip that file. Report to user. Continue with other files. |
?. null-safe accessif inside collection literals: [if (flag) Widget()]Visibility, Offstage, or conditional child: patternswhen expressions instead of if/else@Composable conditional renderingguard statements#if compile-time flags (different from runtime flags!)if in bodynpx claudepluginhub iqbal-mekari/claude-plugins --plugin feature-flag-cleanupFetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
Provides a checklist for code reviews covering functionality, security, performance, maintainability, tests, and quality. Use for pull requests, audits, team standards, and developer training.