Private
Public Access
0
0

move track mds to tracks

This commit is contained in:
2026-06-06 00:42:40 -04:00
parent e670fc1c3e
commit 6c541bc788
2 changed files with 0 additions and 0 deletions
+71
View File
@@ -0,0 +1,71 @@
# 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 + dict
- [ ] `src/session_logger.py` - SessionLogger → module-level functions
- [ ] `src/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 class
- [ ] `src/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 state*
- [ ] `src/mcp_client.py` - MCPClient, ToolRegistry — *justified: tool dispatch handler map + 3-layer security state*
- [ ] `src/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.
- [x] `src/gui_2.py` - **DELEGATION EXTRACTED**: ~90 module-level `render_xxx(app)` functions, `App` class retains only lifecycle and thin `_render_xxx(self)` wrappers. See [docs/guide_gui_2.md](../docs/guide_gui_2.md) §"UI Delegation Pattern".
- [x] `src/command_palette.py` - **EXTRACTED**: `CommandRegistry` and `render_palette_modal` are module-level. `Command` dataclass is data-only. See [docs/guide_command_palette.md](../docs/guide_command_palette.md).
- [x] `src/commands.py` - **EXTRACTED**: All 32 commands registered via `@registry.register` decorator at module level.
## Anti-Regression Protocol
Before refactoring ANY class:
1. **Write test** that validates current behavior
2. **Commit baseline** with `test(baseline): add baseline for <class>`
3. **Extract method** into module-level function
4. **Update all callers** to use function directly
5. **Run test** - must pass identically
6. **Commit extraction** with `refactor(oop): extract <method> from <Class>`
7. **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.py` UI Delegation Pattern fully extracted: ~90 module-level `render_xxx(app)` functions. `App` class reduced to thin wrappers.
- `src/command_palette.py` extracted: `CommandRegistry` is a singleton class holding a dict (justified: needs encapsulated mutable state for register/unregister). All other logic is module-level.
- `src/commands.py` extracted: All 32 commands are module-level functions registered via `@registry.register`. Two helper functions (`_toggle_window`, `_toggle_attr`) are module-level.
- `src/models.py` confirmed using pydantic + dataclass(frozen=True) — already follows data-only container pattern. No changes needed.
- Hot Reload support verified: UI Delegation Pattern enables `HotReloader` to swap `gui_2.render_xxx` references at runtime without losing `app: App` state.
### 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::AIProvider` subclasses — abstract base with 5 concrete subclasses. Refactor would require feature-flag dispatch, not worth the churn.
- `src/mcp_client.py::MCPClient` — would split into `dispatch` (function) + `_state` (module globals). See [docs/guide_mcp_client.md](../docs/guide_mcp_client.md) §"dispatch" for current structure.
## Notes
- Use Strangler Fig pattern: keep class working until last caller migrated
- Prefer `dict`/`NamedTuple` over classes for data containers
- Classes with only data: convert to `dataclass(frozen=True)` or `NamedTuple`
@@ -0,0 +1,33 @@
# Theme Polish & Tone Mapping
## Problem
1. **Missing Theme Colors**: The `ThemePalette` dataclass in `src/theme_models.py` only defined a subset of the ~55 ImGui colors. Because `from_dict` strictly matched dataclass fields, colors like `resize_grip` and `tab_dimmed` from the TOML files were being discarded, breaking window resizing handles and inactive tab styling.
2. **Context Preview Syntax Palette**: `theme_2.apply()` failed to apply the syntax palette for non-NERV themes, and `src/markdown_helper.py` cached its `TextEditor` instances without clearing them on theme switch. This caused "Context Preview" to remain stuck on the previous theme's syntax colors.
3. **Light Theme Brightness**: The user requested a way to dim light themes. We will introduce a Tone Mapping system (Brightness, Contrast, Gamma) that mathematical adjusts the RGB colors before applying them to ImGui. The user requested this to be saved per-palette so each theme can have its own exposure profile.
## Proposed Solution
### 1. Fix Theme Models
- Ensure `src/theme_models.py`'s `ThemePalette` dataclass has all missing ImGui colors (e.g., `resize_grip`, `resize_grip_active`, `resize_grip_hovered`, `tab_dimmed`, `tab_dimmed_selected`, `docking_preview`, `plot_lines`, `nav_windowing_highlight`, etc.). *(Note: I proactively applied the class definition update during exploration, but will formally commit it)*.
### 2. Fix Context Preview Syntax Highlight Sync
- Update `src/theme_2.py` to ensure `apply_syntax_palette()` is called for *all* themes during `apply()`.
- Add an `import src.markdown_helper; src.markdown_helper.get_renderer().clear_cache()` call to the end of `theme_2.apply()` to force code blocks to recreate their `TextEditor` instances with the new palette.
### 3. Per-Palette Tone Mapping
- Add mathematical tone mapping variables to `src/theme_2.py`: `_brightness`, `_contrast`, and `_gamma` (stored as dictionaries keyed by the palette name to allow per-palette saving).
- Implement a math function to adjust RGB floats:
- Brightness: `c * brightness`
- Contrast: `(c - 0.5) * contrast + 0.5`
- Gamma: `pow(c, 1.0 / gamma)`
- Update the palette application loop in `theme_2.apply()` to pass every color float through this tone mapper before calling `style.set_color_()`.
- Update `save_to_config` and `load_from_config` to persist the tone mapping overrides per-palette under `[theme.tone_mapping.<palette>]`.
- Add Brightness, Contrast, and Gamma sliders to the Theme panel in `src/gui_2.py`.
## Implementation Steps
1. **Model & Sync Fixes**: Verify `src/theme_models.py` and update `src/theme_2.py`'s `apply()` function to trigger syntax updates and markdown cache clearing.
2. **Tone Mapping Logic**: Add the dicts and the math `_tone_map(rgb, palette)` function to `theme_2.py`, wrapping all color assignments.
3. **State Persistence**: Update `save_to_config` / `load_from_config` to handle the new per-palette dictionary.
4. **UI Integration**: Add the 3 sliders to `_render_theme_panel` in `src/gui_2.py`, complete with a "Reset to Defaults" button for the current palette.
5. **Testing**: Run the existing test suite and verify no regressions in config saving.