Commit graph

10 commits

Author SHA1 Message Date
bb9471442a docs: the repo now lives in Bunkhouse
Binary Ranch Labs was a placeholder name for a public roof. It is now
Bunkhouse: open tools from Binary Ranch, built with the community.

Forge is canonical, GitHub remains the public mirror. The clone command
and the forge link in the README both point at the new home.

Signed-off-by: Christian Sass <csass@binaryranch.com>
2026-10-21 22:02:34 -05:00
6cddabc633 frontend: a status-bar widget, and evidence the data plane is the product
Omarchy 4 runs one long-running Quickshell process and its bar accepts
command modules that print {"text", "tooltip", "class"}. That is the
cheapest native frontend Vitals can have: no QML, no websocket, no plugin
manifest, just a command the bar runs on an interval.

bar_widget.py prints that shape from the existing JSON API, with a
workload selector and a tooltip that carries the verdict line. It also
fails soft, because a status bar should never make a session look broken
when the monitor is down.

This is the point of splitting sampling from presentation: a native UI on
another distro is a new frontend, not a rewrite.

Signed-off-by: Christian Sass <csass@binaryranch.com>
2026-10-21 13:54:07 -05:00
aeb8065807 docs: contribution terms, and a check that enforces them
Vitals takes contributions under MIT, inbound equal to outbound, with a
Developer Certificate of Origin instead of a CLA. That is the same shape
Nextcloud uses on the project this tool was written to watch, so nobody
contributing here is being asked for paperwork they would not sign
upstream.

tools/check-dco.sh verifies both presence and identity of the sign-off,
and fails the pull request if either is wrong. Tested against three
cases: unsigned, correctly signed, and signed by someone other than the
author.

Signed-off-by: Christian Sass <csass@binaryranch.com>
2026-10-21 13:46:29 -05:00
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