Realizes the chosen host-summary layout: a thin live vitals bar at the very top,
separate from the agent management panel (no more duplicated CPU/MEM/DISK/LOAD).
- New fragment _host_vitals.html + route /plugins/host_agent/vitals/<id>: compact
CPU / Memory / Disk(/) / Load-per-core (threshold-coloured + sparkline) +
Pressure + live/stale·version·last-seen. Polled every 15s; renders nothing
until the agent reports.
- The metric computation (latest snapshot + 6h sparkline query + load/core + PSI)
moves from host_panel into host_vitals. host_panel slims to management only
(reg/target/reporting/stale/ansible) and no longer queries metrics; panel.html
drops the gauge row + pressure block, keeping status + lifecycle actions.
- hosts/detail.html: vitals strip on top (full width, live), then a 2-col
[Monitors | Agent] grid, Ansible full width below, docker fragment last.
UI only. Templates parse; plugin-template parse test covers the new fragment.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016Jg27rgypiW2efULXJDtMC
Move the hardcoded warn/crit cutoffs into Settings -> Thresholds (DB-backed,
live, no restart). New thresholds.* keys + to_thresholds_cfg() + a
threshold_style(value, kind) jinja global that reads them; latency reuses the
existing ping good/warn keys, uptime is direction-aware (floors).
Replace the _macros metric_style/uptime_style macros (now removed) with the
global across Hosts-Overview, host_agent fleet + panel, Uptime/SLA widget, and
the ping page uptime column — all now honor the configured cutoffs. Uptime keeps
its green 'good' look when not degraded.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Milestone 72 phase A (clarity wins, no schema change):
- Add shared metric_style() macro in _macros.html: colours a numeric metric
amber (>=warn) / red (>=crit) on the value ITSELF, not just the status dot.
Defaults 80/90 for percentage gauges; load /core uses warn 80 / crit 100.
Applied to CPU/mem/disk across host_agent panel + fleet widget + the unified
hosts-overview widget.
- Link every host reference to the host hub (/hosts/<id>) in ping, dns,
hosts-overview, host_agent fleet, and uptime widgets; status widget entries
link to their own detail_url. All guarded on session.user_id so the public
share view degrades to plain text (the bare href carries no share token).
- Fix truncation: title= tooltips on all names that ellipsis, plus a hover
underline affordance on the now-clickable ping-name links.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Host agent panel (reporting state) gains a "Re-provision" collapsible (admin +
linked target + managed key): bootstrap user/password → provision.yml, which
reinstalls the steward account + managed key + agent. This is the missing path
after regenerating the managed key — Update alone can't fix a broken key.
- Remove the Ansible sections (run-playbook + target link) from the host EDIT
page — they were the stale free-text version and the wrong place. They live on
the host detail hub (dropdown + discovered variables). Edit page now links to
the host page; edit_host route simplified (no ansible fetch).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Each at-a-glance metric (CPU, Memory, Disk /, Load) now shows a 6h sparkline
(reused core.status.sparkline_svg + a recent-series query; disk uses the root
mount sub-resource) so trend/consistency is visible, not just the instant.
- Load is now normalized: "Load /core" = 1m load ÷ CPU cores as % (100% = run
queue matches capacity), comparable across different hardware. Cores derived
from the per-core CPU metrics already collected — no agent change. Raw load
in the tooltip.
- Added a "Pressure 10s" line: PSI cpu/mem/io (some, avg10), the
hardware-independent saturation signal already collected by the agent.
Scribe #898.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The "Disk (worst)" number was opaque at a glance. Show the root filesystem (/)
usage instead — what people actually care about — on the host panel and the
dashboard widget. "Worst" is kept only for the widget's health dot (so a full
/var or /data still warns) and on the full-metrics page (per-mount + worst
trend). Added hover tooltips defining CPU / Memory / Disk / Load.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A failed provision looked successful in two ways:
1. The host panel showed the agent as deployed (metrics + Update/Rotate/Remove)
because provision/deploy mint the registration row BEFORE the playbook runs
and the panel keyed "installed" on that row. Now gated on the agent actually
checking in (reg.last_seen_at). Three states: reporting (metrics + lifecycle),
pending (token minted but no check-in → "no metrics yet, deploy may be
running/failed" banner + retry + Clear pending registration), and none
(install path).
2. The run reported success though nothing ran — ansible-playbook exits 0 on
"no hosts matched"/empty inventory. The executor now treats an empty PLAY
RECAP (returncode 0 but no hosts executed) as failed, with a clear failure
note. Non-zero exits and recap failed/unreachable were already caught.
Scribe issue #887.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Dev-only instance, no bookmarks — per family rule 22, fully remove old paths
instead of shimming them.
- Delete the /plugins/host_agent/ (index) and /plugins/host_agent/settings/
redirect routes; delete the now-dead host_list.html fleet template.
- Move the remaining management POST routes off /settings/ to /fleet/
(add-host, rotate-token, delete) — single canonical prefix.
- Repoint real callers to canonical URLs: dashboard widgets (host resources →
/hosts/, history → /plugins/host_agent/fleet/), the full-metrics page
breadcrumb + back link (→ the host hub), Settings→Ansible link, and the
agent panel's curl-install link.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make Hosts the front-and-center hub. A host now has a real detail page at
/hosts/<id> that pulls its facets into one view, instead of management being
scattered across a nav-less Host-Agents area and the edit form.
- hosts: new GET /hosts/<id> detail route + hosts/detail.html. Shows the
monitors summary (ping/DNS status + latency + uptime 24h/7d/30d), an Ansible
section (linked target, link/create, run-playbook), and an embedded Agent
panel. Hosts list name links here; ansible-link redirects here.
- host_agent: GET /plugins/host_agent/panel/<host_id> — a self-contained HTMX
fragment embedded into the core hub across the plugin boundary (core never
imports plugin models). Shows live agent metrics + Update/Rotate/Remove when
installed, or the provisioning path when not: inline "generate managed key"
warning, a prompt to link an Ansible target first, then Provision (bootstrap
password) / Install (managed key) tied to the host's target scope.
Part of milestone 70 (Hosts hub). Phase 2+ will enrich the list, redirect the
old fleet/settings pages, and re-taxonomize plugins into capabilities vs
integrations.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>