# DevicePulse (CLI prototype)
DevicePulse is a persistent, multi-metric vitals-trend log. Each "snapshot"
records three genuinely stdlib-observable things at once — logical CPU count
(runtime.NumCPU), this process's own Go-runtime memory usage (heap-alloc and
sys bytes from runtime.ReadMemStats), and the real on-disk byte size of one
or more directory trees you point it at (--watch, a true recursive file-size
walk) — and appends every snapshot as a line of JSON to a history file on
disk. Because the history accumulates over time, DevicePulse can compare a
watched path's disk usage against its own value from the immediately
previous snapshot and print an automatic WARNING when growth exceeds a
configurable percentage threshold (default 25%), the way a real ops-style
vitals monitor would flag a symptom instead of just reporting a number.
This is a different product from the sibling BROWSER app HardwareLens, which
reads live browser APIs (CPU cores, GPU, network) once per page load and
persists nothing — DevicePulse is CLI-native, writes a durable history log,
and computes trend/alerting logic across snapshots taken minutes, hours, or
days apart. It is also different from the CLI siblings ThermalFlow (which
tracks a single CPU-benchmark-derived metric over time) and DrivePulse
(which maps disk space usage at a point in time but keeps no history and
raises no growth warnings): DevicePulse is a consolidated multi-metric log
(CPU + memory + disk, together) with built-in threshold alerting across
snapshots, which neither sibling does.
Honest scope: real hardware sensors (temperature, fan speed, voltage), drive
S.M.A.R.T./health data, and true OS-level free/total disk-space telemetry
all require privileged OS APIs or vendor SDKs (WMI on Windows, IOKit on
macOS, sysfs/hwmon or smartctl on Linux) that Go's standard library does not
expose portably. DevicePulse deliberately does not fake these — they are
roadmap items. See ../plan.md for the full product plan.
## Build from source
Requires Go 1.24+, no external dependencies.
go build -o devicepulse .
Cross-compile examples:
GOOS=windows GOARCH=amd64 go build -o devicepulse.exe .
GOOS=darwin GOARCH=amd64 go build -o devicepulse .
GOOS=darwin GOARCH=arm64 go build -o devicepulse .
GOOS=linux GOARCH=amd64 go build -o devicepulse .
## Usage
devicepulse snapshot --watch
[--watch ...] --history [--warn-growth-pct N]
devicepulse trend --history [--watch ] [--last N] [--json]
devicepulse status --watch [--watch ...] [--json]
devicepulse help
### snapshot
Takes one real vitals snapshot (num_cpu, this process's Go heap-alloc and
sys memory, and the recursive byte size of each --watch directory tree) and
appends it as one JSON line to --history (creating the file if needed).
For each --watch path, if a PREVIOUS snapshot in the history recorded that
same path, its usage is compared against the current usage:
- growth > --warn-growth-pct (default 25) percent -> a WARNING line, with
the exact computed percentage and the before/after byte counts
- growth at or below the threshold -> a normal informational
line reporting the (still real, computed) percentage change
- no prior snapshot recorded that path yet -> informational
"no prior snapshot to compare against" (first-run case, not an error)
- previous usage was exactly 0 and current usage is not -> a WARNING
noting the percentage is undefined when growing from zero
Flags:
--watch directory tree to measure (repeatable, required,
at least one)
--history path to the JSON-lines history file (required)
--warn-growth-pct growth-warning threshold percent (default 25)
Exit code is 2 if any warning fired, 0 otherwise (1 on a hard error), so the
command is safe to use in scripts/cron as a symptom check.
### trend
Read-only. Prints a table of the last --last N snapshots (default: all) from
--history, plus, for each watched path seen in that window (optionally
restricted to a single path with --watch), the min / max / latest usage
across the shown window. All numbers are arithmetic-checkable against the
raw history file. --json prints the same window as machine-readable JSON.
Pointing --history at a file that does not exist yet prints a clean
"no history yet" message and exits cleanly rather than crashing.
Flags:
--history path to the JSON-lines history file (required)
--watch restrict per-path output to this one watched path
--last show only the last N snapshots (default: all)
--json machine-readable JSON output
### status
Takes one snapshot of num_cpu, this process's Go memory stats, and each
--watch path's disk usage, and prints it — WITHOUT reading or writing any
history file at all. This is the closest CLI equivalent to what
HardwareLens's browser page does (a one-shot look at current vitals), but
scoped to the metrics observable from a CLI process.
Flags:
--watch directory tree to measure (repeatable, required)
--json machine-readable JSON output
## History file format (JSON-lines)
One JSON object per line, append-only:
{"timestamp_utc":"2026-08-10T02:19:24Z","num_cpu":4,"go_heap_alloc_bytes":158432,"go_sys_bytes":6380560,"watched":[{"path":"/tmp/dp_test/watchA","bytes":1600},{"path":"/tmp/dp_test/watchB","bytes":350}]}
Fields:
timestamp_utc RFC3339 UTC timestamp the snapshot was taken
num_cpu runtime.NumCPU() at snapshot time
go_heap_alloc_bytes runtime.MemStats.HeapAlloc for this process (NOT
total system RAM — this process's own Go heap)
go_sys_bytes runtime.MemStats.Sys for this process (NOT total
system RAM)
watched array of {path, bytes} — recursive on-disk size of
each --watch directory tree at snapshot time
## Prebuilt binaries
See ../downloads/ for prebuilt binaries (Windows/macOS/Linux) and
CHECKSUMS.txt for their SHA-256 hashes. Unsigned indie builds — Windows
SmartScreen and macOS Gatekeeper will warn on first run, expected until a
code-signing certificate is in place.