Skip to content

Latest commit

 

History

416 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Remo

Spin up a fully-configured remote development environment in minutes. One command gives you a persistent, secure coding environment with Dev Containers support — perfect for long-running AI agents that keep working after you disconnect.

Installation

# From PyPI (recommended)
uv tool install remo-cli

# Or with pip
pip install remo-cli

Ansible collections required by the provider playbooks install automatically the first time you run a provider command (e.g. remo incus create); no separate setup step is needed.

Prerequisites

  • Python 3.11+
  • SSH key pair (~/.ssh/id_rsa)
  • uv (recommended) or pip

Shell completion (optional)

Tab completion for subcommands, flags, and known instance/container names is available for bash, zsh, and fish:

remo completion install

That detects the shell you're actually running (from the process tree, falling back to $SHELL), writes the activation script, and — for bash and zsh — offers to add the single line that loads it. Pass --yes to skip the prompt, or name a shell explicitly (remo completion install fish). fish needs no rc change at all, since its completions directory is a drop-in.

The two can disagree: macOS ships zsh as the login shell, so $SHELL says zsh even when you launch fish from your terminal emulator. remo prefers the shell you're typing into and warns when $SHELL differs, so naming one explicitly is never necessary but always wins.

install.sh offers to do this for you at the end of an install. It can't happen automatically on uv tool install, though: Python wheels have no post-install hook, by design.

After re-loading your shell, remo proxmox info --name <TAB> will suggest registered container names from your registry.json registry.

Re-run remo completion install after upgrading remo. The activation script is a static snapshot — upgrading remo does not rewrite a file you already generated, and a stale script can break completion in ways remo cannot report (your shell parses the file itself, so remo is not running when it fails). Every generated script carries a generated by remo <version> header, remo nudges you when it notices a stale one, and re-running is a safe no-op when nothing changed.

To inspect the script instead of installing it, use remo completion show <shell>.


Quick Start

remo hetzner create             # Provision a VM (or: remo aws create / remo incus create / remo proxmox create)
remo shell                      # Connect to your environment

You land in an interactive project menu. Pick a project, and you're in a persistent Zellij session with your DevContainer already running. Disconnect anytime — your session survives.

  Remote Coding Server
  --------------------

> my-project - active
  another-project
  [Clone new repo]
  [Exit to shell]

Choose Your Platform

Hetzner Cloud AWS Incus Proxmox
Type Cloud VM Cloud VM Local container Local container
Location EU/US datacenters Global regions Your hardware Your hardware
Cost ~€4/month $30/month ($10 spot) Your electricity Your electricity
Storage Block volume EBS / root volume Host mounts LVM / ZFS / dir
Access Server IP SSM (no inbound ports) or SSH LAN hostname LAN IP
Best for EU, budget hosting US, enterprise, spot instances Local dev, homelab Proxmox homelab

All platforms give you the same dev workflow and tooling described below.


The Dev Workflow

Persistent Sessions

Zellij keeps your terminal sessions alive across SSH disconnects:

  • Detach: Ctrl+d returns to the project menu
  • Reconnect: SSH back in, select the same project to resume exactly where you left off

Project Menu

The fzf-powered menu shows your projects from ~/projects:

  • Arrow keys or 1-9: Select a project
  • Enter: Launch/attach to the project's Zellij session
  • c: Clone a new repository
  • x: Exit to shell

Jump Straight to a Project

Skip the menu and land directly in a project (devcontainer auto-launches):

remo shell -p my-app

Run a one-shot command inside the project's devcontainer instead of opening a shell — quote the command as a single string:

remo shell -p my-app --exec 'pytest -x'
remo shell -p my-app --exec 'claude --remote-control'

Fire-and-forget — kick off a command on the remote and exit SSH immediately:

remo shell -p my-app --detach --exec 'claude remote-control --name remo-rc'
remo shell -p my-app --detach --exec './long-build.sh'

Detached output is captured to ~/.local/state/remo/<project>.log on the remote, so you can tail it later (remo shell -p my-app --exec 'tail -f ~/.local/state/remo/my-app.log'). The command's environment gets REMO_INSTANCE and REMO_PROJECT exported automatically — handy for deterministic naming, e.g.:

remo shell -p my-app --detach --exec \
  'claude remote-control --name "remo-$REMO_INSTANCE-$REMO_PROJECT"'

Then on your phone, open claude.ai/code and pick the session by name.

Port Forwarding

Forward remote ports to your local machine during SSH sessions:

remo shell -L 8080                  # Forward remote :8080 to local :8080
remo shell -L 9000:8080             # Forward remote :8080 to local :9000
remo shell -L 8080 -L 3000          # Forward multiple ports
remo shell -L 8080 --no-open        # Skip auto-opening browser

Web ports automatically open in your browser when the tunnel is established.

File Transfer

Copy files between your local machine and any remote environment:

remo cp ./file.txt :/tmp/           # Upload
remo cp :/var/log/app.log ./        # Download
remo cp -r ./my-dir :/home/remo/    # Recursive upload
remo cp --progress big-file.tar :/tmp/  # Show transfer progress

Uses colon notation — a bare :path targets your default environment, or name:path for a specific one.

Version Checking

Remo checks that your local CLI and remote environment are running compatible versions before connecting. If the remote is behind, you'll be prompted to update it. Use --no-update-check to skip.


What's Installed

Every remo environment includes:

Tool Description
Docker + Compose Official Docker CE with compose plugin
Dev Containers CLI devcontainer up, devcontainer exec, etc.
Node.js 24 LTS From NodeSource repository
GitHub CLI gh for GitHub workflow integration
Zellij Terminal multiplexer for persistent sessions
fzf Fuzzy finder powering the project menu (server-side)

Snapshots

Capture a point-in-time copy of an instance before a risky change, then roll back if it breaks. Available on every provider, with the same command surface:

remo <provider> snapshot create <instance> [--name NAME] [--description TEXT]
remo <provider> snapshot list    [INSTANCE]
remo <provider> snapshot restore <instance> <snapshot> [-y]
remo <provider> snapshot delete  <instance> <snapshot> [-y]

--name defaults to remo-YYYYMMDD-HHMMSS. -y / --yes bypasses the confirm prompt on destructive operations.

Provider Create Restore Notes
Incus seconds in-place rollback (container stopped briefly) Free; uses native incus snapshot.
Proxmox seconds in-place rollback (container stopped briefly) Free; requires snapshot-capable rootfs storage (ZFS, LVM-thin, Btrfs, Ceph, NFS, CIFS). dir storage is rejected pre-flight.
AWS async — several minutes in-place EBS volume swap; stops the instance, swaps the root volume, restarts. Typically 2-5 min downtime. Costs $ per GB-month in EBS. Pre-restore root volume is preserved as a tagged orphan — delete it manually once you've verified the restore.
Hetzner async — several minutes server rebuild from the snapshot image, in-place. Typically 1-2 min downtime. Costs € per GB-month.

remo does not estimate storage cost — check your provider's billing console.

The destroy command on each provider checks for existing snapshots first and offers to clean them up. Decline and the snapshots remain (you'll be warned they continue to incur storage costs on AWS/Hetzner).


Register an SSH-reachable host

Already have SSH access to a box — a VM, a bare-metal server, someone else's container — but no hypervisor host access, cloud credentials, or API token? remo add registers it directly into your registry. Provider sync is bulk discovery that needs provider/host access; add is a single manual registration that needs only SSH reachability.

remo add NAME TARGET [--user USER] [--port PORT] [--identity PATH] [--verify] [--yes]

TARGET is [user@]host[:port]. --user, --port, and --identity override (or fill in) the corresponding parts of TARGET. When no user is given, the default SSH user is remo (reported back to you); the default port is 22.

  • --identity PATH records a private key that is persisted and passed to ssh -i on connect — no ~/.ssh/config editing needed for a host that requires a non-default key.
  • --verify does an opt-in, fail-closed SSH reachability check before registering: on failure it surfaces the SSH error, writes nothing, and exits non-zero. Without --verify there is no network round-trip at all.
  • Re-running add with an existing added-host name and a changed target updates it in place (confirm unless --yes) — it never creates a duplicate. It refuses to overwrite a provider-managed entry (incus/proxmox/aws/hetzner) of the same name.
  • IPv6: un-bracketed IPv6 literals are rejected — use a hostname or an ~/.ssh/config alias instead (bracketed [::1]:22 is not supported in this release).

Once added, remo shell NAME and remo cp work over the same direct SSH path as any other host.

remo add mybox 10.0.0.5 --port 2222 --identity ~/.ssh/mybox_ed25519 --verify
remo configure mybox                # install the dev tools (see below)
remo shell mybox                    # open a shell over direct SSH
remo cp ./deploy.sh mybox:/tmp/     # copy a file up
remo remove mybox                   # deregister when you're done

Install the dev tools: remo configure

add only registers a host — it installs nothing. Until you configure it, an added host has no remo-host, no zellij and no project launcher, so remo web lists it with an "update req." badge and no sessions you can open.

remo configure NAME [--only TOOL] [--skip TOOL] [--yes] [-v]

This runs the same Ansible play the providers use, so the host ends up with Docker, Node.js, zellij, fzf, the GitHub CLI, the devcontainers CLI and remo-host. It is idempotent — re-run it any time to refresh the tools, which is also how you update a host after upgrading remo itself.

Two things worth knowing before the first run:

  • It configures the account you registered and grants that account passwordless sudo. It also apt-upgrades the system. You are asked to confirm (defaulting to no); --yes skips the prompt.
  • The host must be Debian/Ubuntu with python3 and sudo available. Registering as root is refused — the workspace account is pinned to UID 1000, which would break the host.

Unlike the provider create path, remo never reboots a host it did not provision; if package updates need one, it tells you and leaves the decision to you. For a provider-managed host use remo <provider> upgrade NAME instead — remo configure refuses those and names the right command.

remo configure mybox                # first-time setup, or refresh the tools
remo configure mybox --skip docker  # everything except Docker
remo web sync                       # authorize the web service on it / merge changes

Re-running it is how a configured host stays current — it refreshes project-menu, remo-host, project-launch and the rest of the toolchain, and applies system package updates. remo shell checks the version on connect and offers to run it for you when the host is behind, exactly as it does for provider hosts. A host you added but never configured is left alone: no marker, no prompt, straight into a login shell.

Example: an OrbStack VM

docs/examples/orbstack-cloud-init.yaml prepares an OrbStack VM on a Mac so remo add and remo configure work first time:

orb create ubuntu remo-mbp -u orbadmin -c docs/examples/orbstack-cloud-init.yaml
remo add mbp remo@<name-that-resolves> --verify

It installs only what Ansible needs to connect and hand over — remo configure does the rest. It creates a remo account at UID 1000 and installs your key there, which is the account to register.

-u orbadmin is not optional. OrbStack creates a Linux account named after your macOS user, pins it to your macOS UID (501, not 1000), and does so after cloud-init finishes — it will even renumber a cloud-init-created account that shares its name. Giving OrbStack a throwaway name to own leaves UID 1000 free. That matters because user_setup pins remo_user to UID 1000: register an account at any other UID and remo configure runs usermod -u 1000 against the account Ansible is logged in as, which shadow-utils refuses to do for a user with running processes. Add --isolated too if you want a plain VM with no Mac file sharing; it is independent of the UID fix.

Which name to register. An OrbStack VM is not on your LAN — it gets a static address on OrbStack's internal bridge, and OrbStack has no bridged/DHCP-from-your -router mode — so its own IP means nothing to any other machine. Three paths, in increasing reach:

From Register Notes
The Mac itself remo-mbp.orb.local OrbStack's DNS. Nothing to set up.
Your LAN, or a VPN <your-mac> OrbStack forwards the VM's :22 to the Mac and exposes it on every interface, so the Mac's name reaches the VM's sshd with nothing installed in the VM.
Anywhere remo-mbp.<tailnet>.ts.net The Tailscale example below — needed only if you want the VM itself on the tailnet.

Prefer a bare name over an FQDN or an IP: it resolves through whichever search domain is up — your VPN's or your router's — so one entry keeps working as you move. That is why a registered host reads "host": "dev1".

Two gotchas on the middle row. It routes through the Mac's :22, so only one VM can own it (and it collides with macOS Remote Login) — for a second VM, change Port in the sshd drop-in and register remo@<mac>:<port>. And a Mac does not register itself in your router's DNS the way a Linux DHCP client does: macOS sends the DHCP hostname only when HostName is set, which it is not by default (LocalHostName, the mDNS .local name, is never sent, and Linux hosts generally cannot resolve .local at all). Fix it once with sudo scutil --set HostName <name> && sudo ipconfig set en0 DHCP — after which the address may change freely, since DNS follows it. If a VPN or a Tailscale exit node with LAN access claims OrbStack's subnet (orb config get network.subnet4), even the Mac-local path black-holes; check with route -n get <vm-ip>.

Devcontainer builds. An OrbStack machine is a container on a shared kernel, so Docker inside it is nested and the kernel refuses the overlayfs mounts BuildKit's default snapshotter needs — without help, no devcontainer builds at all. remo configure detects this and provisions a native-snapshotter buildx builder plus a devcontainer shim that picks the right build environment per project; builds work, but are noticeably slower. Two limits it cannot fix — apt inside a running container, and therefore playwright install --with-deps — are covered in docs/nested-overlayfs.md.

To reach the VM from anywhere — including a remo web service that cannot reach your Mac — use docs/examples/orbstack-cloud-init-tailscale.yaml instead. Same file plus Tailscale; it prints the address to register on first boot:

orb create ubuntu remo-mbp -u orbadmin -c docs/examples/orbstack-cloud-init-tailscale.yaml
remo add mbp remo@remo-mbp.<your-tailnet>.ts.net --verify

Use an ephemeral auth key: cloud-init keeps your user-data on the VM's disk, so the key outlives the boot that used it. Leaving the placeholder is fine — tailscaled still installs, and sudo tailscale up joins interactively with no credential on disk.

remo remove NAME [--yes] deregisters an added host by deleting only the local registry entry — it makes no connection to and no change on the remote environment (unlike a provider destroy, which tears down infrastructure). It refuses to act on a provider-managed host and points you at that provider's destroy instead.

CLI Reference

# Connect to environment
remo shell                          # Auto-connect (or picker if multiple)
remo shell my-env                   # Connect to a specific environment
remo shell -p my-app                # Skip the menu, jump to ~/projects/my-app
remo shell -p my-app --exec 'pytest -x'              # Run command in devcontainer
remo shell -p my-app --detach --exec 'claude remote-control --name rc'  # Fire and exit
remo shell -L 8080                  # Shell + forward remote :8080 to local :8080
remo shell -L 9000:8080             # Shell + forward remote :8080 to local :9000
remo shell -L 8080 -L 3000          # Shell + forward multiple ports
remo shell -L 8080 --no-open        # Skip auto-opening browser
remo shell --no-update-check        # Skip version check

# File transfer
remo cp ./file.txt :/tmp/           # Upload file
remo cp :/var/log/app.log ./        # Download file
remo cp -r ./dir :/home/remo/       # Recursive copy
remo cp --progress big.tar :/tmp/   # Show progress

# Register an SSH-reachable host (provider-neutral; needs only SSH access)
remo add NAME [user@]host[:port]    # Register a single SSH host
remo add NAME host --port 2222 --identity ~/.ssh/key   # Custom port + key
remo add NAME host --verify         # Fail-closed SSH reachability check first
remo add NAME host --user alice     # Override default SSH user (default: remo)
remo configure NAME                 # Install/refresh the dev tools on an added host
remo configure NAME --skip docker   # Skip a tool (repeatable; --only is the inverse)
remo remove NAME [--yes]            # Deregister an added host (local-only)

# Hetzner Cloud
remo hetzner create                 # Provision VM
remo hetzner list                   # List registered VMs
remo hetzner info [--name N]        # Show type, cores, memory, volume size
remo hetzner sync                   # Reconcile registry with existing VMs
remo hetzner sync --all             # Also adopt unlabelled VMs
remo hetzner sync --yes             # Skip the removal confirmation
remo hetzner sync --dry-run         # Preview the plan, change nothing
remo hetzner upgrade NAME           # Update dev tools
remo hetzner resize NAME --volume-size 100   # Grow persistent volume + FS
remo hetzner destroy [--yes]        # Tear down (keeps volume)

# AWS (SSM access — no inbound ports)
remo aws create                     # Provision EC2 via SSM
remo aws create --spot              # Use spot instance (~70% savings)
remo aws list                       # List registered instances
remo aws sync                       # Reconcile registry with existing instances
remo aws sync --all                 # Also adopt untagged remo-* named instances
remo aws sync --yes                 # Skip the removal confirmation
remo aws sync --dry-run             # Preview the plan, change nothing
remo aws upgrade NAME               # Update dev tools
remo aws resize NAME --volume-size 100   # Grow EBS volume + FS in place
remo aws stop [--yes]               # Stop instance (pause billing)
remo aws start                      # Start a stopped instance
remo aws reboot                     # Reboot instance
remo aws destroy [--yes]            # Tear down (keeps storage)
remo aws info [--name N]            # Show type, cores, memory, EBS size

# Incus Containers
remo incus create --name <n> [--host H]  # Create container
remo incus list                     # List registered containers
remo incus info --name <n>          # Show cores, memory, root size
remo incus sync [--host H]          # Reconcile registry with remo-managed containers
remo incus sync [--host H] --all    # Also adopt non-remo containers on the host
remo incus sync [--host H] --yes    # Skip the removal confirmation
remo incus sync [--host H] --dry-run   # Preview the plan, change nothing
remo incus upgrade <n> [--host H] [--host-user U]   # Update dev tools
remo incus resize <n> --volume-size 40 --cores 4 --memory 4096
remo incus tag <n>                  # Mark as remo-managed
remo incus destroy --name <n> [--yes]    # Destroy container
remo incus host bootstrap [HOST]    # Initialize Incus on host (defaults to localhost)

# Proxmox VE LXC Containers
remo proxmox create --name <n> --host <node>  # Create LXC container
remo proxmox list                   # List registered containers
remo proxmox info --name <n>        # Show cores, memory, rootfs size
remo proxmox sync --host <node>     # Reconcile registry with remo-managed containers
remo proxmox sync --host <node> --all   # Also adopt non-remo containers on the node
remo proxmox sync --host <node> --yes   # Skip the removal confirmation
remo proxmox sync --host <node> --dry-run   # Preview the plan, change nothing
remo proxmox upgrade <n> [--host H] [--host-user U]   # Update dev tools
remo proxmox resize <n> --volume-size 40 --cores 4 --memory 4096
remo proxmox tag <n>                # Mark as remo-managed
remo proxmox destroy --name <n> [--yes] [--purge]   # Destroy container
remo proxmox host bootstrap <node>  # Verify node + download LXC template

# Snapshots (all four providers)
remo <provider> snapshot create <instance>                       # Auto-named
remo <provider> snapshot create <instance> --name pre-x --description "before upgrade"
remo <provider> snapshot list                                    # All instances
remo <provider> snapshot list <instance>                         # One instance
remo <provider> snapshot restore <instance> <snap-name> [-y]     # In-place rollback
remo <provider> snapshot delete <instance> <snap-name> [-y]      # Remove
# `<provider> destroy` will list existing snapshots and offer to clean them up first.

# Updates
uv tool upgrade remo-cli            # Update CLI to latest version
remo <platform> upgrade NAME        # Update dev tools on remote

# Help
remo --help
remo <command> --help

# Shell completion
remo completion install             # Install tab completion for your shell
remo completion show bash           # Print the activation script (also: zsh, fish)

See platform-specific docs for full options:

Environment Variables

Variable Description
REMO_HOME Config directory for remo state (default: ~/.config/remo)
REMO_DEVCONTAINER_RUNTIME Default devcontainer runtime for new deployments: devcontainer (default) or deacon (experimental). Overridden per-deployment by --devcontainer-runtime. See Proxmox docs.

Web Session Interface

Don't have the remo CLI or an SSH setup on the device in front of you? remo web runs a small home-lab Docker service that discovers every project across all of your registered instances (Proxmox, AWS, Hetzner, Incus) and streams a real interactive terminal to any browser — no local CLI, no SSH keys on the client. It connects to your instances server-to-instance over SSH, the same way the CLI does, and attaches to the exact same persistent Zellij/devcontainer session remo shell would.

⚠️ Security boundary: remo web is a single-trusted-user MVP with no login. Anyone who can reach the service can open a shell on every instance in your registry. There is no authentication, no per-user isolation, and no public-internet exposure story. Bind it only to a trusted LAN interface, a Tailscale/tailnet address, or a loopback reverse proxy — never expose it to the public internet.

Quick install

uv sync --extra web             # installs the FastAPI/Uvicorn web extra (not part of the normal CLI)
uv run remo web check           # validates registry, SSH identity, runtime dir, executables, reachability
uv run remo web serve --host 127.0.0.1 --port 8080   # local dev

For a home-lab install, use Docker Compose — see docker/compose.example.yml for a ready-to-adapt file covering both deployment modes (tmpfs runtime dir, healthcheck, non-root/read-only hardening in either case):

  • Bind-mount mode: mount your existing registry and SSH key read-only — the container runs with your identity, on the same box as your config.
  • Adopted mode: mount nothing. The container generates its own SSH identity in a writable state volume, and a single remo web push from your workstation pushes your registry and authorizes that identity on every instance — your personal private key never leaves the workstation. remo web sync keeps both sides converged afterwards: a bi-directional three-way merge that pushes local changes up, pulls console-made changes down, propagates deletions with consent in both directions, and surfaces divergent edits as per-entry conflicts (remo web push remains as the deprecated one-way force-overwrite).

Clicking a host's name in the console opens its host detail page: live stats (load, CPU, memory, disks, temperatures) plus — opt-in via REMO_WEB_HOST_ADMIN=enabled, dormant otherwise — host maintenance from the browser: clone a GitHub repo as a new project, delete a project, rebuild a project's devcontainer, and open an SSH shell on the host itself. See Host detail page and maintenance.

With REMO_WEB_REGISTRY_ADMIN=enabled (dormant otherwise) the console can also manage hosts end-to-end — register any SSH-reachable machine with a guided add wizard (paste one authorize command on the host, confirm its key fingerprints in the browser, verify), run remo configure as a background job with a live log, and remove hosts from the registry — which makes remo usable with no workstation CLI at all. Changes made in the console flow back to workstations via remo web sync. See Managing hosts from the console.

Full architecture, security model, Compose walkthrough, adoption workflow, credentials/SSM setup, discovery states, terminal limits, troubleshooting, and upgrade notes: docs/web-session-interface.md.


Troubleshooting

Installed remo on a new machine with existing instances?

remo aws sync                          # Reconcile registry with AWS instances tagged 'remo'
remo hetzner sync                      # Reconcile registry with Hetzner VMs labelled 'remo'
remo incus sync                        # Reconcile registry with remo-managed Incus containers
remo proxmox sync --host <node>        # Reconcile registry with remo-managed Proxmox LXC containers

sync reconciles the registry against what a provider actually has within one bounded scope (an Incus/Proxmox host, an AWS region, or — for Hetzner — the whole project): additions and updates apply immediately, but removing a registry entry that's genuinely gone always requires confirmation first, either interactively or with --yes. --dry-run prints the plan — what would be added, updated, removed, and why — without changing anything or prompting.

A default sync only adds containers/instances that carry the remo managed marker (an Incus user.remo=true config key, a Proxmox remo guest tag, an AWS tag:remo=true, or a Hetzner remo label) — but an existing registry entry is never removed just because it lacks that marker; presence at the provider is what protects it, independently of the marker. To adopt unmarked containers/instances into the registry, use sync --all (per-run, prints what it widened to) or, on Incus/Proxmox/Hetzner, remo <provider> tag <name> (marks one permanently, and for Hetzner also backfills the label on the server itself). AWS has no tag command, so sync --all is the only way to bring an unmarked instance under management there. Containers/instances that predate this marker convention are unmarked; a default sync retains them, names them, and prints both remedies rather than dropping or silently re-marking them.

SSH connection fails?

ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa

Ansible collection not found? Ansible collections reinstall automatically whenever ansible/requirements.yml changes. To force a reinstall manually, delete the collections.lock marker file in REMO_HOME (defaults to ~/.config/remo) and re-run any provider command.

Platform-specific issues? See troubleshooting sections in:


Uninstalling

# Remove the CLI
uv tool uninstall remo-cli      # or: pip uninstall remo-cli

# Remove remo config and state
rm -rf ~/.config/remo
Path Contents
~/.config/remo/ Runtime state: registry.json (environment registry, format v2); known_hosts.v1.bak (pre-upgrade backup, if you upgraded from an older remo)

Note: Uninstalling remo does not destroy any cloud resources (EC2 instances, Hetzner VMs, Incus or Proxmox containers). Run remo <platform> destroy first if you want to tear those down.


License

MIT License - see LICENSE file for details.

About

No description, website, or topics provided.

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages