Commit graph

7 commits

Author SHA1 Message Date
52885cad78 icons: one mark in, every size out, and a place to serve them
Three surfaces were showing generated identicons: the forge org avatar
(which is what Discord unfurls), the GitHub org avatar, and the browser
tab, because the app shipped no favicon at all.

make_icons.py turns one SVG or PNG into the seven sizes plus a
multi-resolution favicon.ico. The server now serves /favicon.ico and
/icons/*.png from icons/ when they exist, and index.html asks for them,
so dropping the real mark into icons/ is the whole integration.

Co-developed-with: CLU <clu@binaryranch.com>
2026-10-21 13:35:45 -05:00
CLU
9cdbb43394 Answer the question the process list asks: what IS that, and whose is it
Eight identical 'call (WebRTC)' rows with no owner is the least useful thing
a monitor can print. Three changes:

- detail panes group processes by role with a plain-English gloss, a pid list,
  and a judgement when a group looks abandoned ('11 of 14 idle for over 30
  min, oldest 201.7h'). The hint states evidence and never says safe to delete,
  because a muted call and a dead call both sit at zero.
- the tab list is one row per URL, duplicates summed with a count badge, each
  row carrying the site's own favicon fetched through the local server and
  cached on disk. Sites with no icon get a letter tile, never a third-party
  icon service.
- Vitals' own cost is in the header, and its own tab is badged 'this screen'.

Tests caught a real bug while writing this: merge_tabs compared each tab to the
group running total, so the busiest tab could never name the row.

Co-developed-with: CLU
2026-10-20 13:56:26 -05:00
CLU
95c1c1d3eb Live UI: stop the page from jumping, and put Vitals in the bookmark bar
The page rebuilt its whole header, bar and row list twice a second, so
numbers snapped, columns resized as digits changed, and rows swapped places
over a hundredth of a core.

- header values are tabular-width and tweened toward the newest sample
- machine-bar segments are keyed and reordered by flex order, so widths
  animate instead of being recreated mid-transition
- rows are keyed DOM nodes updated in place, sorted on a 0.1-core grid with
  the previous order as tiebreak, with hysteresis at the idle threshold
- tabs, banner and detail panes only re-render when their data changes
- poll every 700ms and drop repeat frames from the 2s sampler

bookmark.py puts a Vitals bookmark and a popup bookmarklet in the browser's
bookmark bar. It recomputes Chromium's bookmark checksum (MD5 over the
canonical node serialisation) and verifies it after writing, because a file
that fails that check leaves the browser showing an empty bar while the file
on disk still looks perfect. Refuses while the browser holds the profile,
keeps a timestamped backup, idempotent. install.sh runs it.

Co-developed-with: CLU
2026-10-20 13:52:49 -05:00
f086afc030 docs: point clone and documentation links at the real homes
The quickstart still told people to clone sastian/vitals on the forge,
which stopped existing when the repo moved to binaryranch-labs. A broken
clone command in the first code block is the worst place to have one.

Co-developed-with: CLU <clu@binaryranch.com>
2026-10-19 17:03:52 -05:00
cd6e76c830 docs: record authorship and how to credit it
Credit is not a courtesy here, it is a factual claim about who decided
what. Christian supplied the question, the framing (the browser is the top
layer of the OS), and the field evidence; the code and its failures are
mine. AUTHORS.md states that split so a future reader does not have to
guess.

Co-developed-with: CLU <clu@binaryranch.com>
2026-10-19 16:50:18 -05:00
b66c6619d8 docs: synthetic demo mode and a screenshot with no customer data
The first screenshot was captured on a real workstation: it carried a
machine name, a live call with a named participant, and a staging URL.
None of that belongs in a public repo.

--demo now loads demo/demo-snapshot.json and serves it through the same
API, so documentation screenshots are reproducible, reviewable, and free
of anyone's actual desktop. The canned snapshot is shaped to tell the
story: a leaked automation run at 6.10 cores with idle pages, and a video
call tab carrying 221% page work beside its idle siblings.
2026-10-19 16:49:07 -05:00
9d065153b0 Vitals 0.1.0: workload map with browser tab accounting
Process monitors stop at the browser boundary, so the thing that usually
pegs a machine is invisible: forty identical processes, no age, no tab
names, no idea which page is the offender.

Vitals resolves every process to a human identity (container, flatpak,
systemd unit, tree root, or script), then joins the OS view to the
browser's own DevTools counters so each tab carries its own page-work
number beside the cores its browser instance is burning. The gap between
those two numbers is the diagnosis: idle page, burning compositor.

- dependency-free sampler over /proc, 2s cadence, 5 min in-memory history
- minimal CDP client (WebSocket + JSON) with no third-party packages
- both unit systems side by side: percent of machine and fractional cores
- flags for leaked automation instances and live WebRTC calls
- user service with CPUQuota so the monitor can never be the problem
- identity tests that need no root, server, or browser

MIT licensed. Runs on Linux, reads /proc, asks for no privilege.
2026-10-19 16:42:54 -05:00