mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-09 03:11:58 +00:00
* feat(kanban): generic diagnostics engine for task distress signals Replaces the hallucination-specific ``warnings`` / ``RecoverySection`` surface (shipped in PR #20232) with a reusable diagnostic-rule engine that covers five distress kinds in v1 and can be extended without touching UI code. The "something's wrong with this task" signal is no longer limited to phantom card ids. Closes the follow-up from #20232 discussion. New module ---------- ``hermes_cli/kanban_diagnostics.py`` — stateless, no-side-effect rule engine. Each rule is a pure function of ``(task, events, runs, now, config) -> list[Diagnostic]``. Registry is a simple list; adding a new distress kind is one function + one import, no UI or API changes required. v1 rule set ----------- * ``hallucinated_cards`` (error) — folds the existing ``completion_blocked_hallucination`` event into the new surface. * ``prose_phantom_refs`` (warning) — folds ``suspected_hallucinated_references``. * ``repeated_spawn_failures`` (error → critical at 2x threshold) — fires when ``tasks.spawn_failures >= 3``; suggests ``hermes -p <profile> doctor`` / ``auth``. * ``repeated_crashes`` (error → critical) — fires after N consecutive ``crashed`` run outcomes with no successful completion between; suggests ``hermes kanban log <id>``. * ``stuck_in_blocked`` (warning) — fires after 24h in ``blocked`` state with no comments / unblock attempts; suggests commenting. Every diagnostic carries structured ``actions`` (reclaim, reassign, unblock, cli_hint, comment, open_docs) that render consistently in both CLI and dashboard. Suggested actions are highlighted; generic recovery actions (reclaim / reassign) are available on every kind as fallbacks. Diagnostics auto-clear when the underlying failure resolves — a clean ``completed``/``edited`` event drops hallucination diagnostics, a successful run drops crash diagnostics, a comment drops stuck-blocked diagnostics. Audit events persist; the badge goes away. API --- ``plugin_api.py``: * ``/board`` now attaches ``diagnostics`` (full list) and ``warnings`` (compact summary with ``highest_severity``) per task. * ``/tasks/{id}`` attaches diagnostics so the drawer's Diagnostics section auto-opens on flagged tasks. * NEW ``/diagnostics`` endpoint — fleet-wide listing, filterable by severity, sorted critical-first. CLI --- * NEW ``hermes kanban diagnostics [--severity X] [--task id] [--json]`` — fleet view or single-task view, matches dashboard rule output so CLI users see the same picture. * ``hermes kanban show <id>`` now renders a Diagnostics section near the top with severity markers + suggested actions. Dashboard --------- * Card badge is severity-coloured (⚠ amber warning, !! orange error, !!! red critical) using ``warnings.highest_severity``. * Attention strip above the toolbar counts EVERY task with active diagnostics (not just hallucinations), severity-coloured, lists affected tasks with Open buttons when expanded. * Drawer's old ``RecoverySection`` replaced with generic ``DiagnosticsSection`` rendering a card per active diagnostic: title + detail + structured data (task-id chips when payload keys look like id lists) + action buttons. Reassign profile picker is inline per-diagnostic. Clipboard fallback uses ``.catch()`` for environments where writeText rejects. * Three-rung severity palette; amber for warning, orange for error, red for critical. Uses CSS variables so theming is straightforward. Tests ----- * NEW ``tests/hermes_cli/test_kanban_diagnostics.py`` — 14 unit tests covering each rule's positive/negative/threshold paths, severity sorting, broken-rule isolation, and sqlite3.Row integration. * Dashboard plugin tests extended: ``/diagnostics`` endpoint (empty, populated, severity-filtered), ``/board`` exposes both diagnostic list and compact summary with ``highest_severity``. * Existing hallucination-specific test (``test_board_surfaces_ warnings_field_for_hallucinated_completions``) updated to reflect the new contract: warning summary keys by diagnostic kind (``hallucinated_cards``) not event kind. 379 kanban-suite tests pass (+16 net from this PR). Live verification ----------------- Seeded all 5 diagnostic kinds + one clean + one plain-running task (7 total) into an isolated HERMES_HOME, spun up the dashboard, and verified: * Attention strip: shows ``!! 5 tasks need attention`` in the error-severity orange; Show expands to a list of 5 rows ordered critical > error > warning. * Card badges: error tasks render ``!!`` orange, warning tasks render ``⚠`` amber, clean and plain-running tasks render no badge. * Each of the 5 rules opens a correctly-coloured, correctly-styled diagnostic card in the drawer with its specific suggested action. * Live reassign from a diagnostic card flipped ``broken-ml-worker → alice`` and the drawer refreshed with the new assignee + the same diagnostic still firing (correct: spawn_failures counter hasn't reset yet). * CLI ``hermes kanban diagnostics`` prints all 5 in severity order; ``--severity error`` narrows to 3; ``kanban show <id>`` includes the Diagnostics block at the top with suggested action hint. Migration note -------------- The old ``warnings`` shape (``{count, kinds, latest_at}``) is preserved on the API but ``kinds`` now keys by diagnostic kind (``hallucinated_cards``) instead of event kind (``completion_blocked_hallucination``). ``highest_severity`` is a new required field. The dashboard was the only consumer and has been updated in the same commit; external API consumers of the ``warnings`` field will need to update their kind-match logic. * feat(kanban/diagnostics): lead titles with the actual error text The generic 'Worker crashed N runs in a row' / 'Worker failed to spawn N times' titles buried the actual cause in the data section. Operators had to open logs or expand the diagnostic to see WHY the worker is stuck — rate-limit vs insufficient quota vs bad auth vs context overflow vs network blip all looked identical at a glance. New titles: Agent crashed 3x: openai: 429 Too Many Requests - rate limit reached Agent crashed 3x: anthropic: 402 insufficient_quota - credit balance Agent crashed 3x: provider auth error: 401 Unauthorized Agent spawn failed 4x: insufficient_quota: You exceeded your current Detail keeps the full error snippet (capped at 500 chars + ellipsis for tracebacks). Title takes the first line capped at 160 chars. Fallback title if no error recorded stays honest ('no error recorded'). Tests: 4 new cases covering 429/billing/spawn/truncation. 383 total pass (+4). Live-verified on dashboard with 6 seeded scenarios (rate-limit, billing, auth, context, network, spawn-billing) — each card title leads with the actionable error text.
1272 lines
33 KiB
CSS
1272 lines
33 KiB
CSS
/*
|
|
* Hermes Kanban — dashboard plugin styles.
|
|
*
|
|
* All colors reference theme CSS vars so the board reskins with the
|
|
* active dashboard theme. No hardcoded palette.
|
|
*/
|
|
|
|
.hermes-kanban {
|
|
width: 100%;
|
|
}
|
|
|
|
/* ---- Columns layout -------------------------------------------------- */
|
|
|
|
.hermes-kanban-columns {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
|
|
gap: 0.75rem;
|
|
align-items: start;
|
|
}
|
|
|
|
.hermes-kanban-column {
|
|
display: flex;
|
|
flex-direction: column;
|
|
background: color-mix(in srgb, var(--color-card) 85%, transparent);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: var(--radius);
|
|
padding: 0.5rem;
|
|
min-height: 200px;
|
|
max-height: calc(100vh - 220px);
|
|
transition: border-color 120ms ease, background-color 120ms ease;
|
|
}
|
|
|
|
.hermes-kanban-column--drop {
|
|
border-color: var(--color-ring);
|
|
background: color-mix(in srgb, var(--color-ring) 8%, var(--color-card));
|
|
}
|
|
|
|
.hermes-kanban-column-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
padding: 0.25rem 0.25rem 0.35rem;
|
|
font-weight: 600;
|
|
font-size: 0.85rem;
|
|
color: var(--color-foreground);
|
|
}
|
|
|
|
.hermes-kanban-column-label {
|
|
flex: 1;
|
|
letter-spacing: 0.01em;
|
|
}
|
|
|
|
.hermes-kanban-column-count {
|
|
font-variant-numeric: tabular-nums;
|
|
color: var(--color-muted-foreground);
|
|
font-size: 0.75rem;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.hermes-kanban-column-add {
|
|
appearance: none;
|
|
background: transparent;
|
|
border: 1px solid var(--color-border);
|
|
color: var(--color-foreground);
|
|
border-radius: var(--radius-sm, 0.25rem);
|
|
width: 22px;
|
|
height: 22px;
|
|
line-height: 1;
|
|
font-size: 1rem;
|
|
cursor: pointer;
|
|
}
|
|
.hermes-kanban-column-add:hover {
|
|
background: color-mix(in srgb, var(--color-foreground) 8%, transparent);
|
|
}
|
|
|
|
.hermes-kanban-column-sub {
|
|
padding: 0 0.25rem 0.5rem;
|
|
font-size: 0.7rem;
|
|
color: var(--color-muted-foreground);
|
|
border-bottom: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.hermes-kanban-column-body {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.45rem;
|
|
overflow-y: auto;
|
|
padding-right: 0.1rem;
|
|
}
|
|
|
|
.hermes-kanban-empty {
|
|
padding: 1.5rem 0.5rem;
|
|
text-align: center;
|
|
font-size: 0.75rem;
|
|
color: var(--color-muted-foreground);
|
|
border: 1px dashed color-mix(in srgb, var(--color-border) 70%, transparent);
|
|
border-radius: var(--radius-sm, 0.25rem);
|
|
}
|
|
|
|
/* ---- Status dots ----------------------------------------------------- */
|
|
|
|
.hermes-kanban-dot {
|
|
display: inline-block;
|
|
width: 0.5rem;
|
|
height: 0.5rem;
|
|
border-radius: 999px;
|
|
background: var(--color-muted-foreground);
|
|
}
|
|
.hermes-kanban-dot-triage { background: #b47dd6; } /* lilac — fresh/unspecified */
|
|
.hermes-kanban-dot-todo { background: var(--color-muted-foreground); }
|
|
.hermes-kanban-dot-ready { background: #d4b348; } /* amber */
|
|
.hermes-kanban-dot-running { background: #3fb97d; } /* green */
|
|
.hermes-kanban-dot-blocked { background: var(--color-destructive, #d14a4a); }
|
|
.hermes-kanban-dot-done { background: #4a8cd1; } /* blue */
|
|
.hermes-kanban-dot-archived { background: var(--color-border); }
|
|
|
|
/* ---- Progress pill (N/M child tasks done) --------------------------- */
|
|
|
|
.hermes-kanban-progress {
|
|
font-family: var(--font-mono, ui-monospace, monospace);
|
|
font-size: 0.62rem;
|
|
padding: 0.05rem 0.35rem;
|
|
border-radius: 999px;
|
|
background: color-mix(in srgb, var(--color-foreground) 8%, transparent);
|
|
border: 1px solid color-mix(in srgb, var(--color-border) 80%, transparent);
|
|
color: var(--color-muted-foreground);
|
|
letter-spacing: 0.02em;
|
|
}
|
|
.hermes-kanban-progress--full {
|
|
background: color-mix(in srgb, #3fb97d 22%, transparent);
|
|
border-color: color-mix(in srgb, #3fb97d 45%, transparent);
|
|
color: var(--color-foreground);
|
|
}
|
|
|
|
/* ---- Lanes (per-profile sub-grouping inside Running) ---------------- */
|
|
|
|
.hermes-kanban-lane {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.35rem;
|
|
padding: 0.25rem 0 0.35rem;
|
|
border-top: 1px dashed color-mix(in srgb, var(--color-border) 70%, transparent);
|
|
}
|
|
.hermes-kanban-lane:first-child {
|
|
border-top: 0;
|
|
padding-top: 0;
|
|
}
|
|
.hermes-kanban-lane-head {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.4rem;
|
|
font-size: 0.65rem;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.08em;
|
|
color: var(--color-muted-foreground);
|
|
padding: 0 0.1rem;
|
|
}
|
|
.hermes-kanban-lane-name {
|
|
font-weight: 600;
|
|
font-family: var(--font-mono, ui-monospace, monospace);
|
|
}
|
|
.hermes-kanban-lane-count {
|
|
margin-left: auto;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
/* ---- Card ------------------------------------------------------------ */
|
|
|
|
.hermes-kanban-card {
|
|
cursor: grab;
|
|
transition: transform 100ms ease, box-shadow 100ms ease;
|
|
}
|
|
.hermes-kanban-card:hover {
|
|
box-shadow: 0 1px 0 0 var(--color-ring) inset, 0 0 0 1px var(--color-ring) inset;
|
|
}
|
|
.hermes-kanban-card:active {
|
|
cursor: grabbing;
|
|
transform: scale(0.995);
|
|
}
|
|
|
|
.hermes-kanban-card-content {
|
|
padding: 0.5rem 0.6rem !important;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.3rem;
|
|
}
|
|
|
|
.hermes-kanban-card-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.35rem;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.hermes-kanban-card-id {
|
|
font-family: var(--font-mono, ui-monospace, monospace);
|
|
font-size: 0.65rem;
|
|
color: var(--color-muted-foreground);
|
|
letter-spacing: 0.03em;
|
|
}
|
|
|
|
.hermes-kanban-card-title {
|
|
font-size: 0.85rem;
|
|
font-weight: 500;
|
|
line-height: 1.3;
|
|
color: var(--color-foreground);
|
|
word-break: break-word;
|
|
}
|
|
|
|
.hermes-kanban-card-meta {
|
|
font-size: 0.7rem;
|
|
color: var(--color-muted-foreground);
|
|
gap: 0.55rem;
|
|
}
|
|
|
|
.hermes-kanban-priority {
|
|
font-size: 0.6rem !important;
|
|
padding: 0.05rem 0.3rem !important;
|
|
background: color-mix(in srgb, var(--color-ring) 18%, transparent);
|
|
color: var(--color-foreground);
|
|
border: 1px solid color-mix(in srgb, var(--color-ring) 40%, transparent);
|
|
}
|
|
|
|
.hermes-kanban-tag {
|
|
font-size: 0.6rem !important;
|
|
padding: 0.05rem 0.3rem !important;
|
|
}
|
|
|
|
.hermes-kanban-assignee {
|
|
font-weight: 500;
|
|
color: color-mix(in srgb, var(--color-foreground) 80%, var(--color-muted-foreground));
|
|
}
|
|
.hermes-kanban-unassigned {
|
|
font-style: italic;
|
|
}
|
|
.hermes-kanban-ago {
|
|
margin-left: auto;
|
|
}
|
|
|
|
/* ---- Inline create --------------------------------------------------- */
|
|
|
|
.hermes-kanban-inline-create {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.35rem;
|
|
padding: 0.5rem;
|
|
margin-bottom: 0.5rem;
|
|
background: color-mix(in srgb, var(--color-card) 70%, transparent);
|
|
border: 1px dashed var(--color-border);
|
|
border-radius: var(--radius-sm, 0.25rem);
|
|
}
|
|
|
|
.hermes-kanban-inline-create > .flex.gap-2:last-child > button:first-of-type {
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
|
|
/* ---- Drawer (task detail side panel) --------------------------------- */
|
|
|
|
.hermes-kanban-drawer-shade {
|
|
position: fixed;
|
|
inset: 0;
|
|
background: rgba(0, 0, 0, 0.45);
|
|
z-index: 60;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.hermes-kanban-drawer {
|
|
width: min(var(--hermes-kanban-drawer-width, 640px), 92vw);
|
|
height: 100vh;
|
|
background: var(--color-card);
|
|
border-left: 1px solid var(--color-border);
|
|
display: flex;
|
|
flex-direction: column;
|
|
box-shadow: -4px 0 18px rgba(0, 0, 0, 0.35);
|
|
animation: hermes-kanban-drawer-in 180ms ease-out;
|
|
}
|
|
|
|
@keyframes hermes-kanban-drawer-in {
|
|
from { transform: translateX(100%); opacity: 0.3; }
|
|
to { transform: translateX(0); opacity: 1; }
|
|
}
|
|
|
|
.hermes-kanban-drawer-head {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 0.6rem 0.8rem;
|
|
border-bottom: 1px solid var(--color-border);
|
|
font-family: var(--font-mono, ui-monospace, monospace);
|
|
}
|
|
|
|
.hermes-kanban-drawer-close {
|
|
appearance: none;
|
|
background: transparent;
|
|
border: 0;
|
|
color: var(--color-muted-foreground);
|
|
font-size: 1.25rem;
|
|
line-height: 1;
|
|
cursor: pointer;
|
|
padding: 0 0.25rem;
|
|
}
|
|
.hermes-kanban-drawer-close:hover { color: var(--color-foreground); }
|
|
|
|
.hermes-kanban-drawer-body {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: 0.9rem;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.85rem;
|
|
}
|
|
|
|
.hermes-kanban-drawer-title {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
font-size: 1rem;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.hermes-kanban-drawer-meta {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.15rem;
|
|
padding: 0.5rem 0.6rem;
|
|
background: color-mix(in srgb, var(--color-foreground) 4%, transparent);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: var(--radius-sm, 0.25rem);
|
|
}
|
|
|
|
.hermes-kanban-meta-row {
|
|
display: flex;
|
|
gap: 0.5rem;
|
|
font-size: 0.8rem;
|
|
}
|
|
.hermes-kanban-meta-label {
|
|
width: 92px;
|
|
color: var(--color-muted-foreground);
|
|
}
|
|
.hermes-kanban-meta-value {
|
|
color: var(--color-foreground);
|
|
word-break: break-word;
|
|
}
|
|
|
|
.hermes-kanban-actions {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 0.3rem;
|
|
}
|
|
|
|
/* ---- Home channel subscription toggles (per-platform, per-task) ----- */
|
|
|
|
.hermes-kanban-home-subs {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 0.3rem;
|
|
}
|
|
.hermes-kanban-home-sub {
|
|
font-family: var(--font-mono, ui-monospace, monospace);
|
|
text-transform: lowercase;
|
|
letter-spacing: 0.02em;
|
|
}
|
|
.hermes-kanban-home-sub--on {
|
|
/* Subscribed toggle — use a strong ring-colored accent so the on/off
|
|
* distinction reads at a glance, not just from the ✓ prefix. Border +
|
|
* filled background + bolder weight keep the state obvious across
|
|
* themes (tested on default teal and NERV orange). */
|
|
border-color: var(--color-ring);
|
|
background: color-mix(in srgb, var(--color-ring) 32%, transparent);
|
|
color: var(--color-foreground);
|
|
font-weight: 600;
|
|
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-ring) 40%, transparent);
|
|
}
|
|
|
|
.hermes-kanban-section {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.35rem;
|
|
}
|
|
|
|
.hermes-kanban-section-head {
|
|
font-size: 0.72rem;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.07em;
|
|
color: var(--color-muted-foreground);
|
|
}
|
|
|
|
.hermes-kanban-pre {
|
|
margin: 0;
|
|
padding: 0.5rem 0.6rem;
|
|
white-space: pre-wrap;
|
|
word-break: break-word;
|
|
background: color-mix(in srgb, var(--color-foreground) 4%, transparent);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: var(--radius-sm, 0.25rem);
|
|
font-family: var(--font-mono, ui-monospace, monospace);
|
|
font-size: 0.8rem;
|
|
line-height: 1.5;
|
|
color: var(--color-foreground);
|
|
}
|
|
|
|
.hermes-kanban-comment {
|
|
border-left: 2px solid color-mix(in srgb, var(--color-ring) 35%, transparent);
|
|
padding-left: 0.5rem;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.2rem;
|
|
}
|
|
|
|
.hermes-kanban-comment-head {
|
|
display: flex;
|
|
gap: 0.5rem;
|
|
font-size: 0.7rem;
|
|
}
|
|
.hermes-kanban-comment-author {
|
|
font-weight: 600;
|
|
color: var(--color-foreground);
|
|
}
|
|
.hermes-kanban-comment-ago {
|
|
color: var(--color-muted-foreground);
|
|
}
|
|
|
|
.hermes-kanban-event {
|
|
display: flex;
|
|
gap: 0.5rem;
|
|
font-size: 0.7rem;
|
|
color: var(--color-muted-foreground);
|
|
font-family: var(--font-mono, ui-monospace, monospace);
|
|
}
|
|
.hermes-kanban-event-kind {
|
|
color: var(--color-foreground);
|
|
min-width: 6rem;
|
|
}
|
|
.hermes-kanban-event-payload {
|
|
color: var(--color-muted-foreground);
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
max-width: 280px;
|
|
}
|
|
|
|
.hermes-kanban-drawer-comment-row {
|
|
display: flex;
|
|
gap: 0.4rem;
|
|
padding: 0.55rem 0.75rem;
|
|
border-top: 1px solid var(--color-border);
|
|
background: color-mix(in srgb, var(--color-card) 90%, transparent);
|
|
}
|
|
|
|
.hermes-kanban-count {
|
|
display: inline-flex;
|
|
gap: 0.2rem;
|
|
align-items: center;
|
|
}
|
|
|
|
/* ---- Selection chrome ----------------------------------------------- */
|
|
|
|
.hermes-kanban-card--selected :where(.hermes-kanban-card-content) {
|
|
box-shadow: 0 0 0 2px var(--color-ring) inset,
|
|
0 0 0 1px var(--color-ring) inset;
|
|
background: color-mix(in srgb, var(--color-ring) 6%, var(--color-card));
|
|
}
|
|
|
|
.hermes-kanban-card-check {
|
|
width: 0.85rem;
|
|
height: 0.85rem;
|
|
margin: 0;
|
|
cursor: pointer;
|
|
accent-color: var(--color-ring);
|
|
}
|
|
|
|
/* ---- Bulk action bar ------------------------------------------------ */
|
|
|
|
.hermes-kanban-bulk {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
padding: 0.4rem 0.75rem;
|
|
background: color-mix(in srgb, var(--color-ring) 10%, var(--color-card));
|
|
border: 1px solid color-mix(in srgb, var(--color-ring) 40%, var(--color-border));
|
|
border-radius: var(--radius-sm, 0.25rem);
|
|
flex-wrap: wrap;
|
|
}
|
|
.hermes-kanban-bulk-count {
|
|
font-weight: 600;
|
|
font-size: 0.75rem;
|
|
padding-right: 0.25rem;
|
|
}
|
|
|
|
.hermes-kanban-bulk > button,
|
|
.hermes-kanban-bulk-reassign > button {
|
|
height: 1.7rem !important;
|
|
padding: 0 0.5rem !important;
|
|
font-size: 0.7rem !important;
|
|
border: 1px solid var(--color-border);
|
|
cursor: pointer;
|
|
}
|
|
.hermes-kanban-bulk > button:hover:not(:disabled),
|
|
.hermes-kanban-bulk-reassign > button:hover:not(:disabled) {
|
|
background: color-mix(in srgb, var(--color-foreground) 8%, transparent);
|
|
}
|
|
.hermes-kanban-bulk-reassign {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.25rem;
|
|
padding-left: 0.5rem;
|
|
border-left: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
|
|
}
|
|
|
|
/* ---- Dependency editor chips --------------------------------------- */
|
|
|
|
.hermes-kanban-deps-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
margin-bottom: 0.4rem;
|
|
}
|
|
.hermes-kanban-deps-label {
|
|
font-size: 0.68rem;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.08em;
|
|
color: var(--color-muted-foreground);
|
|
min-width: 4rem;
|
|
}
|
|
.hermes-kanban-deps-chips {
|
|
display: flex;
|
|
gap: 0.3rem;
|
|
flex-wrap: wrap;
|
|
flex: 1;
|
|
}
|
|
.hermes-kanban-deps-empty {
|
|
font-size: 0.7rem;
|
|
color: var(--color-muted-foreground);
|
|
font-style: italic;
|
|
}
|
|
.hermes-kanban-dep-chip {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.15rem;
|
|
padding: 0.1rem 0.35rem;
|
|
background: color-mix(in srgb, var(--color-foreground) 6%, transparent);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: var(--radius-sm, 0.25rem);
|
|
font-family: var(--font-mono, ui-monospace, monospace);
|
|
font-size: 0.68rem;
|
|
color: var(--color-foreground);
|
|
}
|
|
.hermes-kanban-dep-chip-x {
|
|
appearance: none;
|
|
background: transparent;
|
|
border: 0;
|
|
color: var(--color-muted-foreground);
|
|
cursor: pointer;
|
|
font-size: 0.85rem;
|
|
line-height: 1;
|
|
padding: 0 0.15rem;
|
|
}
|
|
.hermes-kanban-dep-chip-x:hover { color: var(--color-destructive, #d14a4a); }
|
|
|
|
/* ---- Inline edit affordances --------------------------------------- */
|
|
|
|
.hermes-kanban-editable {
|
|
cursor: pointer;
|
|
border-bottom: 1px dotted color-mix(in srgb, var(--color-border) 80%, transparent);
|
|
}
|
|
.hermes-kanban-editable:hover {
|
|
color: var(--color-foreground);
|
|
border-bottom-color: var(--color-ring);
|
|
}
|
|
|
|
.hermes-kanban-drawer-title-text {
|
|
cursor: pointer;
|
|
}
|
|
.hermes-kanban-drawer-title-text:hover {
|
|
text-decoration: underline;
|
|
text-decoration-color: var(--color-ring);
|
|
text-decoration-style: dotted;
|
|
text-underline-offset: 3px;
|
|
}
|
|
|
|
.hermes-kanban-edit-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.35rem;
|
|
width: 100%;
|
|
}
|
|
|
|
.hermes-kanban-section-head-row {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 0.5rem;
|
|
}
|
|
.hermes-kanban-edit-link {
|
|
appearance: none;
|
|
background: transparent;
|
|
border: 0;
|
|
color: var(--color-muted-foreground);
|
|
font-size: 0.7rem;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.05em;
|
|
cursor: pointer;
|
|
padding: 0;
|
|
}
|
|
.hermes-kanban-edit-link:hover { color: var(--color-ring); }
|
|
|
|
.hermes-kanban-textarea {
|
|
width: 100%;
|
|
min-height: 8rem;
|
|
background: var(--color-card);
|
|
color: var(--color-foreground);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: var(--radius-sm, 0.25rem);
|
|
padding: 0.5rem 0.6rem;
|
|
font-family: var(--font-mono, ui-monospace, monospace);
|
|
font-size: 0.8rem;
|
|
line-height: 1.5;
|
|
resize: vertical;
|
|
}
|
|
.hermes-kanban-textarea:focus {
|
|
outline: none;
|
|
border-color: var(--color-ring);
|
|
box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-ring) 30%, transparent);
|
|
}
|
|
|
|
/* ---- Markdown rendering -------------------------------------------- */
|
|
|
|
.hermes-kanban-md {
|
|
font-size: 0.85rem;
|
|
line-height: 1.6;
|
|
color: var(--color-foreground);
|
|
}
|
|
.hermes-kanban-md p { margin: 0.25rem 0; }
|
|
.hermes-kanban-md h1,
|
|
.hermes-kanban-md h2,
|
|
.hermes-kanban-md h3,
|
|
.hermes-kanban-md h4 {
|
|
margin: 0.6rem 0 0.2rem;
|
|
line-height: 1.25;
|
|
}
|
|
.hermes-kanban-md h1 { font-size: 1.05rem; }
|
|
.hermes-kanban-md h2 { font-size: 0.95rem; }
|
|
.hermes-kanban-md h3 { font-size: 0.88rem; }
|
|
.hermes-kanban-md h4 { font-size: 0.82rem; }
|
|
.hermes-kanban-md ul {
|
|
margin: 0.25rem 0 0.25rem 1.1rem;
|
|
padding: 0;
|
|
}
|
|
.hermes-kanban-md li { margin: 0.1rem 0; }
|
|
.hermes-kanban-md a {
|
|
color: var(--color-ring);
|
|
text-decoration: underline;
|
|
}
|
|
.hermes-kanban-md code {
|
|
font-family: var(--font-mono, ui-monospace, monospace);
|
|
font-size: 0.8rem;
|
|
padding: 0.05rem 0.3rem;
|
|
background: color-mix(in srgb, var(--color-foreground) 8%, transparent);
|
|
border-radius: 3px;
|
|
color: inherit;
|
|
}
|
|
/* Fenced code block. Set a visible background even when --color-foreground
|
|
* is empty (color-mix falls through to transparent in that case), and force
|
|
* color: inherit so the text tracks the drawer foreground rather than the
|
|
* UA default on <code> elements — otherwise themes that don't set
|
|
* --color-foreground leave code text rendering near-black on dark themes
|
|
* (see issue #18576). */
|
|
.hermes-kanban-md-code {
|
|
margin: 0.35rem 0;
|
|
padding: 0.5rem 0.6rem;
|
|
background: color-mix(in srgb, currentColor 6%, transparent);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: var(--radius-sm, 0.25rem);
|
|
overflow-x: auto;
|
|
}
|
|
.hermes-kanban-md-code code {
|
|
background: transparent;
|
|
padding: 0;
|
|
font-size: 0.8rem;
|
|
white-space: pre;
|
|
color: inherit;
|
|
}
|
|
.hermes-kanban-md strong { font-weight: 600; }
|
|
|
|
/* ---- Touch-drag proxy ---------------------------------------------- */
|
|
|
|
.hermes-kanban-touch-proxy {
|
|
pointer-events: none;
|
|
opacity: 0.85;
|
|
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35);
|
|
transform: scale(1.02);
|
|
transition: none;
|
|
}
|
|
|
|
|
|
/* ---- Staleness tiers ------------------------------------------------ */
|
|
|
|
.hermes-kanban-card--stale-amber :where(.hermes-kanban-card-content) {
|
|
box-shadow: 0 0 0 1px #d4b34888 inset;
|
|
}
|
|
.hermes-kanban-card--stale-amber:hover :where(.hermes-kanban-card-content) {
|
|
box-shadow: 0 0 0 2px #d4b348 inset;
|
|
}
|
|
.hermes-kanban-card--stale-red :where(.hermes-kanban-card-content) {
|
|
box-shadow: 0 0 0 1px var(--color-destructive, #d14a4a) inset,
|
|
0 0 8px color-mix(in srgb, var(--color-destructive, #d14a4a) 30%, transparent);
|
|
}
|
|
.hermes-kanban-card--stale-red:hover :where(.hermes-kanban-card-content) {
|
|
box-shadow: 0 0 0 2px var(--color-destructive, #d14a4a) inset,
|
|
0 0 10px color-mix(in srgb, var(--color-destructive, #d14a4a) 45%, transparent);
|
|
}
|
|
|
|
/* ---- Worker log pane ------------------------------------------------ */
|
|
|
|
.hermes-kanban-log {
|
|
max-height: 360px;
|
|
overflow: auto;
|
|
white-space: pre;
|
|
font-size: 0.78rem;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
|
|
/* ---- Run history (per-attempt log in the drawer) ------------------- */
|
|
|
|
.hermes-kanban-run {
|
|
border-left: 2px solid var(--color-border);
|
|
padding: 0.35rem 0.5rem;
|
|
margin-bottom: 0.4rem;
|
|
background: color-mix(in srgb, var(--color-foreground) 3%, transparent);
|
|
border-radius: var(--radius-sm, 0.25rem);
|
|
}
|
|
.hermes-kanban-run--active { border-left-color: #3fb97d; }
|
|
.hermes-kanban-run--completed { border-left-color: #4a8cd1; }
|
|
.hermes-kanban-run--ended { border-left-color: #6b7280; } /* generic fallback when outcome is unset */
|
|
.hermes-kanban-run--blocked { border-left-color: var(--color-destructive, #d14a4a); }
|
|
.hermes-kanban-run--crashed,
|
|
.hermes-kanban-run--timed_out,
|
|
.hermes-kanban-run--gave_up,
|
|
.hermes-kanban-run--spawn_failed {
|
|
border-left-color: var(--color-destructive, #d14a4a);
|
|
background: color-mix(in srgb, var(--color-destructive, #d14a4a) 6%, transparent);
|
|
}
|
|
.hermes-kanban-run--reclaimed { border-left-color: #d4b348; }
|
|
|
|
.hermes-kanban-run-head {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.6rem;
|
|
font-size: 0.7rem;
|
|
}
|
|
.hermes-kanban-run-outcome {
|
|
font-family: var(--font-mono, ui-monospace, monospace);
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.05em;
|
|
color: var(--color-foreground);
|
|
}
|
|
.hermes-kanban-run-profile {
|
|
color: var(--color-muted-foreground);
|
|
}
|
|
.hermes-kanban-run-elapsed {
|
|
font-variant-numeric: tabular-nums;
|
|
color: var(--color-muted-foreground);
|
|
}
|
|
.hermes-kanban-run-ago {
|
|
margin-left: auto;
|
|
color: var(--color-muted-foreground);
|
|
}
|
|
.hermes-kanban-run-summary {
|
|
font-size: 0.82rem;
|
|
line-height: 1.5;
|
|
padding: 0.2rem 0 0;
|
|
color: var(--color-foreground);
|
|
}
|
|
.hermes-kanban-run-error {
|
|
font-size: 0.7rem;
|
|
color: var(--color-destructive, #d14a4a);
|
|
padding: 0.15rem 0 0;
|
|
font-family: var(--font-mono, ui-monospace, monospace);
|
|
}
|
|
.hermes-kanban-run-meta {
|
|
display: block;
|
|
font-size: 0.72rem;
|
|
line-height: 1.5;
|
|
padding: 0.15rem 0 0;
|
|
color: var(--color-muted-foreground);
|
|
white-space: pre-wrap;
|
|
word-break: break-word;
|
|
font-family: var(--font-mono, ui-monospace, monospace);
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------
|
|
Multi-project: board switcher + create-board dialog
|
|
------------------------------------------------------------------------- */
|
|
.hermes-kanban-boardswitcher {
|
|
border: 1px solid var(--color-border, rgba(120, 120, 140, 0.25));
|
|
border-radius: 0.5rem;
|
|
padding: 0.6rem 0.85rem;
|
|
background: var(--color-card-subtle, rgba(255, 255, 255, 0.02));
|
|
}
|
|
.hermes-kanban-boardswitcher-inner {
|
|
display: flex;
|
|
align-items: flex-end;
|
|
gap: 0.75rem;
|
|
flex-wrap: wrap;
|
|
}
|
|
.hermes-kanban-boardswitcher-compact {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
padding: 0 0.25rem;
|
|
}
|
|
.hermes-kanban-dialog-backdrop {
|
|
position: fixed;
|
|
inset: 0;
|
|
background: rgba(8, 10, 16, 0.55);
|
|
backdrop-filter: blur(2px);
|
|
z-index: 60;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
.hermes-kanban-dialog {
|
|
background: var(--color-card, #121421);
|
|
color: var(--color-foreground);
|
|
border: 1px solid var(--color-border, rgba(120, 120, 140, 0.25));
|
|
border-radius: 0.5rem;
|
|
padding: 1.1rem 1.2rem 1rem;
|
|
width: 28rem;
|
|
max-width: calc(100vw - 2rem);
|
|
max-height: calc(100vh - 3rem);
|
|
overflow: auto;
|
|
box-shadow: 0 18px 40px rgba(0, 0, 0, 0.5);
|
|
}
|
|
.hermes-kanban-dialog-title {
|
|
font-size: 1rem;
|
|
font-weight: 600;
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
.hermes-kanban-dialog-actions {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 0.5rem;
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
/* Hallucination warnings: per-card badge, events callout, attention */
|
|
/* strip, recovery popover. Orange/red palette but muted so the board */
|
|
/* doesn't scream on every render. */
|
|
/* ---------------------------------------------------------------------- */
|
|
.hermes-kanban-warning-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 0.75rem;
|
|
color: #ff9e3b;
|
|
margin-left: 0.25rem;
|
|
cursor: help;
|
|
}
|
|
|
|
/* Attention strip — collapsed state is a thin bar. */
|
|
.hermes-kanban-attention {
|
|
border: 1px solid rgba(255, 158, 59, 0.35);
|
|
background: rgba(255, 158, 59, 0.06);
|
|
border-radius: 0.5rem;
|
|
overflow: hidden;
|
|
}
|
|
.hermes-kanban-attention-bar {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
padding: 0.4rem 0.75rem;
|
|
font-size: 0.8125rem;
|
|
}
|
|
.hermes-kanban-attention-icon { color: #ff9e3b; font-size: 1rem; }
|
|
.hermes-kanban-attention-text { flex: 1; }
|
|
.hermes-kanban-attention-toggle,
|
|
.hermes-kanban-attention-dismiss,
|
|
.hermes-kanban-attention-row-btn {
|
|
background: transparent;
|
|
border: 1px solid rgba(120, 120, 140, 0.3);
|
|
border-radius: 0.3rem;
|
|
padding: 0.15rem 0.55rem;
|
|
font-size: 0.75rem;
|
|
color: inherit;
|
|
cursor: pointer;
|
|
}
|
|
.hermes-kanban-attention-toggle:hover,
|
|
.hermes-kanban-attention-dismiss:hover,
|
|
.hermes-kanban-attention-row-btn:hover {
|
|
background: rgba(255, 158, 59, 0.12);
|
|
}
|
|
.hermes-kanban-attention-list {
|
|
border-top: 1px solid rgba(255, 158, 59, 0.2);
|
|
padding: 0.25rem 0;
|
|
}
|
|
.hermes-kanban-attention-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
padding: 0.3rem 0.75rem;
|
|
font-size: 0.8125rem;
|
|
}
|
|
.hermes-kanban-attention-row:hover {
|
|
background: rgba(255, 158, 59, 0.08);
|
|
}
|
|
.hermes-kanban-attention-row-id {
|
|
font-family: ui-monospace, SFMono-Regular, monospace;
|
|
font-size: 0.75rem;
|
|
color: var(--color-muted-foreground, #888);
|
|
min-width: 7rem;
|
|
}
|
|
.hermes-kanban-attention-row-title {
|
|
flex: 1;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
.hermes-kanban-attention-row-meta {
|
|
font-size: 0.75rem;
|
|
color: var(--color-muted-foreground, #888);
|
|
}
|
|
|
|
/* Events tab — callout style for hallucination events. */
|
|
.hermes-kanban-event--hallucination {
|
|
border-left: 3px solid #ff6b6b;
|
|
background: rgba(255, 107, 107, 0.08);
|
|
padding: 0.5rem 0.65rem;
|
|
border-radius: 0.35rem;
|
|
margin: 0.25rem 0;
|
|
}
|
|
.hermes-kanban-event-header,
|
|
.hermes-kanban-event-header-plain {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
}
|
|
.hermes-kanban-event-warning-icon { color: #ff6b6b; font-size: 1rem; }
|
|
.hermes-kanban-event-warning-label {
|
|
color: #ff6b6b;
|
|
font-weight: 600;
|
|
font-size: 0.8125rem;
|
|
}
|
|
.hermes-kanban-event-phantom-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.4rem;
|
|
flex-wrap: wrap;
|
|
margin-top: 0.3rem;
|
|
padding-left: 1.35rem;
|
|
}
|
|
.hermes-kanban-event-phantom-label {
|
|
font-size: 0.75rem;
|
|
color: var(--color-muted-foreground, #999);
|
|
}
|
|
.hermes-kanban-event-phantom-chip {
|
|
font-family: ui-monospace, SFMono-Regular, monospace;
|
|
font-size: 0.75rem;
|
|
padding: 0.1rem 0.4rem;
|
|
background: rgba(255, 107, 107, 0.15);
|
|
border: 1px solid rgba(255, 107, 107, 0.3);
|
|
border-radius: 0.3rem;
|
|
}
|
|
|
|
/* Recovery section header — amber accent when the task has warnings. */
|
|
.hermes-kanban-section-head-warning { color: #ff9e3b; }
|
|
.hermes-kanban-section-head-row {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 0.5rem;
|
|
}
|
|
.hermes-kanban-section-toggle {
|
|
background: transparent;
|
|
border: 1px solid rgba(120, 120, 140, 0.3);
|
|
border-radius: 0.3rem;
|
|
padding: 0.15rem 0.55rem;
|
|
font-size: 0.75rem;
|
|
color: inherit;
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* Recovery popover body. */
|
|
.hermes-kanban-recovery {
|
|
border: 1px solid rgba(120, 120, 140, 0.25);
|
|
background: rgba(255, 158, 59, 0.04);
|
|
border-radius: 0.5rem;
|
|
padding: 0.75rem;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.75rem;
|
|
}
|
|
.hermes-kanban-recovery-title {
|
|
font-weight: 600;
|
|
font-size: 0.8125rem;
|
|
}
|
|
.hermes-kanban-recovery-hint {
|
|
font-size: 0.75rem;
|
|
color: var(--color-muted-foreground, #888);
|
|
line-height: 1.35;
|
|
}
|
|
.hermes-kanban-recovery-section {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.35rem;
|
|
}
|
|
.hermes-kanban-recovery-label {
|
|
font-size: 0.75rem;
|
|
color: var(--color-muted-foreground, #888);
|
|
}
|
|
.hermes-kanban-recovery-input,
|
|
.hermes-kanban-recovery-select {
|
|
padding: 0.25rem 0.4rem;
|
|
font-size: 0.8125rem;
|
|
background: rgba(0, 0, 0, 0.15);
|
|
border: 1px solid rgba(120, 120, 140, 0.3);
|
|
border-radius: 0.3rem;
|
|
color: inherit;
|
|
outline: none;
|
|
}
|
|
.hermes-kanban-recovery-action-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
flex-wrap: wrap;
|
|
}
|
|
.hermes-kanban-recovery-action-label {
|
|
font-size: 0.8125rem;
|
|
font-weight: 600;
|
|
min-width: 8rem;
|
|
}
|
|
.hermes-kanban-recovery-action-desc {
|
|
flex: 1;
|
|
font-size: 0.75rem;
|
|
color: var(--color-muted-foreground, #888);
|
|
}
|
|
.hermes-kanban-recovery-btn {
|
|
padding: 0.25rem 0.7rem;
|
|
font-size: 0.75rem;
|
|
background: rgba(255, 158, 59, 0.15);
|
|
border: 1px solid rgba(255, 158, 59, 0.4);
|
|
border-radius: 0.3rem;
|
|
color: inherit;
|
|
cursor: pointer;
|
|
}
|
|
.hermes-kanban-recovery-btn:hover:not(:disabled) {
|
|
background: rgba(255, 158, 59, 0.25);
|
|
}
|
|
.hermes-kanban-recovery-btn:disabled {
|
|
opacity: 0.4;
|
|
cursor: not-allowed;
|
|
}
|
|
.hermes-kanban-recovery-reassign-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
flex-wrap: wrap;
|
|
}
|
|
.hermes-kanban-recovery-checkbox {
|
|
font-size: 0.75rem;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.25rem;
|
|
}
|
|
.hermes-kanban-recovery-cmd-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
flex-wrap: wrap;
|
|
}
|
|
.hermes-kanban-recovery-cmd {
|
|
font-family: ui-monospace, SFMono-Regular, monospace;
|
|
font-size: 0.75rem;
|
|
padding: 0.2rem 0.5rem;
|
|
background: rgba(0, 0, 0, 0.2);
|
|
border: 1px solid rgba(120, 120, 140, 0.3);
|
|
border-radius: 0.3rem;
|
|
flex: 1;
|
|
min-width: 10rem;
|
|
overflow-x: auto;
|
|
white-space: nowrap;
|
|
}
|
|
.hermes-kanban-recovery-msg {
|
|
font-size: 0.75rem;
|
|
padding: 0.35rem 0.5rem;
|
|
border-radius: 0.3rem;
|
|
}
|
|
.hermes-kanban-recovery-msg--ok {
|
|
background: rgba(120, 200, 120, 0.12);
|
|
color: #6bc46b;
|
|
border: 1px solid rgba(120, 200, 120, 0.3);
|
|
}
|
|
.hermes-kanban-recovery-msg--err {
|
|
background: rgba(255, 107, 107, 0.12);
|
|
color: #ff8b8b;
|
|
border: 1px solid rgba(255, 107, 107, 0.3);
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
/* Diagnostics — generic, severity-coloured distress signals on tasks. */
|
|
/* Three rungs: warning (amber), error (orange), critical (red). */
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
/* Severity token variables so every diagnostic-coloured surface uses the */
|
|
/* same palette. */
|
|
.hermes-kanban-diag,
|
|
.hermes-kanban-attention,
|
|
.hermes-kanban-warning-badge,
|
|
.hermes-kanban-attention-row {
|
|
--hermes-diag-warning: #ff9e3b;
|
|
--hermes-diag-error: #ff6b3d;
|
|
--hermes-diag-critical: #ff4d4d;
|
|
}
|
|
|
|
/* Warning-badge severity variants (overrides the base colour). */
|
|
.hermes-kanban-warning-badge--warning { color: var(--hermes-diag-warning); }
|
|
.hermes-kanban-warning-badge--error { color: var(--hermes-diag-error); font-weight: 700; }
|
|
.hermes-kanban-warning-badge--critical { color: var(--hermes-diag-critical); font-weight: 700; }
|
|
|
|
/* Attention-strip severity variants. */
|
|
.hermes-kanban-attention--warning {
|
|
border-color: rgba(255, 158, 59, 0.35);
|
|
background: rgba(255, 158, 59, 0.06);
|
|
}
|
|
.hermes-kanban-attention--error {
|
|
border-color: rgba(255, 107, 61, 0.45);
|
|
background: rgba(255, 107, 61, 0.08);
|
|
}
|
|
.hermes-kanban-attention--critical {
|
|
border-color: rgba(255, 77, 77, 0.55);
|
|
background: rgba(255, 77, 77, 0.10);
|
|
}
|
|
.hermes-kanban-attention--error .hermes-kanban-attention-icon { color: var(--hermes-diag-error); }
|
|
.hermes-kanban-attention--critical .hermes-kanban-attention-icon { color: var(--hermes-diag-critical); }
|
|
|
|
/* Per-row severity marker in the expanded attention list. */
|
|
.hermes-kanban-attention-row-sev {
|
|
display: inline-block;
|
|
min-width: 1.5rem;
|
|
font-weight: 600;
|
|
}
|
|
.hermes-kanban-attention-row--warning .hermes-kanban-attention-row-sev { color: var(--hermes-diag-warning); }
|
|
.hermes-kanban-attention-row--error .hermes-kanban-attention-row-sev { color: var(--hermes-diag-error); font-weight: 700; }
|
|
.hermes-kanban-attention-row--critical .hermes-kanban-attention-row-sev { color: var(--hermes-diag-critical); font-weight: 700; }
|
|
|
|
/* Individual diagnostic card inside the drawer's Diagnostics section. */
|
|
.hermes-kanban-diag-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.6rem;
|
|
}
|
|
.hermes-kanban-diag {
|
|
border-left: 3px solid var(--hermes-diag-warning);
|
|
background: rgba(255, 158, 59, 0.05);
|
|
border-radius: 0.35rem;
|
|
padding: 0.6rem 0.75rem;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.4rem;
|
|
}
|
|
.hermes-kanban-diag--error {
|
|
border-left-color: var(--hermes-diag-error);
|
|
background: rgba(255, 107, 61, 0.06);
|
|
}
|
|
.hermes-kanban-diag--critical {
|
|
border-left-color: var(--hermes-diag-critical);
|
|
background: rgba(255, 77, 77, 0.07);
|
|
}
|
|
.hermes-kanban-diag-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
}
|
|
.hermes-kanban-diag-sev {
|
|
font-weight: 700;
|
|
min-width: 1.5rem;
|
|
}
|
|
.hermes-kanban-diag--warning .hermes-kanban-diag-sev { color: var(--hermes-diag-warning); }
|
|
.hermes-kanban-diag--error .hermes-kanban-diag-sev { color: var(--hermes-diag-error); }
|
|
.hermes-kanban-diag--critical .hermes-kanban-diag-sev { color: var(--hermes-diag-critical); }
|
|
.hermes-kanban-diag-title {
|
|
font-weight: 600;
|
|
font-size: 0.875rem;
|
|
}
|
|
.hermes-kanban-diag-detail {
|
|
font-size: 0.8125rem;
|
|
color: var(--color-foreground, #ccc);
|
|
line-height: 1.4;
|
|
}
|
|
.hermes-kanban-diag-data {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.2rem;
|
|
font-size: 0.75rem;
|
|
}
|
|
.hermes-kanban-diag-data-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.35rem;
|
|
flex-wrap: wrap;
|
|
}
|
|
.hermes-kanban-diag-data-key {
|
|
color: var(--color-muted-foreground, #888);
|
|
font-weight: 500;
|
|
}
|
|
.hermes-kanban-diag-data-val {
|
|
font-family: ui-monospace, SFMono-Regular, monospace;
|
|
}
|
|
.hermes-kanban-diag-reassign-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.4rem;
|
|
font-size: 0.75rem;
|
|
}
|
|
.hermes-kanban-diag-reassign-label {
|
|
color: var(--color-muted-foreground, #888);
|
|
}
|
|
.hermes-kanban-diag-actions {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 0.4rem;
|
|
margin-top: 0.1rem;
|
|
}
|
|
.hermes-kanban-diag-action-btn {
|
|
padding: 0.25rem 0.6rem;
|
|
font-size: 0.75rem;
|
|
background: rgba(0, 0, 0, 0.2);
|
|
border: 1px solid rgba(120, 120, 140, 0.3);
|
|
border-radius: 0.3rem;
|
|
color: inherit;
|
|
cursor: pointer;
|
|
text-decoration: none;
|
|
}
|
|
.hermes-kanban-diag-action-btn:hover:not(:disabled) {
|
|
background: rgba(0, 0, 0, 0.3);
|
|
}
|
|
.hermes-kanban-diag-action-btn:disabled {
|
|
opacity: 0.4;
|
|
cursor: not-allowed;
|
|
}
|
|
.hermes-kanban-diag-action-btn--suggested {
|
|
background: rgba(255, 158, 59, 0.15);
|
|
border-color: rgba(255, 158, 59, 0.4);
|
|
font-weight: 600;
|
|
}
|
|
.hermes-kanban-diag-action-btn--suggested:hover:not(:disabled) {
|
|
background: rgba(255, 158, 59, 0.25);
|
|
}
|
|
.hermes-kanban-diag-action-btn--unknown {
|
|
opacity: 0.6;
|
|
cursor: default;
|
|
}
|
|
.hermes-kanban-diag-msg {
|
|
font-size: 0.75rem;
|
|
padding: 0.35rem 0.5rem;
|
|
border-radius: 0.3rem;
|
|
}
|
|
.hermes-kanban-diag-msg--ok {
|
|
background: rgba(120, 200, 120, 0.12);
|
|
color: #6bc46b;
|
|
border: 1px solid rgba(120, 200, 120, 0.3);
|
|
}
|
|
.hermes-kanban-diag-msg--err {
|
|
background: rgba(255, 107, 61, 0.12);
|
|
color: #ff8b6b;
|
|
border: 1px solid rgba(255, 107, 61, 0.3);
|
|
}
|