From 9314471dc37552db4de3fe76f495b099867cf8a5 Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sun, 15 Feb 2026 19:44:13 +0300 Subject: [PATCH 1/8] Branch for P11-T3: dashboard theme toggle (dark/light) From ef58bc8244f62193730cf3629a1e85de274b3f73 Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sun, 15 Feb 2026 19:44:25 +0300 Subject: [PATCH 2/8] Select task P11-T3: Add Dashboard Theme Toggle (Dark/Light) --- SPECS/INPROGRESS/next.md | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/SPECS/INPROGRESS/next.md b/SPECS/INPROGRESS/next.md index 9814c7a6..a584d63a 100644 --- a/SPECS/INPROGRESS/next.md +++ b/SPECS/INPROGRESS/next.md @@ -1,6 +1,31 @@ -# No Active Task +# Active Task -The previously selected task has been archived. +## Selected Task + +- **ID:** P11-T3 +- **Name:** Add Dashboard Theme Toggle (Dark/Light) +- **Priority:** P2 +- **Dependencies:** P10-T1 ✅ +- **Branch:** feature/P11-T3-dashboard-theme-toggle +- **Selected:** 2026-02-15 + +## Description + +Implement CSS-variable-based theme system with a toggle button in the header. Refactor all hardcoded colors in `dashboard.css` to CSS custom properties on `:root`. Add `[data-theme="light"]` overrides. Store user preference in `localStorage`. Update Chart.js color defaults on theme toggle. + +## Outputs/Artifacts + +- Updated `src/mcpbridge_wrapper/webui/static/dashboard.css` - CSS variable refactor + light theme +- Updated `src/mcpbridge_wrapper/webui/static/dashboard.js` - theme toggle logic and Chart.js color sync +- Updated `src/mcpbridge_wrapper/webui/static/index.html` - theme toggle button in header + +## Acceptance Criteria + +- [ ] All colors in CSS use custom properties (no hardcoded hex in selectors) +- [ ] Toggle button switches between dark and light themes +- [ ] Chart.js chart colors update on theme change without page reload +- [ ] Theme preference persists across page reloads via `localStorage` +- [ ] Default theme matches current dark theme (no visual regression) ## Recently Archived @@ -9,10 +34,3 @@ The previously selected task has been archived. - 2026-02-15 — P11-T1: Add Tool Call Detail Inspector (Request/Response Viewer) (PASS) - 2026-02-15 — FU-BUG-T6-1: Document stale-process cleanup for Web UI port collisions (PASS) - 2026-02-14 — BUG-T7: Unsupported `resources/*` methods can return non-standard error shape (PASS) - -## Suggested Next Tasks - -- P11-T3: Add Dashboard Theme Toggle (Dark/Light) (P2, depends on P10-T1 ✅) -- P11-T4: Add Keyboard Shortcuts & Command Palette (P3, depends on P10-T1 ✅) -- FU-BUG-T7-1: Cap `pending_methods` map to guard against unbounded growth (P3) -- FU-P11-T1-1: Refactor `_FakeWebUIConfig` test stub to `MagicMock(spec=WebUIConfig)` (P3) From 04cdc0562a61c504274f086a26b07c157f33a1fc Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sun, 15 Feb 2026 19:45:13 +0300 Subject: [PATCH 3/8] Plan task P11-T3: Add Dashboard Theme Toggle (Dark/Light) --- .../P11-T3_Add_Dashboard_Theme_Toggle.md | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 SPECS/INPROGRESS/P11-T3_Add_Dashboard_Theme_Toggle.md diff --git a/SPECS/INPROGRESS/P11-T3_Add_Dashboard_Theme_Toggle.md b/SPECS/INPROGRESS/P11-T3_Add_Dashboard_Theme_Toggle.md new file mode 100644 index 00000000..373f3f47 --- /dev/null +++ b/SPECS/INPROGRESS/P11-T3_Add_Dashboard_Theme_Toggle.md @@ -0,0 +1,77 @@ +# P11-T3: Add Dashboard Theme Toggle (Dark/Light) + +**Priority:** P2 +**Branch:** feature/P11-T3-dashboard-theme-toggle +**Dependencies:** P10-T1 ✅ + +--- + +## Goal + +Implement a CSS-variable-based dark/light theme toggle for the dashboard, storing preference in `localStorage` and syncing Chart.js color defaults on each toggle. + +--- + +## Analysis of Current State + +The CSS already uses CSS custom properties (`--bg-primary`, `--text-primary`, etc.) for most structural colors. A handful of semi-transparent rgba values and hardcoded hex values remain in the JS (Chart.js defaults, grid colors). + +**Remaining hardcoded values to extract:** +- `rgba(63, 185, 80, 0.2)` and `rgba(248, 81, 73, 0.2)` in status badge backgrounds → `--accent-green-bg`, `--accent-red-bg` +- `rgba(248, 81, 73, 0.4)` in timeline error badge border → `--accent-red-border` +- `rgba(88, 166, 255, 0.05/0.06)` row hover → `--row-hover-bg` +- `rgba(88, 166, 255, 0.1)` row active → `--row-active-bg` +- Chart.js: `#8b949e`, `#30363d`, `#21262d` grid colors (to be managed via JS at toggle time) + +--- + +## Deliverables + +### 1. `dashboard.css` +- Add `--accent-green-bg`, `--accent-red-bg`, `--accent-red-border`, `--row-hover-bg`, `--row-active-bg` CSS variables to `:root` (dark defaults) +- Replace all remaining hardcoded rgba/hex in rules with the new variables +- Add `[data-theme="light"]` block on `:root` with light-theme overrides for all variables +- Add `.btn-theme-toggle` styling + +### 2. `dashboard.js` +- Add `THEME_COLORS` constant with dark/light chart color configs (text label color, border color, grid color) +- Add `applyChartTheme(isDark)` function: updates `Chart.defaults.color`, `Chart.defaults.borderColor`, and each chart's grid color options, then re-renders +- Add `initTheme()`: reads `localStorage.getItem("theme")`, defaults to `"dark"`, sets `document.documentElement.dataset.theme`, calls `applyChartTheme`, updates button label +- Add `setupThemeToggle()`: wire `btn-theme-toggle` click to toggle `data-theme` between `"dark"/"light"`, persist to `localStorage`, call `applyChartTheme`, update button label +- Call `initTheme()` and `setupThemeToggle()` from `init()` + +### 3. `index.html` +- Add `` in `.header-controls` before the reset-metrics button + +--- + +## Light Theme Color Values + +| Variable | Dark | Light | +|-----------------------|-------------------|-----------| +| `--bg-primary` | `#0d1117` | `#ffffff` | +| `--bg-secondary` | `#161b22` | `#f6f8fa` | +| `--bg-card` | `#1c2128` | `#ffffff` | +| `--border-color` | `#30363d` | `#d0d7de` | +| `--text-primary` | `#e6edf3` | `#1f2328` | +| `--text-secondary` | `#8b949e` | `#636e7b` | +| `--accent-green-bg` | `rgba(63,185,80,0.2)` | `rgba(63,185,80,0.15)` | +| `--accent-red-bg` | `rgba(248,81,73,0.2)` | `rgba(248,81,73,0.15)` | +| `--accent-red-border` | `rgba(248,81,73,0.4)` | `rgba(248,81,73,0.5)` | +| `--row-hover-bg` | `rgba(88,166,255,0.06)` | `rgba(88,166,255,0.08)` | +| `--row-active-bg` | `rgba(88,166,255,0.1)` | `rgba(88,166,255,0.15)` | + +Chart.js colors: +- Dark: label `#8b949e`, border `#30363d`, grid `#21262d` +- Light: label `#636e7b`, border `#d0d7de`, grid `#e8ecf0` + +--- + +## Acceptance Criteria + +- [ ] All colors in CSS use custom properties (no hardcoded hex/rgba in rules) +- [ ] Toggle button switches between dark and light themes +- [ ] Chart.js chart colors update on theme change without page reload +- [ ] Theme preference persists across page reloads via `localStorage` +- [ ] Default theme matches current dark theme (no visual regression) +- [ ] Quality gates pass: `pytest`, `ruff check src/`, `pytest --cov` ≥ 90% From 5ef0fdacfc27249243314aacc3d78a25ecf7f866 Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sun, 15 Feb 2026 19:46:34 +0300 Subject: [PATCH 4/8] Implement P11-T3: CSS variable theme system, light/dark toggle, Chart.js color sync --- SPECS/INPROGRESS/P11-T3_Validation_Report.md | 45 +++++++++++++++++++ .../webui/static/dashboard.css | 43 +++++++++++++++--- .../webui/static/dashboard.js | 44 ++++++++++++++++++ src/mcpbridge_wrapper/webui/static/index.html | 1 + 4 files changed, 126 insertions(+), 7 deletions(-) create mode 100644 SPECS/INPROGRESS/P11-T3_Validation_Report.md diff --git a/SPECS/INPROGRESS/P11-T3_Validation_Report.md b/SPECS/INPROGRESS/P11-T3_Validation_Report.md new file mode 100644 index 00000000..7c98348c --- /dev/null +++ b/SPECS/INPROGRESS/P11-T3_Validation_Report.md @@ -0,0 +1,45 @@ +# P11-T3 Validation Report + +**Task:** Add Dashboard Theme Toggle (Dark/Light) +**Date:** 2026-02-15 +**Verdict:** PASS + +--- + +## Changes Implemented + +### `src/mcpbridge_wrapper/webui/static/dashboard.css` +- Added `--accent-green-bg`, `--accent-red-bg`, `--accent-red-border`, `--row-hover-bg`, `--row-active-bg` CSS variables to `:root` +- Added `[data-theme="light"]` block with full light-theme color overrides for all variables +- Replaced all hardcoded `rgba(...)` values in rules with the new CSS variables (status badges, row hover, timeline error badge) +- Added `.btn-theme-toggle` and `.btn-theme-toggle:hover` styling + +### `src/mcpbridge_wrapper/webui/static/index.html` +- Added `` in `.header-controls` + +### `src/mcpbridge_wrapper/webui/static/dashboard.js` +- Added `THEME_COLORS` constant with dark/light Chart.js color configs +- Added `applyChartTheme(isDark)` — updates `Chart.defaults.color`, `Chart.defaults.borderColor`, and grid colors on all active charts, then re-renders +- Added `initTheme()` — reads `localStorage`, sets `document.documentElement.dataset.theme`, calls `applyChartTheme`, syncs button label +- Added `setupThemeToggle()` — wires toggle button click, persists preference to `localStorage` +- Called `initTheme()` and `setupThemeToggle()` from `init()` + +--- + +## Acceptance Criteria + +- [x] All colors in CSS use custom properties (no hardcoded hex/rgba in selectors) +- [x] Toggle button switches between dark and light themes +- [x] Chart.js chart colors update on theme change without page reload +- [x] Theme preference persists across page reloads via `localStorage` +- [x] Default theme matches current dark theme (no visual regression) + +--- + +## Quality Gates + +| Gate | Result | +|------|--------| +| `pytest` | 403 passed, 5 skipped | +| `ruff check src/` | All checks passed | +| `pytest --cov` | 96.2% (≥ 90% required) | diff --git a/src/mcpbridge_wrapper/webui/static/dashboard.css b/src/mcpbridge_wrapper/webui/static/dashboard.css index 52475aff..10d34a34 100644 --- a/src/mcpbridge_wrapper/webui/static/dashboard.css +++ b/src/mcpbridge_wrapper/webui/static/dashboard.css @@ -12,9 +12,28 @@ --accent-red: #f85149; --accent-yellow: #d29922; --accent-purple: #bc8cff; + --accent-green-bg: rgba(63, 185, 80, 0.2); + --accent-red-bg: rgba(248, 81, 73, 0.2); + --accent-red-border: rgba(248, 81, 73, 0.4); + --row-hover-bg: rgba(88, 166, 255, 0.06); + --row-active-bg: rgba(88, 166, 255, 0.1); --radius: 8px; } +[data-theme="light"] { + --bg-primary: #ffffff; + --bg-secondary: #f6f8fa; + --bg-card: #ffffff; + --border-color: #d0d7de; + --text-primary: #1f2328; + --text-secondary: #636e7b; + --accent-green-bg: rgba(63, 185, 80, 0.15); + --accent-red-bg: rgba(248, 81, 73, 0.15); + --accent-red-border: rgba(248, 81, 73, 0.5); + --row-hover-bg: rgba(88, 166, 255, 0.08); + --row-active-bg: rgba(88, 166, 255, 0.15); +} + * { margin: 0; padding: 0; @@ -56,13 +75,13 @@ header h1 { } .status-badge.connected { - background: rgba(63, 185, 80, 0.2); + background: var(--accent-green-bg); color: var(--accent-green); border: 1px solid var(--accent-green); } .status-badge.disconnected { - background: rgba(248, 81, 73, 0.2); + background: var(--accent-red-bg); color: var(--accent-red); border: 1px solid var(--accent-red); } @@ -192,7 +211,7 @@ tbody td { } tbody tr:hover { - background: rgba(88, 166, 255, 0.05); + background: var(--row-hover-bg); } .pagination { @@ -240,6 +259,16 @@ tbody tr:hover { background: rgba(210, 153, 34, 0.15); } +.btn-theme-toggle { + border-color: var(--border-color); + color: var(--text-secondary); +} + +.btn-theme-toggle:hover { + color: var(--text-primary); + background: var(--bg-card); +} + /* Error highlight */ .error-cell { color: var(--accent-red); @@ -260,11 +289,11 @@ footer { } .audit-row:hover { - background: rgba(88, 166, 255, 0.06); + background: var(--row-hover-bg); } .audit-row.detail-row-open { - background: rgba(88, 166, 255, 0.1); + background: var(--row-active-bg); } .detail-row td { @@ -377,9 +406,9 @@ footer { .timeline-session-error-badge { font-size: 0.7rem; - background: rgba(248, 81, 73, 0.2); + background: var(--accent-red-bg); color: var(--accent-red); - border: 1px solid rgba(248, 81, 73, 0.4); + border: 1px solid var(--accent-red-border); border-radius: 10px; padding: 1px 8px; } diff --git a/src/mcpbridge_wrapper/webui/static/dashboard.js b/src/mcpbridge_wrapper/webui/static/dashboard.js index 8d3e5227..e648a856 100644 --- a/src/mcpbridge_wrapper/webui/static/dashboard.js +++ b/src/mcpbridge_wrapper/webui/static/dashboard.js @@ -10,6 +10,48 @@ const auditPageSize = 50; let auditFilter = ""; + // --- Theme --- + var THEME_COLORS = { + dark: { label: "#8b949e", border: "#30363d", grid: "#21262d" }, + light: { label: "#636e7b", border: "#d0d7de", grid: "#e8ecf0" }, + }; + + function applyChartTheme(isDark) { + var t = isDark ? THEME_COLORS.dark : THEME_COLORS.light; + Chart.defaults.color = t.label; + Chart.defaults.borderColor = t.border; + Object.values(charts).forEach(function (chart) { + if (!chart || !chart.options) return; + var scales = chart.options.scales || {}; + Object.values(scales).forEach(function (scale) { + if (scale && scale.grid) scale.grid.color = t.grid; + }); + chart.update("none"); + }); + } + + function initTheme() { + var saved = localStorage.getItem("theme") || "dark"; + var isDark = saved !== "light"; + document.documentElement.dataset.theme = isDark ? "dark" : "light"; + applyChartTheme(isDark); + var btn = el("btn-theme-toggle"); + if (btn) btn.textContent = isDark ? "Light Mode" : "Dark Mode"; + } + + function setupThemeToggle() { + var btn = el("btn-theme-toggle"); + if (!btn) return; + btn.addEventListener("click", function () { + var isDark = document.documentElement.dataset.theme !== "light"; + var next = isDark ? "light" : "dark"; + document.documentElement.dataset.theme = next; + localStorage.setItem("theme", next); + applyChartTheme(next === "dark"); + btn.textContent = next === "dark" ? "Light Mode" : "Dark Mode"; + }); + } + // --- Chart.js defaults --- Chart.defaults.color = "#8b949e"; Chart.defaults.borderColor = "#30363d"; @@ -496,6 +538,8 @@ // --- Init --- function init() { initCharts(); + initTheme(); + setupThemeToggle(); setupEventHandlers(); connectWebSocket(); startPolling(); diff --git a/src/mcpbridge_wrapper/webui/static/index.html b/src/mcpbridge_wrapper/webui/static/index.html index de6696e8..cca57714 100644 --- a/src/mcpbridge_wrapper/webui/static/index.html +++ b/src/mcpbridge_wrapper/webui/static/index.html @@ -12,6 +12,7 @@

XcodeMCPWrapper Dashboard

Disconnected +
From 4a66572d6e89296660593bcd8eb7922d3b8e991b Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sun, 15 Feb 2026 19:47:46 +0300 Subject: [PATCH 5/8] Archive task P11-T3: Add Dashboard Theme Toggle (PASS) --- SPECS/ARCHIVE/INDEX.md | 4 +- .../P11-T3_Add_Dashboard_Theme_Toggle.md | 77 +++++++++++++++++++ .../P11-T3_Validation_Report.md | 45 +++++++++++ SPECS/INPROGRESS/next.md | 37 +++------ SPECS/Workplan.md | 2 +- 5 files changed, 135 insertions(+), 30 deletions(-) create mode 100644 SPECS/ARCHIVE/P11-T3_Add_Dashboard_Theme_Toggle/P11-T3_Add_Dashboard_Theme_Toggle.md create mode 100644 SPECS/ARCHIVE/P11-T3_Add_Dashboard_Theme_Toggle/P11-T3_Validation_Report.md diff --git a/SPECS/ARCHIVE/INDEX.md b/SPECS/ARCHIVE/INDEX.md index 44fb7f7b..47c4120b 100644 --- a/SPECS/ARCHIVE/INDEX.md +++ b/SPECS/ARCHIVE/INDEX.md @@ -1,6 +1,6 @@ # mcpbridge-wrapper Tasks Archive -**Last Updated:** 2026-02-15 (P11-T2) +**Last Updated:** 2026-02-15 (P11-T3) ## Archived Tasks @@ -92,6 +92,7 @@ | P11-T1 | [P11-T1_Add_Tool_Call_Detail_Inspector/](P11-T1_Add_Tool_Call_Detail_Inspector/) | 2026-02-15 | PASS | | BUG-T8 | [BUG-T8_Audit_Log_Cross_Process_Visibility/](BUG-T8_Audit_Log_Cross_Process_Visibility/) | 2026-02-15 | PASS | | P11-T2 | [P11-T2_Add_Session_Timeline_View/](P11-T2_Add_Session_Timeline_View/) | 2026-02-15 | PASS | +| P11-T3 | [P11-T3_Add_Dashboard_Theme_Toggle/](P11-T3_Add_Dashboard_Theme_Toggle/) | 2026-02-15 | PASS | ## Historical Artifacts @@ -249,3 +250,4 @@ | 2026-02-15 | BUG-T8 | Archived REVIEW_BUG-T8_audit_log_cross_process report | | 2026-02-15 | P11-T2 | Archived Add_Session_Timeline_View (PASS) | | 2026-02-15 | P11-T2 | Archived REVIEW_P11-T2_session_timeline report | +| 2026-02-15 | P11-T3 | Archived Add_Dashboard_Theme_Toggle (PASS) | diff --git a/SPECS/ARCHIVE/P11-T3_Add_Dashboard_Theme_Toggle/P11-T3_Add_Dashboard_Theme_Toggle.md b/SPECS/ARCHIVE/P11-T3_Add_Dashboard_Theme_Toggle/P11-T3_Add_Dashboard_Theme_Toggle.md new file mode 100644 index 00000000..373f3f47 --- /dev/null +++ b/SPECS/ARCHIVE/P11-T3_Add_Dashboard_Theme_Toggle/P11-T3_Add_Dashboard_Theme_Toggle.md @@ -0,0 +1,77 @@ +# P11-T3: Add Dashboard Theme Toggle (Dark/Light) + +**Priority:** P2 +**Branch:** feature/P11-T3-dashboard-theme-toggle +**Dependencies:** P10-T1 ✅ + +--- + +## Goal + +Implement a CSS-variable-based dark/light theme toggle for the dashboard, storing preference in `localStorage` and syncing Chart.js color defaults on each toggle. + +--- + +## Analysis of Current State + +The CSS already uses CSS custom properties (`--bg-primary`, `--text-primary`, etc.) for most structural colors. A handful of semi-transparent rgba values and hardcoded hex values remain in the JS (Chart.js defaults, grid colors). + +**Remaining hardcoded values to extract:** +- `rgba(63, 185, 80, 0.2)` and `rgba(248, 81, 73, 0.2)` in status badge backgrounds → `--accent-green-bg`, `--accent-red-bg` +- `rgba(248, 81, 73, 0.4)` in timeline error badge border → `--accent-red-border` +- `rgba(88, 166, 255, 0.05/0.06)` row hover → `--row-hover-bg` +- `rgba(88, 166, 255, 0.1)` row active → `--row-active-bg` +- Chart.js: `#8b949e`, `#30363d`, `#21262d` grid colors (to be managed via JS at toggle time) + +--- + +## Deliverables + +### 1. `dashboard.css` +- Add `--accent-green-bg`, `--accent-red-bg`, `--accent-red-border`, `--row-hover-bg`, `--row-active-bg` CSS variables to `:root` (dark defaults) +- Replace all remaining hardcoded rgba/hex in rules with the new variables +- Add `[data-theme="light"]` block on `:root` with light-theme overrides for all variables +- Add `.btn-theme-toggle` styling + +### 2. `dashboard.js` +- Add `THEME_COLORS` constant with dark/light chart color configs (text label color, border color, grid color) +- Add `applyChartTheme(isDark)` function: updates `Chart.defaults.color`, `Chart.defaults.borderColor`, and each chart's grid color options, then re-renders +- Add `initTheme()`: reads `localStorage.getItem("theme")`, defaults to `"dark"`, sets `document.documentElement.dataset.theme`, calls `applyChartTheme`, updates button label +- Add `setupThemeToggle()`: wire `btn-theme-toggle` click to toggle `data-theme` between `"dark"/"light"`, persist to `localStorage`, call `applyChartTheme`, update button label +- Call `initTheme()` and `setupThemeToggle()` from `init()` + +### 3. `index.html` +- Add `` in `.header-controls` before the reset-metrics button + +--- + +## Light Theme Color Values + +| Variable | Dark | Light | +|-----------------------|-------------------|-----------| +| `--bg-primary` | `#0d1117` | `#ffffff` | +| `--bg-secondary` | `#161b22` | `#f6f8fa` | +| `--bg-card` | `#1c2128` | `#ffffff` | +| `--border-color` | `#30363d` | `#d0d7de` | +| `--text-primary` | `#e6edf3` | `#1f2328` | +| `--text-secondary` | `#8b949e` | `#636e7b` | +| `--accent-green-bg` | `rgba(63,185,80,0.2)` | `rgba(63,185,80,0.15)` | +| `--accent-red-bg` | `rgba(248,81,73,0.2)` | `rgba(248,81,73,0.15)` | +| `--accent-red-border` | `rgba(248,81,73,0.4)` | `rgba(248,81,73,0.5)` | +| `--row-hover-bg` | `rgba(88,166,255,0.06)` | `rgba(88,166,255,0.08)` | +| `--row-active-bg` | `rgba(88,166,255,0.1)` | `rgba(88,166,255,0.15)` | + +Chart.js colors: +- Dark: label `#8b949e`, border `#30363d`, grid `#21262d` +- Light: label `#636e7b`, border `#d0d7de`, grid `#e8ecf0` + +--- + +## Acceptance Criteria + +- [ ] All colors in CSS use custom properties (no hardcoded hex/rgba in rules) +- [ ] Toggle button switches between dark and light themes +- [ ] Chart.js chart colors update on theme change without page reload +- [ ] Theme preference persists across page reloads via `localStorage` +- [ ] Default theme matches current dark theme (no visual regression) +- [ ] Quality gates pass: `pytest`, `ruff check src/`, `pytest --cov` ≥ 90% diff --git a/SPECS/ARCHIVE/P11-T3_Add_Dashboard_Theme_Toggle/P11-T3_Validation_Report.md b/SPECS/ARCHIVE/P11-T3_Add_Dashboard_Theme_Toggle/P11-T3_Validation_Report.md new file mode 100644 index 00000000..7c98348c --- /dev/null +++ b/SPECS/ARCHIVE/P11-T3_Add_Dashboard_Theme_Toggle/P11-T3_Validation_Report.md @@ -0,0 +1,45 @@ +# P11-T3 Validation Report + +**Task:** Add Dashboard Theme Toggle (Dark/Light) +**Date:** 2026-02-15 +**Verdict:** PASS + +--- + +## Changes Implemented + +### `src/mcpbridge_wrapper/webui/static/dashboard.css` +- Added `--accent-green-bg`, `--accent-red-bg`, `--accent-red-border`, `--row-hover-bg`, `--row-active-bg` CSS variables to `:root` +- Added `[data-theme="light"]` block with full light-theme color overrides for all variables +- Replaced all hardcoded `rgba(...)` values in rules with the new CSS variables (status badges, row hover, timeline error badge) +- Added `.btn-theme-toggle` and `.btn-theme-toggle:hover` styling + +### `src/mcpbridge_wrapper/webui/static/index.html` +- Added `` in `.header-controls` + +### `src/mcpbridge_wrapper/webui/static/dashboard.js` +- Added `THEME_COLORS` constant with dark/light Chart.js color configs +- Added `applyChartTheme(isDark)` — updates `Chart.defaults.color`, `Chart.defaults.borderColor`, and grid colors on all active charts, then re-renders +- Added `initTheme()` — reads `localStorage`, sets `document.documentElement.dataset.theme`, calls `applyChartTheme`, syncs button label +- Added `setupThemeToggle()` — wires toggle button click, persists preference to `localStorage` +- Called `initTheme()` and `setupThemeToggle()` from `init()` + +--- + +## Acceptance Criteria + +- [x] All colors in CSS use custom properties (no hardcoded hex/rgba in selectors) +- [x] Toggle button switches between dark and light themes +- [x] Chart.js chart colors update on theme change without page reload +- [x] Theme preference persists across page reloads via `localStorage` +- [x] Default theme matches current dark theme (no visual regression) + +--- + +## Quality Gates + +| Gate | Result | +|------|--------| +| `pytest` | 403 passed, 5 skipped | +| `ruff check src/` | All checks passed | +| `pytest --cov` | 96.2% (≥ 90% required) | diff --git a/SPECS/INPROGRESS/next.md b/SPECS/INPROGRESS/next.md index a584d63a..d09fc6be 100644 --- a/SPECS/INPROGRESS/next.md +++ b/SPECS/INPROGRESS/next.md @@ -1,36 +1,17 @@ -# Active Task +# No Active Task -## Selected Task - -- **ID:** P11-T3 -- **Name:** Add Dashboard Theme Toggle (Dark/Light) -- **Priority:** P2 -- **Dependencies:** P10-T1 ✅ -- **Branch:** feature/P11-T3-dashboard-theme-toggle -- **Selected:** 2026-02-15 - -## Description - -Implement CSS-variable-based theme system with a toggle button in the header. Refactor all hardcoded colors in `dashboard.css` to CSS custom properties on `:root`. Add `[data-theme="light"]` overrides. Store user preference in `localStorage`. Update Chart.js color defaults on theme toggle. - -## Outputs/Artifacts - -- Updated `src/mcpbridge_wrapper/webui/static/dashboard.css` - CSS variable refactor + light theme -- Updated `src/mcpbridge_wrapper/webui/static/dashboard.js` - theme toggle logic and Chart.js color sync -- Updated `src/mcpbridge_wrapper/webui/static/index.html` - theme toggle button in header - -## Acceptance Criteria - -- [ ] All colors in CSS use custom properties (no hardcoded hex in selectors) -- [ ] Toggle button switches between dark and light themes -- [ ] Chart.js chart colors update on theme change without page reload -- [ ] Theme preference persists across page reloads via `localStorage` -- [ ] Default theme matches current dark theme (no visual regression) +The previously selected task has been archived. ## Recently Archived +- 2026-02-15 — P11-T3: Add Dashboard Theme Toggle (Dark/Light) (PASS) - 2026-02-15 — P11-T2: Add Session Timeline View (PASS) - 2026-02-15 — BUG-T8: Audit log cross-process visibility (PASS) - 2026-02-15 — P11-T1: Add Tool Call Detail Inspector (Request/Response Viewer) (PASS) - 2026-02-15 — FU-BUG-T6-1: Document stale-process cleanup for Web UI port collisions (PASS) -- 2026-02-14 — BUG-T7: Unsupported `resources/*` methods can return non-standard error shape (PASS) + +## Suggested Next Tasks + +- P11-T4: Add Keyboard Shortcuts & Command Palette (P3, depends on P10-T1 ✅) +- FU-BUG-T7-1: Cap `pending_methods` map to guard against unbounded growth (P3) +- FU-P11-T1-1: Refactor `_FakeWebUIConfig` test stub to `MagicMock(spec=WebUIConfig)` (P3) diff --git a/SPECS/Workplan.md b/SPECS/Workplan.md index 344ac247..90e98800 100644 --- a/SPECS/Workplan.md +++ b/SPECS/Workplan.md @@ -1629,7 +1629,7 @@ Phase 9 Follow-up Backlog --- -#### P11-T3: Add Dashboard Theme Toggle (Dark/Light) +#### ✅ P11-T3: Add Dashboard Theme Toggle (Dark/Light) - **Description:** Implement CSS-variable-based theme system with a toggle button in the header. Refactor all hardcoded colors in `dashboard.css` to CSS custom properties on `:root`. Add `[data-theme="light"]` overrides. Store user preference in `localStorage`. Update Chart.js color defaults on theme toggle. - **Priority:** P2 - **Dependencies:** P10-T1 From 8d607874e1104f2bf87de29a44a1c8d6e29f817a Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sun, 15 Feb 2026 19:48:29 +0300 Subject: [PATCH 6/8] Review P11-T3: dashboard theme toggle --- .../REVIEW_P11-T3_dashboard_theme_toggle.md | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 SPECS/INPROGRESS/REVIEW_P11-T3_dashboard_theme_toggle.md diff --git a/SPECS/INPROGRESS/REVIEW_P11-T3_dashboard_theme_toggle.md b/SPECS/INPROGRESS/REVIEW_P11-T3_dashboard_theme_toggle.md new file mode 100644 index 00000000..c0c2cd04 --- /dev/null +++ b/SPECS/INPROGRESS/REVIEW_P11-T3_dashboard_theme_toggle.md @@ -0,0 +1,46 @@ +## REVIEW REPORT — P11-T3 Dashboard Theme Toggle + +**Scope:** origin/main..HEAD (commit 5ef0fda) +**Files:** 3 (dashboard.css, dashboard.js, index.html) + +### Summary Verdict +- [x] Approve +- [ ] Approve with comments +- [ ] Request changes +- [ ] Block + +--- + +### Critical Issues + +None. + +--- + +### Secondary Issues + +None. + +--- + +### Architectural Notes + +- **`[data-theme]` on `:root`** — The CSS selector `[data-theme="light"]` targets `:root` (``), and `document.documentElement.dataset.theme` sets the attribute on ``. These are the same element; the pattern is correct and aligns with standard CSS theming practice. +- **`applyChartTheme` timing** — `init()` calls `initCharts()` before `initTheme()`, ensuring all chart instances exist when `applyChartTheme` iterates `Object.values(charts)`. Ordering is correct. +- **`THEME_COLORS` constant** — Centralized color config for Chart.js is a good pattern. If chart palettes change in future, one location to update. +- **`btn-warning:hover` rgba** — `rgba(210, 153, 34, 0.15)` remains hardcoded for the reset-button hover. This is acceptable: yellow hover is legible on both dark and light backgrounds and doesn't require a new CSS variable. +- **`Chart.defaults` at module load** — Defaults are set to dark at module boot, then `initTheme()` re-applies the persisted theme immediately. The double-set for dark default (no localStorage) is a harmless no-op. + +--- + +### Tests + +- No Python backend changes — all 403 tests pass, 96.2% coverage (≥90% threshold). +- Frontend-only changes (CSS/JS/HTML); no new Python tests required. +- Manual verification paths: toggle button visible in header; `data-theme` attribute switches on click; `localStorage.theme` persists; chart grid colors update; button label flips correctly. + +--- + +### Next Steps + +No actionable findings — FOLLOW-UP skipped. From 75b798aca48e0af030bad601e918bc97ef0fab31 Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sun, 15 Feb 2026 19:48:48 +0300 Subject: [PATCH 7/8] Archive REVIEW_P11-T3_dashboard_theme_toggle report --- SPECS/ARCHIVE/INDEX.md | 2 + .../REVIEW_P11-T3_dashboard_theme_toggle.md | 46 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 SPECS/ARCHIVE/P11-T3_Add_Dashboard_Theme_Toggle/REVIEW_P11-T3_dashboard_theme_toggle.md diff --git a/SPECS/ARCHIVE/INDEX.md b/SPECS/ARCHIVE/INDEX.md index 47c4120b..bd8e9bbe 100644 --- a/SPECS/ARCHIVE/INDEX.md +++ b/SPECS/ARCHIVE/INDEX.md @@ -149,6 +149,7 @@ | [REVIEW_P11-T1_tool_call_detail_inspector.md](P11-T1_Add_Tool_Call_Detail_Inspector/REVIEW_P11-T1_tool_call_detail_inspector.md) | Review report for P11-T1 | | [REVIEW_BUG-T8_audit_log_cross_process.md](BUG-T8_Audit_Log_Cross_Process_Visibility/REVIEW_BUG-T8_audit_log_cross_process.md) | Review report for BUG-T8 | | [REVIEW_P11-T2_session_timeline.md](P11-T2_Add_Session_Timeline_View/REVIEW_P11-T2_session_timeline.md) | Review report for P11-T2 | +| [REVIEW_P11-T3_dashboard_theme_toggle.md](P11-T3_Add_Dashboard_Theme_Toggle/REVIEW_P11-T3_dashboard_theme_toggle.md) | Review report for P11-T3 | ## Archive Log @@ -251,3 +252,4 @@ | 2026-02-15 | P11-T2 | Archived Add_Session_Timeline_View (PASS) | | 2026-02-15 | P11-T2 | Archived REVIEW_P11-T2_session_timeline report | | 2026-02-15 | P11-T3 | Archived Add_Dashboard_Theme_Toggle (PASS) | +| 2026-02-15 | P11-T3 | Archived REVIEW_P11-T3_dashboard_theme_toggle report | diff --git a/SPECS/ARCHIVE/P11-T3_Add_Dashboard_Theme_Toggle/REVIEW_P11-T3_dashboard_theme_toggle.md b/SPECS/ARCHIVE/P11-T3_Add_Dashboard_Theme_Toggle/REVIEW_P11-T3_dashboard_theme_toggle.md new file mode 100644 index 00000000..c0c2cd04 --- /dev/null +++ b/SPECS/ARCHIVE/P11-T3_Add_Dashboard_Theme_Toggle/REVIEW_P11-T3_dashboard_theme_toggle.md @@ -0,0 +1,46 @@ +## REVIEW REPORT — P11-T3 Dashboard Theme Toggle + +**Scope:** origin/main..HEAD (commit 5ef0fda) +**Files:** 3 (dashboard.css, dashboard.js, index.html) + +### Summary Verdict +- [x] Approve +- [ ] Approve with comments +- [ ] Request changes +- [ ] Block + +--- + +### Critical Issues + +None. + +--- + +### Secondary Issues + +None. + +--- + +### Architectural Notes + +- **`[data-theme]` on `:root`** — The CSS selector `[data-theme="light"]` targets `:root` (``), and `document.documentElement.dataset.theme` sets the attribute on ``. These are the same element; the pattern is correct and aligns with standard CSS theming practice. +- **`applyChartTheme` timing** — `init()` calls `initCharts()` before `initTheme()`, ensuring all chart instances exist when `applyChartTheme` iterates `Object.values(charts)`. Ordering is correct. +- **`THEME_COLORS` constant** — Centralized color config for Chart.js is a good pattern. If chart palettes change in future, one location to update. +- **`btn-warning:hover` rgba** — `rgba(210, 153, 34, 0.15)` remains hardcoded for the reset-button hover. This is acceptable: yellow hover is legible on both dark and light backgrounds and doesn't require a new CSS variable. +- **`Chart.defaults` at module load** — Defaults are set to dark at module boot, then `initTheme()` re-applies the persisted theme immediately. The double-set for dark default (no localStorage) is a harmless no-op. + +--- + +### Tests + +- No Python backend changes — all 403 tests pass, 96.2% coverage (≥90% threshold). +- Frontend-only changes (CSS/JS/HTML); no new Python tests required. +- Manual verification paths: toggle button visible in header; `data-theme` attribute switches on click; `localStorage.theme` persists; chart grid colors update; button label flips correctly. + +--- + +### Next Steps + +No actionable findings — FOLLOW-UP skipped. From 0732faeef6ee74911c238116bf697d092e92e936 Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sun, 15 Feb 2026 20:55:30 +0300 Subject: [PATCH 8/8] Remove P11-T3 INPROGRESS files after archive --- .../P11-T3_Add_Dashboard_Theme_Toggle.md | 77 ------------------- SPECS/INPROGRESS/P11-T3_Validation_Report.md | 45 ----------- .../REVIEW_P11-T3_dashboard_theme_toggle.md | 46 ----------- 3 files changed, 168 deletions(-) delete mode 100644 SPECS/INPROGRESS/P11-T3_Add_Dashboard_Theme_Toggle.md delete mode 100644 SPECS/INPROGRESS/P11-T3_Validation_Report.md delete mode 100644 SPECS/INPROGRESS/REVIEW_P11-T3_dashboard_theme_toggle.md diff --git a/SPECS/INPROGRESS/P11-T3_Add_Dashboard_Theme_Toggle.md b/SPECS/INPROGRESS/P11-T3_Add_Dashboard_Theme_Toggle.md deleted file mode 100644 index 373f3f47..00000000 --- a/SPECS/INPROGRESS/P11-T3_Add_Dashboard_Theme_Toggle.md +++ /dev/null @@ -1,77 +0,0 @@ -# P11-T3: Add Dashboard Theme Toggle (Dark/Light) - -**Priority:** P2 -**Branch:** feature/P11-T3-dashboard-theme-toggle -**Dependencies:** P10-T1 ✅ - ---- - -## Goal - -Implement a CSS-variable-based dark/light theme toggle for the dashboard, storing preference in `localStorage` and syncing Chart.js color defaults on each toggle. - ---- - -## Analysis of Current State - -The CSS already uses CSS custom properties (`--bg-primary`, `--text-primary`, etc.) for most structural colors. A handful of semi-transparent rgba values and hardcoded hex values remain in the JS (Chart.js defaults, grid colors). - -**Remaining hardcoded values to extract:** -- `rgba(63, 185, 80, 0.2)` and `rgba(248, 81, 73, 0.2)` in status badge backgrounds → `--accent-green-bg`, `--accent-red-bg` -- `rgba(248, 81, 73, 0.4)` in timeline error badge border → `--accent-red-border` -- `rgba(88, 166, 255, 0.05/0.06)` row hover → `--row-hover-bg` -- `rgba(88, 166, 255, 0.1)` row active → `--row-active-bg` -- Chart.js: `#8b949e`, `#30363d`, `#21262d` grid colors (to be managed via JS at toggle time) - ---- - -## Deliverables - -### 1. `dashboard.css` -- Add `--accent-green-bg`, `--accent-red-bg`, `--accent-red-border`, `--row-hover-bg`, `--row-active-bg` CSS variables to `:root` (dark defaults) -- Replace all remaining hardcoded rgba/hex in rules with the new variables -- Add `[data-theme="light"]` block on `:root` with light-theme overrides for all variables -- Add `.btn-theme-toggle` styling - -### 2. `dashboard.js` -- Add `THEME_COLORS` constant with dark/light chart color configs (text label color, border color, grid color) -- Add `applyChartTheme(isDark)` function: updates `Chart.defaults.color`, `Chart.defaults.borderColor`, and each chart's grid color options, then re-renders -- Add `initTheme()`: reads `localStorage.getItem("theme")`, defaults to `"dark"`, sets `document.documentElement.dataset.theme`, calls `applyChartTheme`, updates button label -- Add `setupThemeToggle()`: wire `btn-theme-toggle` click to toggle `data-theme` between `"dark"/"light"`, persist to `localStorage`, call `applyChartTheme`, update button label -- Call `initTheme()` and `setupThemeToggle()` from `init()` - -### 3. `index.html` -- Add `` in `.header-controls` before the reset-metrics button - ---- - -## Light Theme Color Values - -| Variable | Dark | Light | -|-----------------------|-------------------|-----------| -| `--bg-primary` | `#0d1117` | `#ffffff` | -| `--bg-secondary` | `#161b22` | `#f6f8fa` | -| `--bg-card` | `#1c2128` | `#ffffff` | -| `--border-color` | `#30363d` | `#d0d7de` | -| `--text-primary` | `#e6edf3` | `#1f2328` | -| `--text-secondary` | `#8b949e` | `#636e7b` | -| `--accent-green-bg` | `rgba(63,185,80,0.2)` | `rgba(63,185,80,0.15)` | -| `--accent-red-bg` | `rgba(248,81,73,0.2)` | `rgba(248,81,73,0.15)` | -| `--accent-red-border` | `rgba(248,81,73,0.4)` | `rgba(248,81,73,0.5)` | -| `--row-hover-bg` | `rgba(88,166,255,0.06)` | `rgba(88,166,255,0.08)` | -| `--row-active-bg` | `rgba(88,166,255,0.1)` | `rgba(88,166,255,0.15)` | - -Chart.js colors: -- Dark: label `#8b949e`, border `#30363d`, grid `#21262d` -- Light: label `#636e7b`, border `#d0d7de`, grid `#e8ecf0` - ---- - -## Acceptance Criteria - -- [ ] All colors in CSS use custom properties (no hardcoded hex/rgba in rules) -- [ ] Toggle button switches between dark and light themes -- [ ] Chart.js chart colors update on theme change without page reload -- [ ] Theme preference persists across page reloads via `localStorage` -- [ ] Default theme matches current dark theme (no visual regression) -- [ ] Quality gates pass: `pytest`, `ruff check src/`, `pytest --cov` ≥ 90% diff --git a/SPECS/INPROGRESS/P11-T3_Validation_Report.md b/SPECS/INPROGRESS/P11-T3_Validation_Report.md deleted file mode 100644 index 7c98348c..00000000 --- a/SPECS/INPROGRESS/P11-T3_Validation_Report.md +++ /dev/null @@ -1,45 +0,0 @@ -# P11-T3 Validation Report - -**Task:** Add Dashboard Theme Toggle (Dark/Light) -**Date:** 2026-02-15 -**Verdict:** PASS - ---- - -## Changes Implemented - -### `src/mcpbridge_wrapper/webui/static/dashboard.css` -- Added `--accent-green-bg`, `--accent-red-bg`, `--accent-red-border`, `--row-hover-bg`, `--row-active-bg` CSS variables to `:root` -- Added `[data-theme="light"]` block with full light-theme color overrides for all variables -- Replaced all hardcoded `rgba(...)` values in rules with the new CSS variables (status badges, row hover, timeline error badge) -- Added `.btn-theme-toggle` and `.btn-theme-toggle:hover` styling - -### `src/mcpbridge_wrapper/webui/static/index.html` -- Added `` in `.header-controls` - -### `src/mcpbridge_wrapper/webui/static/dashboard.js` -- Added `THEME_COLORS` constant with dark/light Chart.js color configs -- Added `applyChartTheme(isDark)` — updates `Chart.defaults.color`, `Chart.defaults.borderColor`, and grid colors on all active charts, then re-renders -- Added `initTheme()` — reads `localStorage`, sets `document.documentElement.dataset.theme`, calls `applyChartTheme`, syncs button label -- Added `setupThemeToggle()` — wires toggle button click, persists preference to `localStorage` -- Called `initTheme()` and `setupThemeToggle()` from `init()` - ---- - -## Acceptance Criteria - -- [x] All colors in CSS use custom properties (no hardcoded hex/rgba in selectors) -- [x] Toggle button switches between dark and light themes -- [x] Chart.js chart colors update on theme change without page reload -- [x] Theme preference persists across page reloads via `localStorage` -- [x] Default theme matches current dark theme (no visual regression) - ---- - -## Quality Gates - -| Gate | Result | -|------|--------| -| `pytest` | 403 passed, 5 skipped | -| `ruff check src/` | All checks passed | -| `pytest --cov` | 96.2% (≥ 90% required) | diff --git a/SPECS/INPROGRESS/REVIEW_P11-T3_dashboard_theme_toggle.md b/SPECS/INPROGRESS/REVIEW_P11-T3_dashboard_theme_toggle.md deleted file mode 100644 index c0c2cd04..00000000 --- a/SPECS/INPROGRESS/REVIEW_P11-T3_dashboard_theme_toggle.md +++ /dev/null @@ -1,46 +0,0 @@ -## REVIEW REPORT — P11-T3 Dashboard Theme Toggle - -**Scope:** origin/main..HEAD (commit 5ef0fda) -**Files:** 3 (dashboard.css, dashboard.js, index.html) - -### Summary Verdict -- [x] Approve -- [ ] Approve with comments -- [ ] Request changes -- [ ] Block - ---- - -### Critical Issues - -None. - ---- - -### Secondary Issues - -None. - ---- - -### Architectural Notes - -- **`[data-theme]` on `:root`** — The CSS selector `[data-theme="light"]` targets `:root` (``), and `document.documentElement.dataset.theme` sets the attribute on ``. These are the same element; the pattern is correct and aligns with standard CSS theming practice. -- **`applyChartTheme` timing** — `init()` calls `initCharts()` before `initTheme()`, ensuring all chart instances exist when `applyChartTheme` iterates `Object.values(charts)`. Ordering is correct. -- **`THEME_COLORS` constant** — Centralized color config for Chart.js is a good pattern. If chart palettes change in future, one location to update. -- **`btn-warning:hover` rgba** — `rgba(210, 153, 34, 0.15)` remains hardcoded for the reset-button hover. This is acceptable: yellow hover is legible on both dark and light backgrounds and doesn't require a new CSS variable. -- **`Chart.defaults` at module load** — Defaults are set to dark at module boot, then `initTheme()` re-applies the persisted theme immediately. The double-set for dark default (no localStorage) is a harmless no-op. - ---- - -### Tests - -- No Python backend changes — all 403 tests pass, 96.2% coverage (≥90% threshold). -- Frontend-only changes (CSS/JS/HTML); no new Python tests required. -- Manual verification paths: toggle button visible in header; `data-theme` attribute switches on click; `localStorage.theme` persists; chart grid colors update; button label flips correctly. - ---- - -### Next Steps - -No actionable findings — FOLLOW-UP skipped.