Skip to content

itscooleric/clidesdale

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

29 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

clidesdale

   β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•—     β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
  β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β•β• β•šβ•β• β–ˆβ–ˆβ•”β•β•β•β•β•
  β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—       β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—     ───
  β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•       β•šβ•β•β•β•β–ˆβ–ˆβ•‘       \
  β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—    β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘         \    β•±β–”β–”β–”β•²
   β•šβ•β•β•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•šβ•β•β•β•β•β• β•šβ•β•β•β•β•β•β•    β•šβ•β•β•β•β•β•β•         β•²__β•±  ● ● β•²
  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—     β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—(β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—)                   β”‚  β–½  β”‚
  β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•”β•β•β•β•β•(β–ˆβ–ˆβ•”β•β•β•β•β•)                    ╲───╱
  β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  (β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—)                    β•±   β•²
  β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•”β•β•β•  (β•šβ•β•β•β•β–ˆβ–ˆβ•‘)                   β•± ┃ ┃ β•²
  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—(β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘)                  β•±  ┃ ┃  β•²
  β•šβ•β•β•β•β•β• β•šβ•β•  β•šβ•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•(β•šβ•β•β•β•β•β•β•)

  give your agent a VPS                              v0.1
  ────────────────────────────────────────────────────────

  sdale connect edge
  sdale exec edge "docker build -t app ."
  sdale watch edge
  sdale push edge .env /srv/.env

  ────────────────────────────────────────────────────────
  python 3.10+  ·  zero dependencies  ·  dale! 🐴

Give your AI agent SSH access to a disposable VPS. It builds, tests, deploys, and breaks things β€” you watch via activity logs. Dale!

Why

AI agents in sandboxed containers (like clide) can't run Docker, bind ports, or test infrastructure. But you don't want to give them the keys to production either.

clidesdale is the middle ground: a throwaway VPS the agent can SSH into and go a little crazy on. You co-pilot via activity logs and shared tmux sessions β€” observable, interruptible, disposable.

The pattern

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     SSH (ed25519)     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  agent        β”‚ ────────────────────> β”‚  dale (VPS)      β”‚
β”‚  (sandboxed)  β”‚                       β”‚                  β”‚
β”‚               β”‚  sdale exec ────────> β”‚  docker build    β”‚
β”‚  write code   β”‚  sdale push ────────> β”‚  docker run      β”‚
β”‚  unit tests   β”‚  sdale sync ────────> β”‚  deploy          β”‚
β”‚  git          β”‚  <──── results ────── β”‚  break stuff     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚                                       β”‚
        β”‚          activity logs (.sdale-*.log)  β”‚
        └──────── sdale watch / clidestable β”€β”€β”€β”€β”€β”˜
                  human watches in real time

Core rules

  1. Everything is logged β€” sdale exec and sdale run log all commands + output to activity files. The human can sdale watch or use clidestable to see everything in real time.
  2. Rsync, don't clone β€” code lives in the agent's sandbox. Sync it to the VPS for builds. Single source of truth.
  3. The VPS is disposable β€” if the agent bricks it, reprovision. Keep provisioning scripted and repeatable.
  4. SSH key per agent β€” each agent gets its own key pair. Revoke by removing the pubkey.

Install

pip install .
# or run directly:
python -m sdale

Requires Python 3.10+. Zero external dependencies β€” stdlib only.

Quick start

1. Provision a VPS

Any cheap VPS works. Install Docker and tmux:

apt-get update && apt-get install -y docker.io tmux

Or use a full bootstrap like forge for Docker CE, Tailscale, UFW, and SSH hardening.

2. Generate + install SSH key

On the agent's machine:

ssh-keygen -t ed25519 -f ~/.ssh/sdale -N "" -C "agent-sdale"

Add the pubkey to the VPS:

ssh-copy-id -i ~/.ssh/sdale.pub deploy@vps-ip

3. Configure sdale.json

{
  "dales": {
    "edge": {
      "host": "203.0.113.10",
      "user": "deploy",
      "key": "~/.ssh/sdale",
      "session": "build"
    }
  },
  "defaults": {
    "key": "~/.ssh/sdale",
    "exclude": ["node_modules", ".git"]
  }
}

See sdale.example.json for the full format.

4. Dale!

# Connect to a dale (creates tmux session + activity log)
sdale connect edge

# Run commands directly (captured in activity log)
sdale exec edge "docker build -t app ."
sdale exec edge "docker run --rm app npm test"

# Or via tmux (observable + wait for completion)
sdale run -w edge "make deploy"

# Push a config file
sdale push edge .env /srv/app/.env

# Sync code to the dale
sdale sync edge ./my-project /srv/app

# Watch agent activity in real time
sdale watch edge

# Check status / view audit log
sdale status edge
sdale log edge

CLI reference

Command Description
sdale connect <dale> Create/reuse tmux session, set up activity log
sdale watch <dale> Watch agent activity in real time (tails activity log)
sdale exec <dale> "<cmd>" Run command via direct SSH (no tmux, good for scripting)
sdale exec -e <dale> "<cmd>" Same, but merge stderr into stdout (avoids 2>&1)
sdale multi <dale> "c1" "c2" Run multiple commands in one SSH round-trip
sdale cat <dale> <path> [path...] Read one or more remote files
sdale health <dale> Quick connectivity + system status check
sdale health -d <dale> Include Docker container listing
sdale push <dale> <src> <dst> Copy a single file to the dale via scp
sdale pull <dale> <remote> [local] Copy a file from the dale to local
sdale run <dale> "<cmd>" Send command to the dale's tmux session (observable)
sdale run -w <dale> "<cmd>" Send via tmux + wait for completion, print output
sdale output <dale> [-n N] Capture recent tmux pane output (default: 20 lines)
sdale sync <dale> <src> [dst] Rsync local directory to the dale
sdale status [dale] Show dale status (or list all)
sdale list List configured dales
sdale log <dale> [--full|--since DUR] Show event log for a dale
sdale disconnect <dale> Kill the tmux session

Observability

Activity logs

sdale exec and sdale run write all commands and output to activity log files on the dale:

/opt/stacks/.sdale-<dale-name>.log

Watch them in real time with sdale watch <dale> or from clidestable's web dashboard.

Audit log (JSONL)

Every command is also logged as structured JSONL to ~/.sdale/logs/<dale>/events.jsonl, compatible with the clide session event schema v1.

{"event":"dale_exec","ts":"2026-03-15T04:30:12Z","session_id":"sdale-edge-1710473400","schema_version":1,"dale":"edge","command":"docker build -t app .","exit_code":"0"}
{"event":"dale_push","ts":"2026-03-15T04:31:02Z","session_id":"sdale-edge-1710473400","schema_version":1,"dale":"edge","src":".env","dst":"/srv/app/.env"}

Secret values (API keys, tokens) are automatically scrubbed before writing.

Ecosystem

Project What
clide CLI Development Environment β€” sandboxed terminal for AI agents
clidesdale This CLI β€” SSH access to remote VPSes for agents
clidestable VPS-side server β€” dashboard, stall management, split terminal view

Roadmap

See issues for the full backlog.

Name

clidesdale = clide's dale. A horse (Clydesdale β†’ clidesdale). Also Spanish for "dale!" β€” go for it! Because that's what you're telling your agent: here's a VPS, dale. 🐴

About

🐴 give your AI agent a VPS β€” CLI for SSH access to throwaway dales with observable tmux sessions

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors