jetson-thor-cli
Agent and CLI for operating NVIDIA Jetson Thor (Blackwell-based robotics/edge-AI compute, Orin's successor) — provisioning, inference, and on-device ops.
What you get
- An agent-first CLI cited from teken's
python-clireference — the runtime package has no third-party dependencies. - A mesh identity —
culture.yaml(suffix+backend) and the matching resident prompt file (AGENTS.colleague.md, since this template runsbackend: colleague). - The canonical guildmaster skill kit (14 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 thor whoami # identity from culture.yaml
uv run thor learn # self-teaching prompt (add --json)
uv run thor status # machine-wide scope, anomalies first
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. |
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.
Machine scope (Jetson Thor host telemetry)
Jetson Thor 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 (includes the L4T version). |
memory |
Unified RAM + swap (CPU and iGPU share one pool). |
gpu |
Blackwell iGPU: utilization, temp, power, clocks, and GPU processes. |
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). |
power |
nvpmodel mode, jetson_clocks state, and per-rail power draw (Jetson-only — no discrete-GPU equivalent). |
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.
On real Thor hardware nvidia-smi is present but thin: it reports
name/utilization.gpu/utilization.memory but temperature.gpu,
power.draw, and clocks.sm all come back [N/A] — the iGPU doesn't expose
those counters through NVML the way a discrete card does. gpu backfills
those three fields from stable sysfs nodes instead (devfreq for clock, the
*gpu* thermal zone for temperature, the VDD_GPU hwmon rail for power), and
records which fields it backfilled in source (nvidia-smi+sysfs). Because
Thor's GPU shares one unified memory pool with the CPU — no discrete
VRAM — nvidia-smi reports memory.total/memory.used as [N/A] too; gpu
instead sums per-process compute-app memory and points at thor memory for
the shared pool rather than inventing a VRAM number:
uv run thor gpu
uv run thor power
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 |
|---|---|
thor swap overview |
Comprehensive read of the swap noun: the descriptive summary plus the live snapshot (memory, swap, devices, sar trend). The superset of status. |
thor 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 thor swap overview.) |
thor 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. thor swap grow 64G; don't type the literal word size). |
thor swap history [--window DUR] [--top N] |
Top per-process memory/swap consumers over a time window (e.g. --window 1h --top 10). |
thor swap sample |
Record one per-process telemetry snapshot (this is what a scheduled timer calls). |
uv run thor swap status
uv run thor swap grow 64G # dry-run: prints the plan, changes nothing
uv run thor swap history --window 1h --top 5
uv run thor swap sample
Per-process history collection via systemd timer
Per-process memory and swap history accrues only when thor swap sample runs
on a schedule. Here's a systemd service and timer pair:
# /etc/systemd/system/jetson-thor-swap-sample.service
[Unit]
Description=Sample per-process swap/memory for jetson-thor-cli
[Service]
Type=oneshot
ExecStart=/usr/bin/env thor swap sample
# /etc/systemd/system/jetson-thor-swap-sample.timer
[Unit]
Description=Periodic thor swap sample
[Timer]
OnBootSec=2min
OnUnitActiveSec=10min
Persistent=true
[Install]
WantedBy=timers.target
Enable with sudo systemctl enable --now jetson-thor-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).
uv run thor monitor config --init # scaffold ~/.config/jetson-thor/monitor.json
export JETSON_THOR_WEBHOOK_URL=https://… # or put webhook_url in the config
uv run thor monitor check # dry run: what's firing right now
uv run thor monitor config # show resolved config + thresholds
| 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 (unit: jetson-thor-monitor.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
(~/.config/jetson-thor/monitor.json; 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
jetson_thor/and thejetson-thor-cliCLI/dist name throughoutpyproject.toml, the package,tests/,sonar-project.properties, and thisREADME.md. The name is hard-coded in ~100 places, so list every occurrence first — see thegit grepdiscovery command inCLAUDE.md, the authoritative rename procedure. - 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
Apache 2.0 — see LICENSE.
Metadata
Release files for jetson-thor-cli 0.6.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jetson_thor_cli-0.6.1.tar.gz | 278.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jetson_thor_cli-0.6.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 397.0 kB
Release files / jetson_thor_cli-0.6.1.tar.gz
| Download URL | jetson_thor_cli-0.6.1.tar.gz |
|---|---|
| Size | 278.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b668778fa78c8b2c7213c94cd602372e02d0d9b688c21f3ef09c51ab29e2456b
|
|
BLAKE2b-256 checksum How to use checksums |
7a9353e175a1a5832b107290e29a071a1a528baeb54dab74a348a246a391cdd5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","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 / jetson_thor_cli-0.6.1-py3-none-any.whl
| Download URL | jetson_thor_cli-0.6.1-py3-none-any.whl |
|---|---|
| Size | 118.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fa71323fac8b43c1953c149865c9332f8e4726d182a14acda04f4b42981985e6
|
|
BLAKE2b-256 checksum How to use checksums |
96fd4b627ce392ef5a227a68ff47043627b6582d98c850b6576e87af899dd7fe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","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}
|