The first open-source macOS app to manage NVIDIA Jetson devices.
Power modes, Docker, ROS2, cameras, GPIO, AI models, ANIMA pipelines — all from your Mac.
brew tap RobotFlow-Labs/tap
brew install thorappThis installs both the THOR.app GUI and the thorctl CLI.
git clone https://github.com/RobotFlow-Labs/thorapp.git
cd thorapp
make build # Build all targets
make install-cli # Install thorctl to /usr/local/bin
make run # Package .app bundle and launch- macOS 14+ (Sonoma) on Apple Silicon
- Swift 6.2+ (
xcode-select --install) - Docker Desktop (for Jetson simulators — optional for real hardware)
THOR replaces SSH + terminal workflows with a native macOS control center for your Jetson devices.
# Add your Jetson (GUI or CLI)
thorctl connect 192.168.1.100
# Or use the built-in Docker simulators
docker compose up -d
thorctl connect localhost 8470The app provides 12 feature panels organized into 4 groups:
| DEVICE | RUNTIME | OPERATIONS | OBSERVE |
|---|---|---|---|
| Overview | Docker | Files | Logs |
| System Info | ROS2 | Deploy | History |
| Power & Thermal | ANIMA | GPU & Models | |
| Hardware |
thorctl health # Agent health check
thorctl sysinfo # System info (model, kernel, JetPack, uptime)
thorctl power # Power mode, clocks, fan speed
thorctl cameras # List cameras (CSI, USB, ZED)
thorctl gpu # GPU info, CUDA, TensorRT, models
thorctl docker # List Docker containers
thorctl ros2-nodes # List ROS2 nodes
thorctl ros2-topics # List ROS2 topics
thorctl ros2-echo /chatter # Echo a live ROS2 topic
thorctl modules # List ANIMA AI modules
thorctl network # Network interfaces
thorctl disks # Storage usage
thorctl usb # USB devices
thorctl exec "uname -a" # Run any command
thorctl watch # Live metrics dashboard
thorctl screenshot # Capture screen for debugging25 commands total. Run thorctl help for the full list.
- Power modes: Switch between MAXN, 30W, 15W via nvpmodel
- Jetson clocks: Lock/unlock frequencies for max performance
- Fan control: Adjustable PWM speed slider
- Thermal monitoring: Live temperature gauges with color-coded alerts
- Cameras: Auto-detect CSI, USB, and ZED cameras
- GPIO: Pin state visualization with direction indicators
- I2C: Bus scanning with device address discovery
- USB: Full device enumeration
- Serial: Port detection (ttyUSB, ttyACM, ttyTHS)
- List, start, stop, restart containers with confirmation dialogs
- View container logs
- Image management (list, pull)
- NVIDIA Container Runtime support
- Nodes: List active nodes
- Topics: List with message types, echo live messages
- Services: List with service types
- Launch: Start/stop launch files
- Lifecycle: Node state management (configure, activate, deactivate)
- Bags: Record, stop, list, play rosbags
- Browse module registry (PETRA, CHRONOS, PYGMALION)
- Check Jetson platform compatibility
- Compose docker-compose pipelines with TensorRT backend
- Deploy with one click, monitor per-container health
- CUDA version, TensorRT version
- GPU memory usage gauge
- TensorRT engine file listing
- Model inventory (ONNX, TRT, PT, SafeTensors)
- rsync delta sync + scp upload
- Drag-and-drop with progress tracking
- SHA-256 checksum verification
- Transfer history
- Kernel, L4T, JetPack version info
- Package management (apt update/upgrade)
- User management
- Storage monitoring with per-filesystem usage bars
- Network interface listing with IP/MAC
- WiFi scanning and connection
- Trust-On-First-Use: SSH host key fingerprint verification
- Keychain: All credentials in macOS Keychain
- Localhost agent: API bound to 127.0.0.1, accessed via SSH tunnel
- Confirmations: Reboot, delete, container stop require explicit confirmation
- Auto-reconnect: Exponential backoff (2-32s)
macOS Jetson Device
┌──────────────────┐ ┌──────────────────────┐
│ THOR.app │ SSH Tunnel │ THOR Agent │
│ (SwiftUI) │◄──────────────────►│ (Python/FastAPI) │
│ │ │ 50 endpoints │
│ thorctl (CLI) │ HTTP/JSON │ 10 router modules │
│ 25 commands │◄──────────────────►│ localhost:8470 │
└──────────────────┘ │ │
│ ├ power.py │
│ ├ system.py │
│ ├ hardware.py │
│ ├ docker.py │
│ ├ ros2.py │
│ ├ gpu.py │
│ ├ anima.py │
│ ├ network.py │
│ ├ storage.py │
│ └ logs.py │
└──────────────────────┘
thorapp/
├── Package.swift # 4 Swift targets
├── Makefile # build, test, run, install, Docker
├── Sources/
│ ├── THORApp/ # SwiftUI macOS app
│ │ ├── Views/ # 26 views (sidebar, panels, dialogs)
│ │ └── Services/ # 8 services (connector, deployer, etc.)
│ ├── THORShared/ # Shared library
│ │ ├── Database/ # GRDB SQLite (13 tables)
│ │ ├── Models/ # 50+ response types
│ │ ├── SSH/ # Session manager, host key verifier
│ │ └── Keychain/ # macOS Keychain wrapper
│ ├── THORctl/ # CLI (25 commands)
│ └── THORCore/ # Background helper
├── Agent/ # Python Jetson agent
│ ├── main.py # FastAPI core
│ ├── routers/ # 10 endpoint modules
│ ├── sim.py # Simulation state
│ └── process_manager.py # Background process tracking
├── Tests/ # 71 tests, 8 suites
├── Docker/ # Jetson simulator
└── .github/workflows/ # CI/CD
make build # Debug build
make release # Release build
make test # Run all 71 tests
make test-unit # Unit tests only (no Docker)
make run # Package + launch app
make docker-up # Start Jetson simulators
make docker-down # Stop simulators
make install-cli # Install thorctl to /usr/local/bin
make icon # Generate app icon
make stats # Show project statistics
make clean # Clean build artifactsdocker compose up -d # Start Thor + Orin sims
thorctl connect localhost 8470 # Connect to Thor sim
thorctl connect localhost 8471 # Connect to Orin sim
# Default SSH: jetson@localhost:2222 (password: jetson)
# Thor sim: port 2222 (SSH), port 8470 (agent)
# Orin sim: port 2223 (SSH), port 8471 (agent)The sims include:
- ROS2 Humble with demo talker/listener (live
/chattertopic) - Docker CLI (Docker-in-Docker via socket mount)
- Simulated JetPack 6.1, CUDA 12.6, TensorRT 10.3
On your real Jetson device:
# Copy agent files
scp -r Agent/ jetson@YOUR_JETSON:/opt/thor-agent/
# Install dependencies
ssh jetson@YOUR_JETSON "pip3 install fastapi 'uvicorn[standard]' psutil pyyaml python-multipart"
# Create systemd service
ssh jetson@YOUR_JETSON "sudo tee /etc/systemd/system/thor-agent.service << EOF
[Unit]
Description=THOR Jetson Agent
After=network.target
[Service]
Type=simple
User=jetson
ExecStart=/usr/bin/python3 /opt/thor-agent/main.py
Restart=always
Environment=THOR_AGENT_HOST=127.0.0.1
Environment=THOR_AGENT_PORT=8470
[Install]
WantedBy=multi-user.target
EOF"
# Enable and start
ssh jetson@YOUR_JETSON "sudo systemctl daemon-reload && sudo systemctl enable --now thor-agent"| Device | JetPack | Status |
|---|---|---|
| Jetson Thor | 7.0+ | Primary |
| Jetson AGX Orin | 5.1+ | Supported |
| Jetson Orin NX | 5.1+ | Supported |
| Jetson Orin Nano | 5.1+ | Supported |
- Fork the repo
make build && make test- Submit a PR
See LICENSE for MIT license details.
Built by RobotFlow Labs • An AIFLOW LABS project
