Why vmup batches expire after 5 minutes
TTL is in minutes. The host cron deletes expired batches. vmup prune --all deletes every remote batch now. The laptop sleep job is a backup if the VM was unreachable.
A batch is throwaway context for an agent turn. vmup defaults to 5 minutes so ~/vmup does not accumulate screenshots from last week. You can raise TTL; you cannot turn expiry off with a flag (use a large --ttl or stop the sweeper if you must keep files). To delete every remote batch now, run vmup prune --all.
Recipes: Clean up batches.
How batches disappear
Remote sweeper. ~/vmup/.cleanup.sh is a bash script installed over SSH. Crontab runs it every minute:
find "$DIR" -maxdepth 1 -type d -name 'agents-*' -mmin +N -exec rm -rf {} +
find "$DIR" -maxdepth 1 -type d -name 'agents-*.partial' -mmin +N -exec rm -rf {} +N is the TTL baked in at install time. Changing ttl_minutes in config does not edit a script that is already on the VM. vmup check --sweeper rewrites it.
The script only touches agents-* directories one level under the remote root. It will not rm ~/vmup itself or your home directory.
Client sleep. After a successful upload, vmup spawns bash -c 'sleep T && ssh … rm -rf <batch>' detached. T is max(60, ttlMinutes * 60) seconds. If the laptop sleeps, the process dies, and this path does nothing. That is why the sweeper warning exists: the host cron still runs when your laptop lid is shut.
Prune. vmup prune is a third path: you decide, now, from this machine. Default prune still honors TTL and also drops leftover *.partial dirs. vmup prune --all deletes every agents-* batch immediately, including ones still inside TTL. vmup prune --id <batchId> deletes one. Not --all and --id together.
TTL resolution
Minutes, not hours, as of 0.3.0. Old configs with ttl_hours still work: hours × 60, and only if ttl_minutes is absent. Same for VMUP_TTL_HOURS.
Order: --ttl → VMUP_TTL_MINUTES → VMUP_TTL_HOURS → profile → top-level config → 5.
clampTtlMinutes: non-finite or <= 0 → 5; otherwise round and at least 1.
--ttl on an upload sets the client sleep and (via scheduleClientDelete) that batch’s delay. It does not rewrite .cleanup.sh. A one-off --ttl 60 can outlive the sweeper’s baked N if N is 5: the cron may delete the batch first. After a lasting TTL change, reinstall the sweeper.
Partial dirs
Failed uploads try to rm agents-….partial. The sweeper and prune also delete leftover *.partial directories (age prune deletes them immediately; --all deletes live batches and leftover partials together; the sweeper uses the same age as live batches).
Local cache
~/.cache/vmup/ is not TTL’d by the remote script. Successful uploads delete the session dir. Failures and --keep-local leave it. vmup prune --local removes batch dirs there older than 24 hours. update-check.json in the same cache root is not a batch dir and is left alone.
How a batch is built
Collect files, stage them under a batch id, stream them over ssh into a partial remote dir, rename into place, and copy the prompt to the clipboard.
Direct SSH vs ssh_host
Choose direct SSH (host, user, key, port) or an OpenSSH alias (ssh_host) from ~/.ssh/config. vmup still calls ssh.