Last entry of ``KNOWN_V5_MISSING_PLUGINS`` after this commit:
``("processlist",)``.
Model (``glances/plugins/diskio/model_v5.py``):
- Fields: disk_name (PK, string), read_count / write_count
(rate, number, internal — exportable for IOPS consumers but
not rendered), read_bytes / write_bytes (rate, bytespers, watched,
``prominent=False``, ``strict_thresholds=True``, NO default
thresholds).
- Sustained disk traffic is host-specific (a DB server may stream
MB/s by design) — alerts only fire when operators set
``read_bytes_warning=...`` per-disk or per-field in
``[diskio]``. ``strict_thresholds=True`` blocks the bare-``<level>``
fallback (same pattern as memswap.sin/sout) so a legacy
``[diskio] careful=50`` cannot trigger spurious alerts.
- ``read_time``/``write_time`` and the derived ``read_latency`` /
``write_latency`` of v4 are not ported — deferred with the
``--diskio-latency`` mode.
- ``psutil.disk_io_counters()`` may raise or return ``None`` on
platforms without disk I/O support — model returns ``[]`` rather
than crashing.
Renderer (``glances/plugins/diskio/render_curses_v5.py``):
DISK I/O R/s W/s
nvme0n1 0B 0B
sda 1.4M 732K
- 3-cell rows, 18 + 1 + 7 + 1 + 7 = 34 chars (fits sidebar cap).
- Sorted by disk_name. Cycle-1 disks (no rate baseline) are skipped
entirely — no ``-`` placeholder wall on startup.
- Rate cells display ``auto_unit(bytes_per_sec)`` WITHOUT a trailing
``/s`` — header carries the per-second semantic (v4 parity).
- Long disk names tail-truncated with leading underscore.
Adjacent:
- ``KNOWN_V5_MISSING_PLUGINS`` shrinks to ``("processlist",)``.
- ``test_attach_mcp_logs_known_v5_gaps`` updated.
- v4 catalogue grows a ``## diskio`` section + ✅ footer.
28 new tests (13 model + 15 renderer). Full v5 suite: 762 passed.
Sister of the v5 ``mem`` plugin. Same pattern, slimmer layout
(single-column body — v4 ``memswap.msg_curse`` does not 2-col).
Model (``glances/plugins/memswap/model_v5.py``):
- ``total`` / ``used`` / ``free`` — bytes, snapshot.
- ``percent`` — watched + prominent, default thresholds 50/70/90
(same ladder as ``mem`` for UX consistency).
- ``sin`` / ``sout`` — cumulative in v4; v5 exposes them as
bytes/sec via ``rate: True``.
- Tolerates platforms without a swap file (Illumos, OpenBSD —
issues #1767, #2719): psutil raises, model returns ``{}`` so
the scheduler tick keeps going.
Renderer (``glances/plugins/memswap/render_curses_v5.py``):
SWAP 25.0%
total 16.0G
used 4.0G
free 12.0G
- Line 1: ``SWAP`` (HEADER) + percent cell coloured by ``_levels.percent``.
Title escalates to warning/critical when the prominent percent reaches
those levels.
- Lines 2-4: ``total`` / ``used`` / ``free`` as label/value pairs.
- Value column floored at 6 chars so it does not jiggle between cycles.
Adjacent changes:
- ``KNOWN_V5_MISSING_PLUGINS`` in ``mcp_adapter_v5`` shrinks to
``processlist, fs, diskio`` — memswap no longer surfaces in the
MCP startup gap log.
- v4 catalogue (``docs/architecture/tui-v4-rendering-patterns.md``)
grows a ``## memswap`` section + ✅ footer pointing to the new
renderer.
22 new tests (11 model + 11 renderer). Full v5 suite: 669 passed
(+22), lint clean.
- ``conf/glances.conf``: add a commented ``[outputs] enable_mcp``
entry above the existing ``mcp_path`` / ``mcp_allowed_hosts`` keys.
Notes that the gate is off by default and that ``--enable-mcp``
flips it via the config overlay.
- ``docs/architecture/glances-v5-architecture-decisions.md``: new
§11 "MCP endpoint" covering:
- §11.1 opt-in lifecycle (CLI + config)
- §11.2 adapter architecture + flow diagram
- §11.3 resource/prompt inventory with v5 status per entry
- §11.4 known v5 gaps (logged on mount)
- §11.5 alert schema (v5-native, no v4 translation — decision
logged in the G3-MCP plan)
- §11.6 auth (HTTP middleware passes SSE through; no special MCP
middleware needed)
- §11.7 DNS rebinding (independent ``mcp_allowed_hosts``)
- §11.8 out of scope (history buffer, unported v4 plugins,
WebSocket transport)
Plan covers 6 tasks: adapter, mount in webserver_v5 (gated by
[outputs] enable_mcp), CLI overlay propagation, explicit gap docs
(history + missing plugins), conf + architecture doc, final sweep.
Scope contract: do NOT rewrite GlancesMcpServer. Introduce a thin
McpStatsAdapter / McpPluginView in glances/outputs/mcp_adapter_v5.py
that exposes the v4-style stats interface (getPluginsList,
get_plugin(name), get_raw, get_limits, ...) over StatsStoreV5 +
plugin registry + GlancesAlerts.
Surfaces v5 gaps explicitly:
- no history → adapter returns {} + WARN log (1× per plugin);
- processlist/fs/diskio/memswap not in v5 → get_plugin returns None,
MCP raises the canonical "Plugin not found" ValueError;
- auth+SSE: middleware must not buffer; verify or port v4
GlancesMcpAuthMiddleware pattern.
Decision logged: alert schema = v5-native (option a, no v4 translation).
- New §1.5 "Mode dispatch (CLI ↔ runtime)": alignment table, ASCII
diagram of the assemble/serve branching, rationale (v4 mental model
+ remove unauthenticated default footgun), and open points (fate of
--quiet/--no-tui, client mode).
- §1.4 (TUI thread): rephrased "CLI control" + "Shutdown" bullets to
reflect that default mode no longer starts uvicorn.
- §4 (REST API): preamble notes the API server is now opt-in via -s;
every subsection below applies to server mode exclusively.
MCP wiring is referenced as deferred to a dedicated G3-MCP plan
(consistent with Task 2 of G2 being dropped).
- ``run-v5``: TUI mode (the new default — help string updated to
reflect it no longer binds a socket).
- ``run-v5-debug``: TUI mode + ``-d``.
- ``run-v5-server`` (new): REST API mode (``-s``), headless.
- ``run-v5-server-debug`` (new): REST mode + ``-d``.
- ``run-v5-mcp`` (new): REST + ``--enable-mcp``. The flag is accepted +
validated today but the MCP mount is not yet wired into v5 — see the
plan footer (Task 2 dropped, deferred to a dedicated G3-MCP plan).
Also updates the plan file: marks Task 2 (MCP gate) as DROPPED with a
rationale section explaining that MCP is not yet wired into v5
``webserver_v5``, so there is nothing to gate. The CLI flag + validation
shipped in Task 1 are kept; the actual mount + gate will land in
G3-MCP.
- Add a "✅ v5 renderer at ..." footer line under each migrated plugin
section of the v4 TUI rendering catalogue (cpu, mem, load, network,
percpu). Network + percpu footers also note which v4 modes are
deferred to G2+ (--byte / --network-cumul / --network-sum and the
quicklook-enabled toggle).
- New NEWS.rst entry for ``5.0.0a3 (Phase 2 G1)`` summarising the
per-plugin renderer convention, the discovery mechanism, the new
schema renderer hints (short_name / internal), and the visual-parity
groundwork (prominent reverse pairs, 3-cycle alert warmup, top-row
spacing, CPU/perCPU toggle, dynamic title color, psutil baseline guard).
Plugins can declare an optional short_name in fields_description for
compact label display in tight per-plugin renderers:
ctx_switches.short_name = 'ctx_sw'
soft_interrupts.short_name = 'sw_int'
interrupts.short_name = 'inter'
A new field_label(schema, field_name, prefer_short=False) helper
encapsulates the resolution order:
- prefer_short=True: short_name -> label -> field name
- prefer_short=False (default, generic renderer): label -> field name
The cpu render_curses_v5 now pulls every column label via
field_label(..., prefer_short=True) instead of hardcoding labels.
Mirrors v4 short_name (cf. curse_add_stat in plugins/plugin/model.py).
Documented in architecture decisions section 3.2 and SKILL-plugin.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
One commit per plugin, each replicating its v4 msg_curse layout. Each
task starts by reading the v4 source + catalogue (project memory rule
`feedback-tui-v5-must-mirror-v4`).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- SKILL-plugin.md: new section explaining when and how to write a
per-plugin TUI renderer; pointers to cpu reference + v4 catalogue.
- architecture §1.4: per-plugin renderer documented as the escape hatch
for layouts the generic table fallback cannot produce.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two TUI corrections raised by the v4/v5 visual comparison:
1. Internal fields (time_since_update, cpucore) leaked into the UI. They
are computation support (rate divisor, threshold normalizer) and
should never be displayed. Introduces a new `internal: True` flag in
the `fields_description` schema. Tagged:
- time_since_update (base class, every plugin)
- cpucore (cpu, load)
The flag is rendering-only: the field still goes through the REST
API and is available to `normalize_by` / `rate` computations.
2. Plugin blocks rendered as left/right cells with a fixed 1-space gap,
which made cpu/mem/load blocks misaligned. Now:
- scalar blocks: 2-column table (label left-aligned, value right-aligned)
- collection blocks: N-column table (primary key left-aligned, rest right)
Column widths auto-fit the widest content per block.
Docs:
- SKILL-plugin.md: `internal` added to renderer-hints table
- glances-v5-architecture-decisions.md §3.2: `internal` documented
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add the v5 configuration module with layered overlay (defaults → /etc →
XDG → → -C → env vars), typed get() accessor,
as_dict_secure() for CVE-2026-32609 redaction, and a reload() hook
preparing the Phase 4 mtime polling.
The module lives next to glances/config.py (v4) without import or
inheritance — strict isolation throughout the v5 transition.
42 unit tests (unittest only, no pytest per architecture decision §9),
~30 ms total. Ruff check + format clean.
Includes the SKILL-config.md contributor doc.
Refs: docs/architecture/glances-v5-architecture-decisions.md (§2, Phase 0)
- Add [mpp] section to conf/glances.conf with disable=True
- Add docs/aoa/mpp.rst documentation page and index entry
- Add unit test test_026_mpp with Rockchip MPP test fixtures
- Remove unnecessary hasattr guard on get_refresh()
- Init _last_stats_computed_time to time.time() to avoid stale first reading
- Guard against ZeroDivisionError in IO/network rate calculations
- Use title-case status from pylxd directly
- Add trailing newline to containers.rst
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>