syswatch-terminal-diagnostics
SysWatch is a single-host system diagnostics TUI for macOS and Linux with twelve tabs, plain-English insights, and session scrubbing.
Best use case
syswatch-terminal-diagnostics is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
SysWatch is a single-host system diagnostics TUI for macOS and Linux with twelve tabs, plain-English insights, and session scrubbing.
Teams using syswatch-terminal-diagnostics should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/syswatch-terminal-diagnostics/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How syswatch-terminal-diagnostics Compares
| Feature / Agent | syswatch-terminal-diagnostics | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
SysWatch is a single-host system diagnostics TUI for macOS and Linux with twelve tabs, plain-English insights, and session scrubbing.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# SysWatch Terminal Diagnostics
> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection.
SysWatch is a single-host system diagnostics TUI written in Rust for macOS and Linux. It consolidates what you'd normally get from `htop`, `iostat`, `vm_stat`, `powermetrics`, `launchctl`, and many other tools into twelve navigable tabs, with plain-English anomaly detection and a session-wide scrubber.
---
## Install
```bash
git clone https://github.com/matthart1983/syswatch.git && cd syswatch
cargo build --release
./target/release/syswatch
```
**Requirements:** Rust 1.75+. No extra system dependencies on Linux. macOS links against system frameworks automatically.
> Crates.io, Homebrew, and pre-built binaries are planned for the v0.1 release.
---
## Running SysWatch
```bash
# Default — 1 Hz refresh
./target/release/syswatch
# 2 Hz refresh (500 ms tick)
syswatch --tick 500
# Boot directly into a specific tab
syswatch --tab procs
syswatch --tab cpu
syswatch --tab insights
```
---
## Key Bindings
```text
1 2 3 4 5 6 7 8 9 Overview / CPU / Mem / Disks / FS / Procs / GPU / Power / Services
0 - + Net / Timeline / Insights
Tab / Shift-Tab Cycle tabs forward / backward
↑ / ↓ Select row (Procs, Services tabs)
s Cycle sort column (Procs, Services tabs)
← / → Scrub session backward / forward (Timeline tab)
Home / End Jump to oldest sample / return to live
p Pause collection
q / Ctrl-C Quit
```
---
## Tabs Reference
| Key | Tab | Data Source / Replaces |
|-----|-----|------------------------|
| `1` | Overview | Dashboard of all subsystems |
| `2` | CPU | `htop` CPU panel, `mpstat`, `top -d` |
| `3` | Memory | `free`, `vm_stat`, `htop` mem panel |
| `4` | Disks | `iostat`, `iotop` (aggregate) |
| `5` | Filesystems | `df -h`, `df -i`, `mount` |
| `6` | Procs | `htop`, `ps auxf`, `pstree` |
| `7` | GPU | `ioreg AGXAccelerator` / `/sys/class/drm` |
| `8` | Power | `pmset`, `ioreg AppleSmartBattery` / `/sys/class/power_supply` |
| `9` | Services | `launchctl list` / `systemctl list-units` |
| `0` | Net | `nettop`, `iftop` |
| `-` | Timeline | Session log + scrubber |
| `+` | Insights | Plain-English anomaly cards |
---
## Architecture Overview
```text
src/
├── main.rs CLI entry point + arg parsing
├── app.rs Event loop, tab state, scrub plumbing
├── collect/
│ ├── collector.rs sysinfo-backed CPU/Mem/Procs + dispatch
│ ├── gpu.rs system_profiler / sysfs DRM
│ ├── power.rs ioreg / pmset / sysfs power_supply
│ ├── services.rs launchctl / systemctl
│ └── ring.rs Bounded history ring + nth_back for scrubbing
├── insights/ Pure functions over (History, &Snapshot)
├── tabs/ One file per tab — thin renderers over the model
└── ui/
├── chrome.rs Header, tab bar, footer
├── palette.rs Single color source of truth
└── widgets.rs block_bar, sparkline, panel helpers
```
**Refresh model:**
- **1 Hz** fast loop: CPU, Memory, Procs, Net, IO
- **5 s** slow loop: Power, Services (subprocess-heavy on macOS)
- CPU budget target: < 0.5% at idle
---
## Extending SysWatch: Adding a Collector
Collectors live in `src/collect/`. Each one populates a typed `Snapshot` struct and is called from `collector.rs`.
```rust
// src/collect/my_subsystem.rs
use crate::collect::ring::Ring;
#[derive(Debug, Clone)]
pub struct MySnapshot {
pub value: f64,
pub label: String,
}
pub struct MyCollector {
history: Ring<MySnapshot>,
}
impl MyCollector {
pub fn new(capacity: usize) -> Self {
Self {
history: Ring::new(capacity),
}
}
pub fn collect(&mut self) -> MySnapshot {
// Replace with real data collection
let snap = MySnapshot {
value: 42.0,
label: "example".to_string(),
};
self.history.push(snap.clone());
snap
}
/// Returns the nth most recent snapshot (for scrubbing).
pub fn nth_back(&self, n: usize) -> Option<&MySnapshot> {
self.history.nth_back(n)
}
}
```
Register it in `collector.rs` and call `collect()` in the fast or slow loop as appropriate.
---
## Extending SysWatch: Adding a Tab Renderer
Tab renderers live in `src/tabs/`. They receive the current (or scrubbed) snapshot and render into a `ratatui` `Frame`.
```rust
// src/tabs/my_tab.rs
use ratatui::{
layout::{Constraint, Direction, Layout, Rect},
style::{Color, Style},
widgets::{Block, Borders, Paragraph},
Frame,
};
use crate::collect::my_subsystem::MySnapshot;
pub fn render(f: &mut Frame, area: Rect, snap: &MySnapshot) {
let block = Block::default()
.title(" My Tab ")
.borders(Borders::ALL)
.border_style(Style::default().fg(Color::Cyan));
let text = Paragraph::new(format!(
"Value: {:.2}\nLabel: {}",
snap.value, snap.label
))
.block(block);
f.render_widget(text, area);
}
```
Wire it into `app.rs`'s tab dispatch match arm and add the tab label to `ui/chrome.rs`.
---
## Extending SysWatch: Adding an Insight
Insights are pure functions in `src/insights/`. They take history + the latest snapshot and return zero or more anomaly cards.
```rust
// src/insights/my_insight.rs
use crate::collect::my_subsystem::MySnapshot;
#[derive(Debug, Clone)]
pub struct InsightCard {
pub title: String,
pub body: String,
pub suggested_tab: &'static str,
}
pub fn check(snap: &MySnapshot) -> Vec<InsightCard> {
let mut cards = vec![];
if snap.value > 90.0 {
cards.push(InsightCard {
title: "High value detected".to_string(),
body: format!(
"Current value is {:.1}, which exceeds the 90.0 threshold.",
snap.value
),
suggested_tab: "my_tab",
});
}
cards
}
```
Register the check in `insights/mod.rs` so it's included in the Insights tab and Overview badge.
---
## Using the Ring Buffer (Session Scrubbing)
The `Ring<T>` type in `src/collect/ring.rs` is the backbone of session scrubbing. Any collector that wraps its history in a `Ring` gets scrubbing for free when the tab renderer calls `nth_back`.
```rust
use crate::collect::ring::Ring;
// Create a ring holding 3600 samples (1 hour at 1 Hz)
let mut ring: Ring<f64> = Ring::new(3600);
// Push a new sample each tick
ring.push(42.0);
// In scrub mode, app.rs tracks `scrub_offset: usize`
// 0 = live, N = N ticks in the past
let scrub_offset = 5; // 5 seconds ago
if let Some(val) = ring.nth_back(scrub_offset) {
println!("Value 5s ago: {}", val);
}
```
In `app.rs`, the `←`/`→` keys increment/decrement `scrub_offset`, and every tab renderer receives the offset so they all show the same point in time.
---
## Optional Cargo Features
```toml
# Cargo.toml — enable NVIDIA GPU stats (requires NVML / nvidia-smi)
[features]
gpu-nvidia = ["nvml-wrapper"]
# Enable SMART disk health (requires smartctl in PATH)
smart = []
```
Build with a feature:
```bash
cargo build --release --features gpu-nvidia
cargo build --release --features smart
cargo build --release --features gpu-nvidia,smart
```
---
## Platform Notes
### macOS
- GPU utilization and used memory on Apple Silicon: available **without sudo** via `ioreg AGXAccelerator PerformanceStatistics`.
- Fan speeds, per-component power, GPU temperature: require `sudo powermetrics`. SysWatch shows available data and displays a one-line note where sudo is needed — it never prompts.
- Thermal zone temps require IOReport private FFI (deferred).
### Linux
- Thermal zones: available for free via sysfs (`/sys/class/thermal/`).
- GPU data: read from `/sys/class/drm`.
- Power supply: `/sys/class/power_supply`.
- No elevated privileges required for core functionality.
---
## Common Patterns
### Checking live vs. scrubbed state in a tab
```rust
// In app.rs, scrub_offset == 0 means "live"
pub struct App {
pub scrub_offset: usize,
// ...
}
// In a tab renderer:
pub fn render(f: &mut Frame, area: Rect, app: &App) {
let snap = if app.scrub_offset == 0 {
app.collector.latest()
} else {
app.collector.nth_back(app.scrub_offset)
.unwrap_or_else(|| app.collector.latest())
};
// render snap...
}
```
### Pausing collection
The `p` key sets `app.paused = true`. The event loop skips `collect()` calls but the UI still redraws on keypress, so scrubbing works while paused.
```rust
if !app.paused {
app.collector.collect();
}
```
---
## Troubleshooting
| Symptom | Fix |
|---------|-----|
| `cargo build` fails on macOS with framework linker errors | Ensure Xcode Command Line Tools are installed: `xcode-select --install` |
| GPU tab shows "no data" on Apple Silicon | Normal without sudo for temp/power; util + memory should appear via ioreg |
| Services tab is slow to update | Expected — launchctl/systemctl are subprocess-heavy; they run on the 5 s slow loop |
| Timeline scrubbing shows stale data | The ring capacity is set at startup; scrubbing is limited to collected history |
| Net tab shows no interfaces | May need to run as a user with access to network stats; check `netwatch-sdk` compatibility |
| `syswatch --tab X` not recognized | Use lowercase tab names: `cpu`, `mem`, `disks`, `fs`, `procs`, `gpu`, `power`, `services`, `net`, `timeline`, `insights`, `overview` |
---
## Anti-Goals (What SysWatch Will Not Do)
- **Not multi-host** — use NetWatch's web dashboard for fleet monitoring.
- **Not a daemon** — no background collector, no Prometheus push.
- **Not interactive** — read-only by design; does not kill, renice, unmount, or restart anything.
- **Not a log search UI** — surfaces OOM kills as signals; does not index logs.
- **No smooth charts** — block sparklines and real numbers only.
---
## Related Projects
- [NetWatch](https://github.com/matthart1983/netwatch) — sibling network diagnostics TUI, same chrome and palette.
- [netwatch-sdk](https://github.com/matthart1983/netwatch-sdk) — shared parsers for net interface counters and aggregate disk IO used by both tools.Related Skills
wterm-web-terminal
Web terminal emulator with Zig/WASM core, DOM rendering, and React/vanilla JS bindings
sheets-terminal-spreadsheet
Terminal-based spreadsheet TUI tool written in Go for editing CSV files in the terminal with vim-like keybindings
rattles-terminal-spinners
Minimal terminal spinner library for Rust with preset collection and no-std support
ghostling-libghostty-terminal
Build minimal terminal emulators using the libghostty-vt C API with Raylib for windowing and rendering
cmux-terminal-multiplexer
AI-native terminal multiplexer with programmable socket API, full Playwright-equivalent browser automation, and agent team coordination — built for Claude Code and autonomous agent workflows
```markdown
---
zeroboot-vm-sandbox
Sub-millisecond VM sandboxes for AI agents using copy-on-write KVM forking via Zeroboot
yourvpndead-vpn-detection
Android app that detects VPN/proxy servers (VLESS/xray/sing-box) via local SOCKS5 vulnerability, exposing exit IPs and server configs without root
xata-postgres-platform
Expert skill for Xata open-source cloud-native Postgres platform with copy-on-write branching, scale-to-zero, and Kubernetes deployment
x-mentor-skill-nuwa
AI-powered X (Twitter) content strategy skill that distills methodologies from 6 top creators + open-source algorithm data into actionable writing, growth, and monetization guidance.
wx-favorites-report
End-to-end pipeline to extract, decrypt, and visualize WeChat Mac favorites from encrypted SQLite DB into an interactive HTML report.
worldmonitor-intelligence-dashboard
Real-time global intelligence dashboard with AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking