一键导入
syswatch-terminal-diagnostics
SysWatch is a single-host system diagnostics TUI for macOS and Linux with twelve tabs, plain-English insights, and session scrubbing.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
SysWatch is a single-host system diagnostics TUI for macOS and Linux with twelve tabs, plain-English insights, and session scrubbing.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
AI agent skill for using deepsec, the agent-powered security vulnerability scanner for large codebases
Open-source Luau/Lua script IDE and executor built as a Windows Forms C# application with Monaco editor integration
Use Claude Code's autonomous agent loop with DeepSeek V4 Pro, OpenRouter, or any Anthropic-compatible backend at up to 17x lower cost.
Native macOS Markdown viewer app with Quick Look extension, Mermaid diagrams, KaTeX math, document outline, and editor integration
Minimalist batteries-included repository for training, evaluating, and deploying diffusion-forcing video world models for robot manipulation, gaming, and MPC planning.
WARNING - This project is malicious software disguised as an FL Studio crack/patcher
| name | syswatch-terminal-diagnostics |
| description | SysWatch is a single-host system diagnostics TUI for macOS and Linux with twelve tabs, plain-English insights, and session scrubbing. |
| triggers | ["add syswatch to my project","monitor system resources in the terminal","use syswatch for diagnostics","integrate syswatch tui","watch cpu memory disk gpu in terminal","syswatch tab navigation and keybindings","syswatch insights and anomaly detection","syswatch session scrubbing and timeline"] |
Skill by 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.
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.
# 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
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
| 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 |
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:
Collectors live in src/collect/. Each one populates a typed Snapshot struct and is called from collector.rs.
// 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.
Tab renderers live in src/tabs/. They receive the current (or scrubbed) snapshot and render into a ratatui Frame.
// 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.
Insights are pure functions in src/insights/. They take history + the latest snapshot and return zero or more anomaly cards.
// 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.
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.
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.
# 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:
cargo build --release --features gpu-nvidia
cargo build --release --features smart
cargo build --release --features gpu-nvidia,smart
ioreg AGXAccelerator PerformanceStatistics.sudo powermetrics. SysWatch shows available data and displays a one-line note where sudo is needed — it never prompts./sys/class/thermal/)./sys/class/drm./sys/class/power_supply.// 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...
}
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.
if !app.paused {
app.collector.collect();
}
| 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 |