4.3 KiB
4.3 KiB
OOP Refactoring Tracker
Tracks elimination of class-based OOP from the codebase to reduce AI agent scope misinterpretation.
Status: IN PROGRESS (UI Delegation Pattern widely adopted; core classes retained with justification)
Phase 1: Leaf Classes (No internal dependents)
These classes have no dependencies on other classes being refactored. Start here.
src/tool_bias.py- ToolBiasEngine → module functions + dictsrc/session_logger.py- SessionLogger → module-level functionssrc/summarize.py- SummaryCache class → plain dict + functions
Phase 2: Internal Classes (Depend on Phase 1)
These classes use Phase 1 classes. Refactor Phase 1 first.
src/project_manager.py- ProjectManager classsrc/aggregate.py- Aggregator class
Phase 3: Core Classes (High risk - many callers)
These have many dependents. Handle last with extra testing.
src/ai_client.py- AI client classes (AIProvider, etc.) — justified: holds multi-provider singleton statesrc/mcp_client.py- MCPClient, ToolRegistry — justified: tool dispatch handler map + 3-layer security statesrc/models.py- Data classes → dataclass/NamedTuple — already done: uses pydantic + dataclass(frozen=True)
Phase 4: GUI Classes (Highest risk)
Classes used in GUI callbacks. Require live testing.
src/gui_2.py- DELEGATION EXTRACTED: ~90 module-levelrender_xxx(app)functions,Appclass retains only lifecycle and thin_render_xxx(self)wrappers. See docs/guide_gui_2.md §"UI Delegation Pattern".src/command_palette.py- EXTRACTED:CommandRegistryandrender_palette_modalare module-level.Commanddataclass is data-only. See docs/guide_command_palette.md.src/commands.py- EXTRACTED: All 32 commands registered via@registry.registerdecorator at module level.
Anti-Regression Protocol
Before refactoring ANY class:
- Write test that validates current behavior
- Commit baseline with
test(baseline): add baseline for <class> - Extract method into module-level function
- Update all callers to use function directly
- Run test - must pass identically
- Commit extraction with
refactor(oop): extract <method> from <Class> - Delete class only when ALL methods extracted
Progress Log
2026-05-11
- Initial tracker created
- Anti-OOP conventions added to
conductor/code_styleguides/python.md - Ruff PLR rules added to
pyproject.toml
2026-06-02
src/gui_2.pyUI Delegation Pattern fully extracted: ~90 module-levelrender_xxx(app)functions.Appclass reduced to thin wrappers.src/command_palette.pyextracted:CommandRegistryis a singleton class holding a dict (justified: needs encapsulated mutable state for register/unregister). All other logic is module-level.src/commands.pyextracted: All 32 commands are module-level functions registered via@registry.register. Two helper functions (_toggle_window,_toggle_attr) are module-level.src/models.pyconfirmed using pydantic + dataclass(frozen=True) — already follows data-only container pattern. No changes needed.- Hot Reload support verified: UI Delegation Pattern enables
HotReloaderto swapgui_2.render_xxxreferences at runtime without losingapp: Appstate.
Pending Refactors (Out of Scope, tracked here)
src/tool_bias.py::ToolBiasEngine— small class (~50 lines), refactor candidate but currently 1+ methods.src/session_logger.py::SessionLogger— facade class, refactor candidate.src/summarize.py::SummaryCache— class wraps LRU dict + lock, refactor candidate but lock encapsulation is a valid justification.src/ai_client.py::AIProvidersubclasses — abstract base with 5 concrete subclasses. Refactor would require feature-flag dispatch, not worth the churn.src/mcp_client.py::MCPClient— would split intodispatch(function) +_state(module globals). See docs/guide_mcp_client.md §"dispatch" for current structure.
Notes
- Use Strangler Fig pattern: keep class working until last caller migrated
- Prefer
dict/NamedTupleover classes for data containers - Classes with only data: convert to
dataclass(frozen=True)orNamedTuple