| name | Codebase-Aware Implementation |
| description | Ensure new features follow existing project patterns by studying current code and docs before coding. |
| last_verified | "2026-01-23T00:00:00.000Z" |
| applicable_sdk | Android 14+ (API 34+) |
| dependencies | ["best-practice-check","git-commit-awareness"] |
Skill: Codebase-Aware Implementation
Last Verified: 2026-01-23
Applicable SDK: Android 14+ (API 34+)
Dependencies: best-practice-check, git-commit-awareness
Purpose
Always implement new features by studying existing project patterns first, rather than defaulting to "comfortable" but inconsistent approaches.
The Problem
❌ Pattern-Blind Development
class NewFeatureActivity : AppCompatActivity() {
private lateinit var binding: ActivityNewFeatureBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityNewFeatureBinding.inflate(layoutInflater)
setContentView(binding.root)
}
}
But the project uses
- Custom View architecture (not Activities)
- Manual XML layouts (not ViewBinding)
- Specific initialization patterns
Result: Inconsistent code that requires refactoring
The Solution: Pattern Discovery First
Mandatory Pre-Implementation Phase
Before writing ANY new code:
- Search for similar features → Understand existing patterns
- Read architectural docs → Check
.agent/ARCHITECTURE.md
- Identify conventions → Review
.agent/AGENTS.md
- Match the style → Implement consistently
Implementation Workflow
Phase 1: Discovery (ALWAYS DO THIS FIRST)
Step 1.1: Find Similar Features
grep -r "SwitchMaterial" app/src/main/res/layout/
grep -r "setOnCheckedChangeListener" app/src/main/kotlin/
ls -la app/src/main/kotlin/**/settings/
Questions to Answer
- How are settings stored? (SharedPreferences? DataStore? Repository?)
- What naming convention is used? (
is*Enabled? *Setting?)
- Where is UI logic? (Activity? Fragment? BottomSheet?)
Step 1.2: Read Architecture Docs
cat .agent/ARCHITECTURE.md
cat .agent/AGENTS.md
cat .agent/DEVELOPMENT_NOTES.md
Look for
- Package structure rules
- Naming conventions
- Design patterns in use
- LOCKED patterns (must not change)
Step 1.3: Analyze Existing Implementation
Read at least 2-3 similar features before implementing:
Read: SettingsBottomSheet.kt
Read: ThemeManager.kt
Read: SettingsDataStore.kt or SharedPreferences usage
Read: layout/bottom_sheet_settings.xml
Phase 2: Pattern Matching
Identify Core Patterns
| Aspect | Pattern Discovery |
|---|
| Architecture | MVC? MVP? MVVM? Custom View-based? |
| State Management | SharedPreferences? DataStore? Repository? |
| UI Framework | Activities? Fragments? Custom Views? Compose? |
| Dependency Injection | Manual? Hilt? Koin? |
| Resource Naming | icon_*_*_24dp? ic_*? Check existing resources |
| Code Structure | Where do similar features live? |
Document Your Findings
Before implementing, write down:
## Implementation Plan
### Existing Patterns Discovered
- Settings stored in: SharedPreferences (`SettingsManager.kt`)
- Toggles defined in: `bottom_sheet_settings.xml`
- Naming: `is[Feature]Enabled` (e.g., `isOledProtectionEnabled`)
- UI Pattern: Material SwitchMaterial with custom styling
### My Implementation Will
- [ ] Store setting in SharedPreferences via SettingsManager
- [ ] Add SwitchMaterial to bottom_sheet_settings.xml
- [ ] Follow `is*Enabled` naming convention
- [ ] Use existing toggle listener pattern
- [ ] Match existing toggle spacing/styling
Phase 3: Consistent Implementation
Follow Project Conventions Exactly
Example: Adding "Auto-Brightness" Toggle
class BrightnessManager {
fun saveAutoBrightness(enabled: Boolean) {
val prefs = context.getSharedPreferences("my_prefs", Context.MODE_PRIVATE)
prefs.edit().putBoolean("auto_brightness", enabled).apply()
}
}
object SettingsManager {
var isAutoBrightnessEnabled: Boolean
get() = prefs.getBoolean(KEY_AUTO_BRIGHTNESS, false)
set(value) = prefs.edit().putBoolean(KEY_AUTO_BRIGHTNESS, value).apply()
private const val KEY_AUTO_BRIGHTNESS = "is_auto_brightness_enabled"
}
Balancing: Best Practice vs. Agile Speed
The Dilemma
Scenario: You need to add a feature quickly (agile), but the codebase has technical debt.
Options:
- Quick & Dirty: Implement fastest way → Technical debt grows
- Perfect Refactor: Refactor everything first → Slow, risky
- Pattern Match: Follow existing patterns, even if imperfect → Recommended
Decision Framework
┌─────────────────────────────────────────┐
│ Is the existing pattern DANGEROUS? │
│ (security issue, crashes, data loss) │
└─────────────────┬───────────────────────┘
│
┌─────────┴─────────┐
│ │
YES NO
│ │
v v
┌───────────┐ ┌────────────────┐
│ STOP │ │ Follow existing│
│ Discuss │ │ pattern │
│ with user │ └────────────────┘
└───────────┘
Pattern Quality Assessment
Ask these questions about existing patterns:
| Question | If YES | If NO |
|---|
| Is it consistent across the codebase? | ✅ Follow it | 🤔 Discuss with user |
| Is it documented in AGENTS.md as LOCKED? | ✅ Must follow | ⚠️ Can propose changes |
| Would changing it require touching 10+ files? | ✅ Follow it | 💡 Can improve incrementally |
| Does it cause bugs or crashes? | 🚨 Must fix | ✅ Follow it |
| Is it just "not ideal" but functional? | ✅ Follow it | ✅ Follow it |
The "Good Enough" Rule
当需要跟随不完美的模式时:
Follow existing pattern if:
✓ Pattern is consistent across codebase
✓ Pattern works without bugs
✓ Changing it requires major refactoring
✓ Team is in "delivery mode" (agile sprint)
Propose improvements if:
✗ Pattern causes frequent bugs
✗ Pattern violates SOLID principles severely
✗ Better alternative requires < 5 file changes
✗ You're in "refactor mode" (tech debt sprint)
Refactoring Strategy
Incremental Improvement
Instead of big-bang refactors:
❌ BAD: Refactor entire settings system before adding toggle
Time: 2 weeks, Risk: High, Value: ?
✅ GOOD: Add toggle using existing pattern + note tech debt
Time: 1 hour, Risk: Low, Value: Feature shipped
✅ BETTER: Add toggle + improve pattern in that area only
Time: 2 hours, Risk: Low, Value: Feature + local improvement
Technical Debt Documentation
When you follow a suboptimal pattern, document it:
object SettingsManager {
var isOledProtectionEnabled: Boolean
get() = prefs.getBoolean("is_oled_protection_enabled", false)
set(value) = prefs.edit().putBoolean("is_oled_protection_enabled", value).apply()
}
Then add to .agent/FUTURE_FEATURES.md:
## Technical Debt
- [ ] Migrate SharedPreferences to DataStore
- Provides type safety
- Supports Kotlin Flow for reactive updates
- Affects ~8 files in settings package
Examples from OpenFlip Project
Example 1: Adding Widget Style
Scenario: Add new "Minimal" widget style
❌ Wrong Approach (Pattern-Blind)
class MinimalWidgetProvider : AppWidgetProvider() {
override fun onUpdate(...) {
}
}
✅ Right Approach (Codebase-Aware)
Step 1: Discovery (Example 1)
ls app/src/main/kotlin/widget/
Step 2: Pattern Analysis
abstract class WidgetClockBaseProvider : AppWidgetProvider() {
protected abstract fun getLayoutId(): Int
protected abstract fun getWidgetStyle(): WidgetStyle
}
Step 3: Pattern-Matched Implementation (Example 1)
class WidgetClockMinimalProvider : WidgetClockBaseProvider() {
override fun getLayoutId() = R.layout.widget_minimal
override fun getWidgetStyle() = WidgetStyle.MINIMAL
}
Result: Consistent with 4 other widgets, no refactoring needed
Example 2: Adding Color to Theme
Scenario: Add accent color to theme system
❌ Wrong Approach
<color name="accent">#FF5722</color>
<color name="accentDark">#E64A19</color>
✅ Right Approach
Step 1: Discovery (Example 2)
grep -r "color name=" app/src/main/res/values/colors.xml
cat .agent/skills/color-tokens/SKILL.md
Step 2: Read Conventions
<color name="bg_primary_light">#FFFFFF</color>
<color name="bg_primary_dark">#000000</color>
<color name="text_primary_light">#000000</color>
<color name="text_primary_dark">#FFFFFF</color>
Pattern: [category]_[level]_[theme]
Step 3: Pattern-Matched Implementation (Example 2)
<color name="accent_primary_light">#FF5722</color>
<color name="accent_primary_dark">#E64A19</color>
AI Assistant Checklist
Before implementing ANY new feature:
### Pre-Implementation Checklist
- [ ] **Search for similar features**
- [ ] Used Grep to find similar code
- [ ] Used Glob to find similar files
- [ ] Read at least 2 similar implementations
- [ ] **Read architectural docs**
- [ ] Checked .agent/ARCHITECTURE.md
- [ ] Checked .agent/AGENTS.md
- [ ] Checked relevant skills/
- [ ] **Identify patterns**
- [ ] Package structure convention
- [ ] Naming conventions
- [ ] Architectural patterns (MVC/MVVM/etc)
- [ ] Resource naming patterns
- [ ] **Document findings**
- [ ] Wrote down discovered patterns
- [ ] Noted any LOCKED rules
- [ ] Identified files to match
- [ ] **Plan implementation**
- [ ] Implementation plan matches existing patterns
- [ ] Will not require immediate refactoring
- [ ] Follows project conventions exactly
### Only After Above: Proceed with Implementation
Communication with User
When Patterns Are Unclear
Template:
I found two different patterns for [feature] in the codebase:
Pattern A (used in FileX.kt, FileY.kt):
[code example]
Pattern B (used in FileZ.kt):
[code example]
Which pattern should I follow for this new feature?
Or should I refactor to unify these patterns first?
When Patterns Are Suboptimal
Template:
I discovered the existing [feature] pattern:
[code example]
This pattern works but has limitations:
- [limitation 1]
- [limitation 2]
I can:
1. Follow the existing pattern (fast, consistent, ships feature)
2. Improve the pattern locally (medium effort, better code)
3. Refactor all usages (slow, high risk, best quality)
In agile mode, I recommend Option 1 or 2. Which do you prefer?
Summary
Golden Rules
- Never code before research - Always discover patterns first
- Consistency > perfection - Match existing style even if imperfect
- Document tech debt - Note what should be improved later
- Incremental improvement - Small refactors > big rewrites
- Communicate trade-offs - Explain agile vs. quality choices
Time Budget
For typical feature implementation:
20% - Pattern discovery (search, read, analyze)
10% - Planning (document findings, match patterns)
60% - Implementation (write code matching patterns)
10% - Verification (test, review consistency)
Investing time in discovery PREVENTS refactoring loops.
Related Skills