dgx-spark-cli
Agent and CLI for operating an NVIDIA DGX Spark (Grace-Blackwell) workstation — device setup, health/monitoring, and local AI/ML workload management.
What you get
- An agent-first CLI cited from teken
(
afi-cli) — the runtime package has no third-party dependencies. - A mesh identity —
culture.yaml(suffix+backend) and the matching prompt file (CLAUDE.mdforbackend: claude). - The canonical guildmaster skill kit (11 skills) under
.claude/skills/, vendored cite-don't-import. Seedocs/skill-sources.md. - A build + deploy baseline — pytest, lint, the agent-first rubric gate, and PyPI Trusted Publishing wired into GitHub Actions.
Quickstart
uv sync
uv run pytest -n auto # run the test suite
uv run dgx-spark-cli whoami # identity from culture.yaml
uv run dgx-spark-cli learn # self-teaching prompt (add --json)
uv run teken cli doctor . --strict # the agent-first rubric gate CI runs
CLI
| Verb | What it does |
|---|---|
whoami |
Report this agent's nick, version, backend, and model from culture.yaml. |
learn |
Print a structured self-teaching prompt. |
explain <path> |
Markdown docs for any noun/verb path. |
overview |
Read-only descriptive snapshot of the agent. |
doctor |
Check the agent-identity invariants (prompt-file-present, backend-consistency). |
cli overview |
Describe the CLI surface itself. |
Machine scope (DGX Spark host telemetry)
The Spark is the system, so these read-only verbs sit at the top level:
| Verb | What it does |
|---|---|
status |
Machine-wide scope, anomalies first — the headline. |
memory |
Unified RAM + swap (the GB10 shares one pool across CPU and GPU). |
gpu |
Blackwell GB10: utilization, temp, power, clocks, and GPU processes. |
power |
GB10 power draw, SM clocks (current and max) and P-state via nvidia-smi. |
disk |
Filesystem usage for real block devices (via /proc/mounts + statvfs). |
thermal |
SoC thermal zones and hwmon sensors (no lm-sensors needed). |
containers |
Running Docker containers and their health. |
network |
Interfaces, default route, and reachable addresses. |
processes |
Top processes by resident memory (via /proc). |
They have zero runtime dependencies — kernel telemetry is read from /proc and
/sys, while nvidia-smi, docker, and ip are shelled out and degrade
gracefully (a missing tool reports available: false and still exits 0).
doctor remains the health gate. Because the GB10 has no discrete VRAM,
nvidia-smi reports aggregate GPU memory as [N/A]; gpu instead sums
per-process compute-app memory so you can see how much of the shared pool the
GPU holds.
Every command supports --json. Results go to stdout, errors/diagnostics to
stderr (never mixed). Exit codes: 0 success, 1 user error, 2 environment
error, 3+ reserved.
Swap management
Swap inspection is read-only; the grow command is a dry-run by default — re-run with --apply to mutate. All commands support --json.
| Verb | What it does |
|---|---|
spark swap overview |
Comprehensive read of the swap noun: the descriptive summary plus the live snapshot (memory, swap, devices, sar trend). The superset of status. |
spark swap status |
The quick snapshot only: read-only swap + memory pressure with a recent sar trend. No root needed. (Also shown, with the verb list, by spark swap overview.) |
spark swap grow SIZE [--apply] [--ephemeral] |
Grow swap. DEFAULT is a DRY RUN: prints a warning and the exact command plan but changes nothing. Re-run with --apply to actually perform it (needs root — without root it prints the plan and a sudo ... --apply hint). --ephemeral activates the new size for this boot only (no /etc/fstab change); the default is permanent (survives reboot). SIZE is a placeholder — replace it with a value like 64G, 32GiB, or a raw byte count (e.g. spark swap grow 64G; don't type the literal word size). |
spark swap history [--window DUR] [--top N] |
Top per-process memory/swap consumers over a time window (e.g. --window 1h --top 10). |
spark swap sample |
Record one per-process telemetry snapshot (this is what a scheduled timer calls). |
Per-process history collection via systemd timer
Per-process memory and swap history accrues only when spark swap sample runs on a schedule. Here's a systemd service and timer pair:
# /etc/systemd/system/spark-swap-sample.service
[Unit]
Description=Sample per-process swap/memory for dgx-spark-cli
[Service]
Type=oneshot
ExecStart=/usr/bin/env spark swap sample
# /etc/systemd/system/spark-swap-sample.timer
[Unit]
Description=Periodic spark swap sample
[Timer]
OnBootSec=2min
OnUnitActiveSec=10min
Persistent=true
[Install]
WantedBy=timers.target
Enable with sudo systemctl enable --now spark-swap-sample.timer. Note that system-level CPU/mem/swap trend already comes from sysstat/sar; this timer only adds the per-process layer.
Monitoring (monitor) — AI-free webhook watchdog
monitor turns the collectors into a deterministic, always-on watchdog. It
evaluates the same numbers against configurable thresholds and POSTs to a
generic webhook when a catastrophe condition crosses — and again when it
clears (edge-triggered, so a standing condition doesn't spam). No AI, no new
dependencies (urllib does the POST).
dgx-spark-cli monitor config --init # scaffold ~/.config/dgx-spark/monitor.json
export DGX_SPARK_WEBHOOK_URL=https://… # or put webhook_url in the config
dgx-spark-cli monitor check # dry run: what's firing right now
dgx-spark-cli monitor test # POST a synthetic alert
dgx-spark-cli monitor install # write the systemd --user unit
dgx-spark-cli monitor enable # start it always-on (+ linger)
dgx-spark-cli monitor status # service + currently firing alerts
| Verb | What it does |
|---|---|
monitor check |
Evaluate thresholds now (no webhook, no state change). |
monitor once |
One cycle: evaluate, deliver transitions, update state. |
monitor run |
Foreground watch loop (the systemd ExecStart). |
monitor test |
POST a synthetic alert to verify the webhook. |
monitor config [--init] |
Show resolved config / write a scaffold. |
monitor install|enable|disable|status|uninstall |
Manage the systemd --user service. |
Watches memory %, swap %, disk %, hottest sensor, GPU temp, load-per-core,
I/O contention (iowait % + blocked processes), container health, and subsystem
availability. Thresholds live in the config
(null disables a check); webhook_format is generic (default), slack, or
discord.
When monitor run starts (the systemd ExecStart), it POSTs a one-shot
"started watching" liveness alert — so a watchdog that silently fails to come
up is noticed by the absence of its heartbeat, not just the absence of an alert.
A failed startup POST is logged, never fatal. Set notify_on_start: false in the
config to disable it.
Make it your own
- Rename the package
spark/and thedgx-spark-cliCLI/dist name throughoutpyproject.toml, the package,tests/, andsonar-project.properties. - Edit
culture.yamlwith yoursuffixandbackend. - Rewrite
CLAUDE.mdfor your agent and run/init. - Re-vendor only the skills you need from guildmaster (see
docs/skill-sources.md).
See CLAUDE.md for the full conventions (version-bump-every-PR,
the cicd PR lane, deploy setup).
License
MIT — see LICENSE.
Metadata
Release files for dgx-spark-cli 0.8.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dgx_spark_cli-0.8.0.tar.gz | 246.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dgx_spark_cli-0.8.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 342.5 kB
Release files / dgx_spark_cli-0.8.0.tar.gz
| Download URL | dgx_spark_cli-0.8.0.tar.gz |
|---|---|
| Size | 246.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
87d1373160be6d3f8f25b6a83cd8f35de8400f9e842c2d7d4405731eb1bf1ac8
|
|
BLAKE2b-256 checksum How to use checksums |
5de410437169fae22571996d5b24082c6df37ede69b182517b122c735a6153e8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / dgx_spark_cli-0.8.0-py3-none-any.whl
| Download URL | dgx_spark_cli-0.8.0-py3-none-any.whl |
|---|---|
| Size | 96.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
54fafcecb115d362eb019f97ceb89e3686f27c39dc9902470fc4a898504a7787
|
|
BLAKE2b-256 checksum How to use checksums |
8d8f2ba2db04058eb7cf60ad61dea53b793b2ce6ee6d8648a25344ec093bbd85
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|