From 0e0ddaac8fa07494ef797b2f6293c0701fcff62e Mon Sep 17 00:00:00 2001 From: Tranquil-Flow Date: Sun, 10 May 2026 08:28:48 -0700 Subject: [PATCH] fix(kanban-dashboard): tone down completed-run metadata panel (#19548) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hand-rebased onto current main from PR #19980; the original branch was stale against main (~6 unrelated dashboard fixes had landed since), so applying the PR's dist files directly would have silently reverted them. The run-history panel in the task drawer rendered each completed run's `metadata` field as a `` containing `JSON.stringify(r.metadata)` — a single unindented monoline. With `white-space: pre-wrap` and a monospace font, a writer task's metadata (changed_files paths, source URLs, generated-artifact details) wrapped into a tall block of code-ish text that filled the parent run row. The container's faint `--color-foreground 3%` background then made the whole thing read like a crash dump even though the run completed normally. Restyle and label, no interactivity changes: - Wrap the meta payload in a `.hermes-kanban-run-meta-block` sub-block with an explicit `Metadata` label (small, uppercase, muted) so the panel reads as auxiliary detail at a glance. - Pretty-print the JSON (`indent=2`) so the structure is scannable instead of a wall of monoline text. - Cap `.hermes-kanban-run-meta` at `max-height: 8.5rem; overflow: auto` so a verbose blob scrolls inside its own pane rather than swamping the run row. - Sub-block uses a thin `border-left` rule and `background: transparent` — distinct from the destructive-tinted treatment used by crashed / timed_out / blocked / spawn_failed runs higher in the same file. Tests: two new static-asset assertions in `tests/plugins/test_kanban_dashboard_plugin.py` lock in the rendered shape (the plugin ships built-only, no src/). --- plugins/kanban/dashboard/dist/index.js | 7 ++- plugins/kanban/dashboard/dist/style.css | 24 +++++++++- tests/plugins/test_kanban_dashboard_plugin.py | 48 +++++++++++++++++++ 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/plugins/kanban/dashboard/dist/index.js b/plugins/kanban/dashboard/dist/index.js index 1f0b4c6d3b5..71adc77a666 100644 --- a/plugins/kanban/dashboard/dist/index.js +++ b/plugins/kanban/dashboard/dist/index.js @@ -2398,8 +2398,11 @@ ? h("div", { className: "hermes-kanban-run-error" }, r.error) : null, r.metadata - ? h("code", { className: "hermes-kanban-run-meta" }, - JSON.stringify(r.metadata)) + ? h("div", { className: "hermes-kanban-run-meta-block" }, + h("div", { className: "hermes-kanban-run-meta-label" }, "Metadata"), + h("code", { className: "hermes-kanban-run-meta" }, + JSON.stringify(r.metadata, null, 2)), + ) : null, ); }), diff --git a/plugins/kanban/dashboard/dist/style.css b/plugins/kanban/dashboard/dist/style.css index cb88bdfa5dd..3233facb53c 100644 --- a/plugins/kanban/dashboard/dist/style.css +++ b/plugins/kanban/dashboard/dist/style.css @@ -863,15 +863,37 @@ padding: 0.15rem 0 0; font-family: var(--font-mono, ui-monospace, monospace); } +/* Run metadata is a secondary detail panel. Render it as a clearly-labeled + * sub-block with a thin left rule, capped height, and muted treatment so + * a verbose JSON blob (e.g. changed_files + URLs from a writer task) does + * not visually swamp the parent run row or get mistaken for a crash dump. + * See issue #19548. */ +.hermes-kanban-run-meta-block { + margin-top: 0.4rem; + padding: 0.25rem 0.5rem; + border-left: 2px solid var(--color-border); + background: transparent; +} +.hermes-kanban-run-meta-label { + font-size: 0.65rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.06em; + color: var(--color-muted-foreground); + padding-bottom: 0.15rem; +} .hermes-kanban-run-meta { display: block; + max-height: 8.5rem; + overflow: auto; font-size: 0.72rem; line-height: 1.5; - padding: 0.15rem 0 0; + padding: 0; color: var(--color-muted-foreground); white-space: pre-wrap; word-break: break-word; font-family: var(--font-mono, ui-monospace, monospace); + background: transparent; } /* ------------------------------------------------------------------------- diff --git a/tests/plugins/test_kanban_dashboard_plugin.py b/tests/plugins/test_kanban_dashboard_plugin.py index 0fc6c493c14..9eb4ac45a97 100644 --- a/tests/plugins/test_kanban_dashboard_plugin.py +++ b/tests/plugins/test_kanban_dashboard_plugin.py @@ -1785,3 +1785,51 @@ def test_dashboard_lane_head_preserves_assignee_casing(): "Lane head must not visually uppercase profile names — see #21320 " "and the explanatory comment in the CSS rule." ) + + +# --------------------------------------------------------------------------- +# Built-asset regressions for the dashboard's run-history rendering +# (issue #19548 — completed-run metadata used to render as a large pale box +# that read like a crash dump). The plugin ships built-only, so we lock in +# the rendered shape with static assertions on dist/index.js + dist/style.css. +# --------------------------------------------------------------------------- + + +def _dashboard_dist_path(name: str) -> Path: + repo_root = Path(__file__).resolve().parents[2] + p = repo_root / "plugins" / "kanban" / "dashboard" / "dist" / name + assert p.exists(), f"dashboard asset missing: {p}" + return p + + +def test_run_metadata_pretty_printed_with_label(): + """Run-history metadata is pretty-printed JSON inside a labeled sub-block.""" + js = _dashboard_dist_path("index.js").read_text(encoding="utf-8") + # Pretty-printed JSON (indent=2) so a writer task's changed_files + + # URLs blob doesn't render as one wall-of-text monoline. + assert "JSON.stringify(r.metadata, null, 2)" in js + # Explicit label so the panel reads as auxiliary detail, not a crash dump. + assert '"hermes-kanban-run-meta-label"' in js + assert '"Metadata"' in js + # Wrapped in the labelled meta block container. + assert '"hermes-kanban-run-meta-block"' in js + + +def test_run_metadata_secondary_styling(): + """Metadata block is capped, transparent, and visually secondary.""" + css = _dashboard_dist_path("style.css").read_text(encoding="utf-8") + # The label class exists with muted-foreground treatment. + assert ".hermes-kanban-run-meta-label" in css + # Container styling: thin left rule, no opaque highlighted fill that + # could be mistaken for an error/warning panel. + assert ".hermes-kanban-run-meta-block" in css + block_start = css.index(".hermes-kanban-run-meta-block {") + block_decl = css[block_start : block_start + 400] + assert "background: transparent" in block_decl + assert "border-left" in block_decl + # Cap meta height so verbose JSON doesn't sprawl across the run row. + meta_start = css.index(".hermes-kanban-run-meta {") + meta_decl = css[meta_start : meta_start + 400] + assert "max-height" in meta_decl + assert "overflow: auto" in meta_decl + assert "color: var(--color-muted-foreground)" in meta_decl