diff --git a/.agents/phases/todo/08_events_paging_and_copy/00_phase.md b/.agents/phases/complete/08_events_paging_and_copy/00_phase.md similarity index 100% rename from .agents/phases/todo/08_events_paging_and_copy/00_phase.md rename to .agents/phases/complete/08_events_paging_and_copy/00_phase.md diff --git a/.agents/phases/todo/08_events_paging_and_copy/01_paginate_event_feeds.md b/.agents/phases/complete/08_events_paging_and_copy/01_paginate_event_feeds.md similarity index 100% rename from .agents/phases/todo/08_events_paging_and_copy/01_paginate_event_feeds.md rename to .agents/phases/complete/08_events_paging_and_copy/01_paginate_event_feeds.md diff --git a/.agents/phases/todo/08_events_paging_and_copy/02_strip_flavor_text.md b/.agents/phases/complete/08_events_paging_and_copy/02_strip_flavor_text.md similarity index 100% rename from .agents/phases/todo/08_events_paging_and_copy/02_strip_flavor_text.md rename to .agents/phases/complete/08_events_paging_and_copy/02_strip_flavor_text.md diff --git a/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.err b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.err new file mode 100644 index 0000000..e69de29 diff --git a/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.md b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.md new file mode 100644 index 0000000..6b4489c --- /dev/null +++ b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.md @@ -0,0 +1,19 @@ +All green. Final report: + +**Verified (phase 08 — both task files already in `complete/`; this was the final verification pass)** +- `Dash.eventsPager()` in `app.js` (50/page, `1–50 of N` strip, aria-labelled `‹ prev`/`next ›` disabled at the ends, `WeakMap` page state, reset only when the event *set* changes, `EVENT_FEED_LIMIT`=200) with three call sites; `ul.events` bounded to 320px + `overflow-y:auto`; `/api/events` untouched (`le=500`, no silent clamp). +- Live browser against the real fleet: `/system` `1–50 of 121`, `/llm` `1–50 of 200`, `/ups` `1–50 of 200`; container 320px vs scrollHeight 1543/2368; page 2 → `51–100 of 200` and survived two polls; no empty `.sub`/`.faint` container visible on any page; footers carry only measurements (`rates over Δ11.9s · poll 10s`). Fresh artifacts: `data/logs/08-final-{system-head,llm-page,index-page,ups-feed-page2}.png` (32 phase screenshots already present). +- Grep of live served bytes for all 13 deleted flavour fragments + `actions = -`: none survive in HTML or JS. +- `AGENTS.md` carries both new UI-convention rules (flavour-text rule with the `TODO.md:7` cited examples; the event-feed-window rule) and the updated test count. + +**Tests / lint (full project 100% green)** +- `bash .agents/validate.sh` → **EXIT=0**: `uv run pytest --cov --cov-fail-under=94` → **624 passed, 9 skipped, coverage 97.91%**; `ruff check src tests agent` → All checks passed; `pyright` → 0 errors; `node --check` ×5 clean; repo hygiene clean. +- `uv run pytest -m live --live` (`.env.dev` sourced) → **9 passed**; `uv pip list --outdated` → empty. Re-ran pytest/ruff/pyright/node after the doc edits → all exit 0. + +**Completion criteria**: bounded scroll + 50/page + count footer ✅ (all three feeds, live) · no removed flavour string ✅ · AGENTS.md rule ✅ · `validate.sh` green + screenshots in `data/logs/` ✅. + +**Documentation**: full README/AGENTS review against code (env table vs `config.py`/`.env*.example`, script flags, Containerfile uid 10001/8090, chart heights 120/110/160, test count, coverage) — one inaccuracy fixed: README said "Every page's event feed" (the overview has none) → now "The three event feeds (`/system`, `/llm`, `/ups`)"; also restored the missing trailing newline in `TODO.md`. Everything else verified consistent. + +**Notes**: paging stays client-side (no API change); the task-02 defect fix in `/ups` setup copy (`NUT_HOST`/`NUT_PORT`, `LISTEN 127.0.0.1`, one `instcmds` per command, never `actions = -`) re-verified against README and live bytes. Pre-existing items intentionally left to their own phases: `ups.test.result: "Done and passed"` rated `warn` (operator's `TODO.md` entry) and the dev-DB `database is locked` retention issue. + +**Next pending phase**: `.agents/phases/todo/09_disks_smartctl/` diff --git a/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.md.status b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.md.status new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.md.status @@ -0,0 +1 @@ +ok diff --git a/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.validate b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.validate new file mode 100644 index 0000000..36b642f --- /dev/null +++ b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.validate @@ -0,0 +1,48 @@ +== uv run pytest --cov (hermetic: no network, live tests skip) == +........................................................................ [ 11%] +........................................................................ [ 22%] +........................................................................ [ 34%] +........................................................................ [ 45%] +...........................sssssssss.................................... [ 56%] +........................................................................ [ 68%] +........................................................................ [ 79%] +........................................................................ [ 90%] +......................................................... [100%] +=============================== warnings summary =============================== +.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1 + /var/home/ducoterra/Projects/Personal/dashboards/.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead. + from starlette.testclient import TestClient as TestClient # noqa + +-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html +================================ tests coverage ================================ +_______________ coverage: platform linux, python 3.14.4-final-0 ________________ + +Name Stmts Miss Cover Missing +------------------------------------------------------------------ +src/dashboards/__init__.py 3 0 100% +src/dashboards/__main__.py 14 1 93% 28 +src/dashboards/alerts.py 166 0 100% +src/dashboards/api.py 193 0 100% +src/dashboards/app.py 107 6 94% 50-51, 56, 58, 60, 127 +src/dashboards/collectors.py 142 5 96% 97-98, 102-103, 120 +src/dashboards/config.py 113 0 100% +src/dashboards/debug.py 14 0 100% +src/dashboards/poller.py 165 3 98% 192-194, 279 +src/dashboards/prom.py 105 5 95% 107, 144, 158, 161, 164 +src/dashboards/rates.py 37 1 97% 51 +src/dashboards/severity.py 49 0 100% +src/dashboards/sources/__init__.py 0 0 100% +src/dashboards/sources/host.py 199 1 99% 147 +src/dashboards/sources/llm.py 150 1 99% 228 +src/dashboards/sources/nut.py 389 20 95% 128, 142, 148, 160, 166, 178, 186, 199, 270-271, 273, 489, 501, 536, 569, 573, 630-631, 636, 648 +src/dashboards/sources/nut_sim.py 134 0 100% +src/dashboards/store.py 178 2 99% 243-244 +------------------------------------------------------------------ +TOTAL 2158 45 98% +Required test coverage of 94% reached. Total coverage: 97.91% +624 passed, 9 skipped, 1 warning in 53.90s +== uv run ruff check src tests agent == +All checks passed! +== uv run pyright == +0 errors, 0 warnings, 0 informations +== node --check src/dashboards/web/static/*.js == diff --git a/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__01_paginate_event_feeds.a1.err b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__01_paginate_event_feeds.a1.err new file mode 100644 index 0000000..e69de29 diff --git a/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__01_paginate_event_feeds.a1.md b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__01_paginate_event_feeds.a1.md new file mode 100644 index 0000000..4e2b74c --- /dev/null +++ b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__01_paginate_event_feeds.a1.md @@ -0,0 +1,14 @@ +**Implemented (task 01 — event feeds: scrollable and paginated)** +- `Dash.eventsPager(el, events, opts)` in `app.js`: one shared pager — 50 rows/page, `1–50 of N` footer with `‹ prev` / `next ›` (aria-labelled for direction, `disabled` at the ends), strip hidden when the feed fits, page state in a `WeakMap` keyed by the `