Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# PRD: BUG-T18 — Error Breakdown full-width layout fix

## Objective
Implement the Web UI layout change so the "Error Breakdown" widget is rendered as a full-width chart card in the dashboard, not as a half-width card inside the two-column chart grid. The fix must preserve existing responsive behavior across desktop, tablet, and mobile breakpoints and avoid regressions in dashboard rendering.

Scope is limited to frontend dashboard assets and associated regression tests:
- `src/mcpbridge_wrapper/webui/static/index.html`
- `src/mcpbridge_wrapper/webui/static/dashboard.css`
- Relevant web UI unit tests that validate served dashboard markup/contracts.

Out of scope:
- Backend metrics aggregation logic
- Chart data semantics
- Non-layout redesign of dashboard widgets

## Success Criteria
- Error Breakdown card spans the full row width in the charts layout at non-mobile breakpoints.
- Existing Tool Usage (Bar) and Tool Distribution (Pie) widgets remain correctly rendered.
- Mobile layout (`<=768px`) remains single-column and unaffected.
- Regression test coverage exists for the full-width Error Breakdown layout contract.
- All quality gates pass with coverage remaining >= 90%.

## Acceptance Tests
1. Inspect served dashboard HTML and verify Error Breakdown container uses the full-width layout class.
2. Verify CSS rules still allow full-width containers via `grid-column: 1 / -1`.
3. Manual smoke check at representative widths: `1450px`, `1200px`, `1024px`, `768px`, and narrow mobile.
4. Run quality gates:
- `pytest`
- `ruff check src/`
- `mypy src/`
- `pytest --cov`

## Test-First Plan
1. Add or extend a server/web UI unit test that asserts the served dashboard markup encodes a full-width Error Breakdown container.
2. Run targeted test module to validate the new assertion fails before layout update (or verify current state is missing the contract).
3. Apply minimal markup/CSS updates to satisfy the failing test.
4. Re-run targeted tests, then full quality gates.

## Execution Plan
### Phase 1: Baseline and Contract Definition
- Inputs: current dashboard HTML/CSS and web UI tests.
- Outputs: explicit layout contract for Error Breakdown full-width behavior.
- Verification: targeted test captures required class/layout structure.

### Phase 2: Layout Implementation
- Inputs: chart row markup and existing `.chart-container.wide` CSS behavior.
- Outputs: Error Breakdown widget updated to opt into full-width spanning without changing data bindings.
- Verification: served HTML and manual viewport checks confirm full-width rendering.

### Phase 3: Regression and Validation
- Inputs: updated tests and quality gate commands.
- Outputs: passing tests, lint/type checks, and coverage report; validation report artifact.
- Verification: command outputs recorded with PASS verdict and coverage >= 90%.

## Constraints and Decisions
- Reuse existing `wide` layout contract instead of introducing a new custom layout system.
- Keep changes minimal and local to avoid unintended visual regressions.
- Preserve existing chart IDs and JS hooks to avoid runtime chart initialization breakage.

## Notes
- Update `SPECS/Workplan.md` status fields for BUG-T18 during ARCHIVE.
- If additional chart-grid responsiveness issues are discovered, track them as separate follow-up tasks rather than extending BUG-T18 scope.

---
**Archived:** 2026-02-26
**Verdict:** PASS
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Validation Report: BUG-T18

## Task
Error Breakdown widget must be full width streatched.

## Implementation Summary
- Updated dashboard markup so the Error Breakdown container now uses the existing full-width grid contract (`chart-container wide`) with a stable container ID.
- Added a regression test in `tests/unit/webui/test_server.py` to enforce that the served dashboard HTML keeps Error Breakdown as a full-width chart container.
- Preserved existing chart IDs and JS hooks (`chart-error-breakdown`) to avoid runtime behavior changes.

## Quality Gates

### 1) `PYTHONPATH=src pytest`
- Result: PASS
- Evidence: `652 passed, 5 skipped`

### 2) `ruff check src/`
- Result: PASS
- Evidence: `All checks passed!`

### 3) `mypy src/`
- Result: PASS
- Evidence: `Success: no issues found in 18 source files`

### 4) `PYTHONPATH=src pytest --cov`
- Result: PASS
- Evidence:
- `652 passed, 5 skipped`
- `Required test coverage of 90.0% reached`
- `Total coverage: 91.33%`

## Validation Notes
- Test-first flow was followed:
- Added regression test for full-width Error Breakdown container.
- Confirmed it failed before markup change.
- Applied layout fix and confirmed the test passed.
- Full-width behavior is implemented via existing `.chart-container.wide { grid-column: 1 / -1; }` layout rule, preserving responsive behavior conventions already used by timeline/latency charts.

## Verdict
PASS
6 changes: 5 additions & 1 deletion SPECS/ARCHIVE/INDEX.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# mcpbridge-wrapper Tasks Archive

**Last Updated:** 2026-02-25 (BUG-T20_Session_Timeline_can_show_negative_duration_due_to_incorrect_entry_ordering)
**Last Updated:** 2026-02-26 (BUG-T18_Error_Breakdown_full_width_layout_fix)

## Archived Tasks

| Task ID | Folder | Archived | Verdict |
|---------|--------|----------|---------|
| BUG-T18 | [BUG-T18_Error_Breakdown_full_width_layout_fix/](BUG-T18_Error_Breakdown_full_width_layout_fix/) | 2026-02-26 | PASS |
| BUG-T20 | [BUG-T20_Session_Timeline_can_show_negative_duration_due_to_incorrect_entry_ordering/](BUG-T20_Session_Timeline_can_show_negative_duration_due_to_incorrect_entry_ordering/) | 2026-02-25 | PASS |
| BUG-T19 | [BUG-T19_Audit_Log_and_Session_Timeline_are_inconsistent_with_tool_charts_in_multi_process_runs/](BUG-T19_Audit_Log_and_Session_Timeline_are_inconsistent_with_tool_charts_in_multi_process_runs/) | 2026-02-25 | PASS |
| BUG-T13 | [BUG-T13_Per-Tool_Latency_Statistics_does_not_show_params_when_capture_params_is_false/](BUG-T13_Per-Tool_Latency_Statistics_does_not_show_params_when_capture_params_is_false/) | 2026-02-25 | PASS |
Expand Down Expand Up @@ -251,6 +252,7 @@
| [REVIEW_bug_t15_webui_port_config.md](_Historical/REVIEW_bug_t15_webui_port_config.md) | Review report for BUG-T15 |
| [REVIEW_bug_t16_pie_responsive.md](_Historical/REVIEW_bug_t16_pie_responsive.md) | Review report for BUG-T16 |
| [REVIEW_bug_t18_workplan_entry.md](_Historical/REVIEW_bug_t18_workplan_entry.md) | Review report for BUG-T18 |
| [REVIEW_bug_t18_error_breakdown_layout.md](_Historical/REVIEW_bug_t18_error_breakdown_layout.md) | Review report for BUG-T18 full-width layout fix |
| [REVIEW_bug_t17_audit_log_rows_stay_unfolded.md](_Historical/REVIEW_bug_t17_audit_log_rows_stay_unfolded.md) | Review report for BUG-T17 |
| [REVIEW_bug_t14_latency_rows.md](_Historical/REVIEW_bug_t14_latency_rows.md) | Review report for BUG-T14 |
| [REVIEW_bug_t20_session_timeline_ordering.md](_Historical/REVIEW_bug_t20_session_timeline_ordering.md) | Review report for BUG-T20 |
Expand All @@ -265,6 +267,8 @@

| Date | Task ID | Action |
|------|---------|--------|
| 2026-02-26 | BUG-T18 | Archived REVIEW_bug_t18_error_breakdown_layout report |
| 2026-02-26 | BUG-T18 | Archived Error_Breakdown_full_width_layout_fix (PASS) |
| 2026-02-25 | BUG-T20 | Archived REVIEW_bug_t20_session_timeline_ordering report |
| 2026-02-25 | BUG-T20 | Archived Session_Timeline_can_show_negative_duration_due_to_incorrect_entry_ordering (PASS) |
| 2026-02-25 | BUG-T19 | Archived REVIEW_bug_t19_audit_session_consistency report |
Expand Down
29 changes: 29 additions & 0 deletions SPECS/ARCHIVE/_Historical/REVIEW_bug_t18_error_breakdown_layout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
## REVIEW REPORT — BUG-T18 Error Breakdown Layout

**Scope:** origin/main..HEAD
**Files:** 7

### Summary Verdict
- [x] Approve
- [ ] Approve with comments
- [ ] Request changes
- [ ] Block

### Critical Issues
- None.

### Secondary Issues
- None.

### Architectural Notes
- The implementation reuses the existing `.chart-container.wide` grid contract, which is already the dashboard’s established mechanism for full-width chart cards.
- A dedicated regression assertion on served dashboard markup keeps this layout requirement explicit and low-maintenance.

### Tests
- `PYTHONPATH=src pytest` — PASS (`652 passed, 5 skipped`)
- `ruff check src/` — PASS
- `mypy src/` — PASS
- `PYTHONPATH=src pytest --cov` — PASS (`91.33%`, requirement `>=90%`)

### Next Steps
- FOLLOW-UP is skipped because no actionable review findings were identified.
3 changes: 1 addition & 2 deletions SPECS/INPROGRESS/next.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@

## Recently Archived

- **BUG-T18** — Error Breakdown widget must be full width streatched (2026-02-26, PASS)
- **BUG-T20** — Session Timeline can show negative duration due to incorrect entry ordering (2026-02-25, PASS)
- **BUG-T19** — Audit Log and Session Timeline are inconsistent with tool charts in multi-process runs (2026-02-25, PASS)
- **BUG-T13** — Per-Tool Latency Statistics does not show params when `capture_params` is false (2026-02-25, PASS)

## Suggested Next Tasks

- BUG-T18 — Error Breakdown widget must be full width streatched
- BUG-T4 — Repeated Xcode permission prompts for each short-lived MCP client process
- BUG-T1 — Kimi CLI MCP Connection Failure
13 changes: 7 additions & 6 deletions SPECS/Workplan.md
Original file line number Diff line number Diff line change
Expand Up @@ -1598,11 +1598,12 @@ Temporarily increase dashboard refresh interval via config to reduce frequency o

---

### BUG-T18: Error Breakdown widget must be full width streatched
### BUG-T18: Error Breakdown widget must be full width streatched
- **Type:** Bug / Web UI / Layout
- **Status:** 🔴 Open
- **Status:** ✅ Fixed (2026-02-26)
- **Priority:** P2
- **Discovered:** 2026-02-20
- **Completed:** 2026-02-26
- **Component:** Web UI Dashboard (`webui/static/index.html`, `webui/static/dashboard.css`)
- **Affected Clients:** All clients using Web UI dashboard
- **Affected Surface:** Error Breakdown widget
Expand All @@ -1623,10 +1624,10 @@ Likely the widget container is using the default chart card class and is not mar
None.

#### Resolution Path
- [ ] Reproduce on current dashboard layout and confirm non-full-width rendering
- [ ] Update chart container/layout rules so Error Breakdown spans full width
- [ ] Validate responsive behavior at desktop/tablet/mobile breakpoints
- [ ] Add regression coverage for full-width Error Breakdown layout
- [x] Reproduce on current dashboard layout and confirm non-full-width rendering
- [x] Update chart container/layout rules so Error Breakdown spans full width
- [x] Validate responsive behavior at desktop/tablet/mobile breakpoints
- [x] Add regression coverage for full-width Error Breakdown layout

#### Related Items
- **P10-T1** ✅ — Web UI dashboard chart layout baseline
Expand Down
2 changes: 1 addition & 1 deletion src/mcpbridge_wrapper/webui/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ <h3>Tool Usage (Bar)</h3>
<h3>Tool Distribution (Pie)</h3>
<canvas id="chart-tool-pie"></canvas>
</div>
<div class="chart-container">
<div class="chart-container wide" id="chart-error-breakdown-container">
<h3>Error Breakdown</h3>
<canvas id="chart-error-breakdown"></canvas>
<div id="error-breakdown-empty" class="chart-empty-msg">No errors recorded</div>
Expand Down
10 changes: 10 additions & 0 deletions tests/unit/webui/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,16 @@ def test_dashboard_served(self, client):
assert "/static/dashboard.css" in response.text
assert "/static/dashboard.js" in response.text

def test_dashboard_error_breakdown_widget_is_full_width(self, client):
"""Error Breakdown chart container spans full width in charts layout."""
response = client.get("/")
assert response.status_code == 200
assert (
'<div class="chart-container wide" id="chart-error-breakdown-container">'
in response.text
)
assert '<canvas id="chart-error-breakdown"></canvas>' in response.text

def test_dashboard_js_uses_uniform_client_widget_escaping(self, client):
"""Client widget interpolations in dashboard.js use escapeHtml uniformly."""
response = client.get("/static/dashboard.js")
Expand Down