From a31b2f400f4fb1898b463eeb5c627cafc31886d7 Mon Sep 17 00:00:00 2001 From: "clagentic-builder[bot]" <290147524+clagentic-builder[bot]@users.noreply.github.com> Date: Thu, 2 Jul 2026 18:46:02 -0400 Subject: [PATCH] feat(diagnostics): add per-entry dismiss + clear-all, parity with Notifications panel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Diagnostics panel entries only ever accumulated with no way to clear seen preflight/CLI-stderr warnings. Adds: - stable per-entry id (_nextDiagnosticId) so a rendered item can be located and removed - per-item dismiss (x) control -> dismissDiagnostic(id), removes from the diagnostics array + DOM, restores the empty-state placeholder when the list drains, refreshes the badge - Clear all button in the panel header -> clearAllDiagnostics() Client-side only: unlike Notifications (notification_dismiss / notification_dismiss_all over the websocket), diagnostics have no server-side dismiss contract, so this only mutates in-memory state + DOM. A dismissed diagnostic can legitimately reappear if the next settings-preflight run re-emits the same condition. Does not touch the lr-e901 dedup path (_isDuplicateDiagnostic, DEDUP_WINDOW_MS) or toast rendering — covered by the existing addDiagnostic dedup regression test, which still passes. --- lib/public/css/diagnostics.css | 57 +++++ lib/public/index.html | 5 +- lib/public/modules/diagnostics.js | 99 ++++++++- ...agnostics-dismiss-clear-all-parity.test.js | 205 ++++++++++++++++++ 4 files changed, 361 insertions(+), 5 deletions(-) create mode 100644 test/diagnostics-dismiss-clear-all-parity.test.js diff --git a/lib/public/css/diagnostics.css b/lib/public/css/diagnostics.css index 29165556..8b3b1166 100644 --- a/lib/public/css/diagnostics.css +++ b/lib/public/css/diagnostics.css @@ -56,6 +56,38 @@ min-height: 0; } +/* Header actions group: Clear all + Close, side by side (parity with the + Notifications panel's .notif-banner-clear-all placement). */ +.diagnostics-panel-header-actions { + display: flex; + align-items: center; + gap: 6px; +} + +.diagnostics-panel-clear-all { + display: inline-flex; + align-items: center; + padding: 3px 8px; + background: none; + border: 1px solid var(--border); + border-radius: 999px; + font-family: var(--font-mono, monospace); + font-size: 9.5px; + font-weight: 400; + letter-spacing: 0.06em; + color: var(--text-muted); + cursor: pointer; + transition: color 0.15s, border-color 0.15s; +} +.diagnostics-panel-clear-all:hover { + color: var(--text); + border-color: var(--border-bright, var(--border)); +} +.diagnostics-panel-clear-all:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 1px; +} + /* -------------------------------------------------------- Diagnostic items -------------------------------------------------------- */ @@ -114,6 +146,31 @@ letter-spacing: 0.08em; } +/* Per-entry dismiss (x) control, pushed to the end of the meta row. */ +.diagnostics-item-dismiss { + margin-left: auto; + background: none; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 4px; + flex-shrink: 0; + transition: color 0.15s, background 0.15s; +} +.diagnostics-item-dismiss:hover { + color: var(--text); + background: rgba(var(--overlay-rgb), 0.06); +} +.diagnostics-item-dismiss:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 1px; +} +.diagnostics-item-dismiss .lucide { width: 12px; height: 12px; } + /* Message text */ .diagnostics-message { font-size: 12px; diff --git a/lib/public/index.html b/lib/public/index.html index 5893fdb1..9a9370bc 100644 --- a/lib/public/index.html +++ b/lib/public/index.html @@ -342,7 +342,10 @@