.claude/skills/feature-toggle-developer/SKILL.md
Guides systematic removal of feature toggles from the codebase with automated cleanup detection. Use when removing feature flags, enabling toggles permanently, or cleaning up unused code after toggle removal.
npx skillsauth add anyproto/anytype-swift feature-toggle-developerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Status: Active
Auto-activates on: Feature flag/toggle removal, cleanup after refactoring toggles
Related Skills: code-generation-developer, ios-dev-guidelines, code-review-developer
Guides the systematic removal of feature toggles (feature flags) from the codebase with automated cleanup detection. Ensures no orphaned code, unused components, or forgotten files remain after toggle removal.
FeatureDescription+Flags.swiftBefore removing any toggle, gather complete information:
Find the toggle definition:
# Location: Modules/AnytypeCore/AnytypeCore/Utils/FeatureFlags/FeatureDescription+Flags.swift
rg "static let toggleName" --type swift
Check the defaultValue to determine which branch to keep:
defaultValue: true → Keep the TRUE branch, remove FALSE branchdefaultValue: false → Keep the FALSE branch, remove TRUE branchSearch for ALL usages:
rg "toggleName" --type swift
Identify usage patterns:
if FeatureFlags.toggleName { ... }if !FeatureFlags.toggleName { ... } or guard !FeatureFlags.toggleNameif FeatureFlags.toggleName && otherCondition { ... }let value = FeatureFlags.toggleName ? a : b@State private var toggle = FeatureFlags.toggleNameList affected files and present to user for review
Systematic removal process:
Remove conditional checks and simplify:
Example 1 - Simple conditional (defaultValue: true):
// BEFORE
if FeatureFlags.toggleName {
// feature code
}
// AFTER (keep true branch)
// feature code
Example 2 - Ternary operator (defaultValue: true):
// BEFORE
VStack(spacing: FeatureFlags.toggleName ? 8 : 0)
// AFTER
VStack(spacing: 8)
Example 3 - Inverted logic (defaultValue: true):
// BEFORE
guard !FeatureFlags.toggleName else { return }
oldCode()
// AFTER (flag is true, so guard fails, remove entire block)
// [entire block deleted]
Example 4 - State variable (defaultValue: true):
// BEFORE
@State private var toggle = FeatureFlags.toggleName
if toggle { newUI() } else { oldUI() }
// AFTER
newUI()
// Note: @State variable removed in cleanup phase
Remove feature flag definition:
// Delete from: Modules/AnytypeCore/AnytypeCore/Utils/FeatureFlags/FeatureDescription+Flags.swift
static let toggleName = FeatureDescription(...)
Run code generation:
make generate
This updates FeatureFlags+Flags.swift automatically.
Verify removal:
rg "toggleName" --type swift # Should return no results
CRITICAL: After toggle removal, systematically check for orphaned code:
Search for @State variables that were only used for the toggle:
# Look for patterns like: @State private var someToggle = FeatureFlags.toggleName
rg "@State.*=.*FeatureFlags" --type swift
Action: Remove the entire @State variable declaration if it's no longer used.
When a toggle controlled which UI component to show, one component may now be unused:
Detection Pattern:
Example from vaultBackToRoots:
// BEFORE
if !vaultBackToRootsToggle {
SpaceCardLabel(...) // This became unused
} else {
NewSpaceCardLabel(...)
}
// AFTER
NewSpaceCardLabel(...)
// CLEANUP: SpaceCardLabel is now unused
rg "SpaceCardLabel" --type swift # Check if used anywhere else
# If only in its own file → DELETE the file
Action:
rg "UnusedComponentName" --type swiftToggle removal may leave entire classes unused:
Detection:
# For each major component that was conditionally used:
rg "UnusedViewModel" --type swift
rg "class UnusedViewModel" --type swift
Action: Delete unused ViewModels, their files, and DI registrations.
After simplification, import AnytypeCore may only have been needed for FeatureFlags:
Detection:
AnytypeCoreFeatureFlags.toggleNameAnytypeCore usageAction: Remove unused import.
Toggle-gated functionality may have parameters that are no longer needed:
Example:
// BEFORE
func configure(showFeature: Bool) {
if showFeature && FeatureFlags.toggle { ... }
}
// AFTER toggle removal
func configure(showFeature: Bool) {
if showFeature { ... }
}
// POTENTIAL CLEANUP: Is showFeature still needed?
Action: Review function signatures and remove unnecessary parameters.
Toggle removal affects tests:
Check:
Files to check:
rg "toggleName" AnyTypeTests/ --type swift
rg "toggleName" "Anytype/Sources/PreviewMocks/" --type swift
Action: Update or remove tests for deleted code paths.
Before committing:
Grep verification:
rg "toggleName" --type swift # Should be empty
Compilation check:
Generate updated commit message:
IOS-XXXX Removed [toggleName] toggle
Review cleanup summary:
Use this checklist after every toggle removal:
## Cleanup Verification for [toggleName]
- [ ] Toggle definition removed from FeatureDescription+Flags.swift
- [ ] `make generate` run successfully
- [ ] All conditional usage removed
- [ ] No grep results for toggle name
- [ ] Unused @State variables removed
- [ ] Unused view components identified and deleted
- [ ] Unused ViewModels/services deleted
- [ ] Unused imports removed (especially AnytypeCore)
- [ ] Orphaned function parameters removed
- [ ] Tests updated (check AnyTypeTests/ and PreviewMocks/)
- [ ] Comments referencing old component updated
- [ ] Xcode compilation verified (by user)
Watch out for !FeatureFlags.toggle:
// If defaultValue: true
if !FeatureFlags.toggle {
oldCode() // This branch NEVER runs, delete it
}
Simplify conditions properly:
// BEFORE (defaultValue: true)
if FeatureFlags.toggle && userHasPermission {
showFeature()
}
// AFTER
if userHasPermission {
showFeature()
}
Be careful with guards:
// BEFORE (defaultValue: true)
guard !FeatureFlags.toggle else { return }
performOldBehavior()
// AFTER (toggle is true, guard returns, entire block is dead code)
// DELETE ENTIRE BLOCK
make generate command and troubleshootingdevelopment
Smart router to testing patterns and practices. Use when writing unit tests, creating mocks, testing edge cases, or working with Swift Testing and XCTest frameworks.
development
Audit and improve SwiftUI runtime performance through code review and Instruments guidance. Use for diagnosing slow rendering, janky scrolling, excessive view updates, or layout thrash in SwiftUI apps.
development
SwiftUI view structure, composition, and best practices. Use when refactoring SwiftUI views, organizing view files, or extracting subviews.
development
Write, review, or improve SwiftUI code following best practices for state management, view composition, performance, macOS-specific APIs, and iOS 26+ Liquid Glass adoption. Use when building new SwiftUI features, refactoring existing views, reviewing code quality, or adopting modern SwiftUI patterns.