Skip to content

saage remote: list + cleanup commands, ps progress, terminate unregisters target - #38

Merged
cgpadwick merged 4 commits into
masterfrom
feat/remote-list-cleanup
Aug 1, 2026
Merged

saage remote: list + cleanup commands, ps progress, terminate unregisters target#38
cgpadwick merged 4 commits into
masterfrom
feat/remote-list-cleanup

Conversation

@cgpadwick

Copy link
Copy Markdown
Owner

Problem

Targets in credentials.toml accumulate forever: add-target appends, nothing removes them — even terminate leaves the registration behind. The result is a long list of dead names in every error message, and saage remote ps silently probing each dead box for a full ConnectTimeout, which reads as a hang.

Changes

  • saage remote list — table of registered targets (name, dest, $/hr, per-target key). Pure local, no network.
  • saage remote cleanup — interactive pruning: one remove <name> (user@host)? [y/N] prompt per target (default N, sorted order). Warns when an unfinished run in the local ledger references the target. Optional --check ssh-probes each target first and shows reachable/unreachable as information only — offline every box looks dead, so reachability never decides anything. Prints a reminder after removals that removing a target does not terminate the box.
  • creds.remove_target() — deletes the [targets.<name>] section by text splice so the rest of the file stays byte-identical (comments and [storage]/[lambda] sections survive; a TOML re-emit would strip comments). Never deletes key files (per-instance Thunder keys are unrecoverable). Preserves 0600.
  • saage remote terminate — now also unregisters the matching target, so spawned boxes stop becoming permanent clutter.
  • saage remote ps — narrates each probe (checking <name> (<dest>)… ok (N sessions) / unreachable) so a wall of stale targets reads as progress instead of a hang.

Design notes: docs/superpowers/specs/2026-08-01-remote-target-cleanup-design.md.

Testing

  • 19 new offline unit tests (tests/remote/test_target_cleanup.py, additions to test_creds.py): splice removal edge cases (middle/last section, comment preservation, 0600, key files untouched), cleanup prompt loop with scripted input, active-run warning, --check output, ps progress lines with a stubbed SshTarget, terminate unregistration.
  • tests/remote/: 103 passed, 5 skipped (ssh/live markers).
  • Full suite: 415 passed; the 5 failures (test_skills, test_agent, test_checkpoint warning-capture tests) also fail on clean master and are unrelated.
  • Manual smoke: list → scripted cleanuplist confirms removal and billing reminder.

🤖 Generated with Claude Code

cgpadwick and others added 4 commits August 1, 2026 11:16
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ters target

Targets accumulated forever: add-target appends, nothing removed them —
even terminate left the registration behind, so every spawned box became
permanent clutter and `saage remote ps` probed each dead one for a full
ConnectTimeout in silence (read as a hang).

- `saage remote list`: registered targets, pure local, no network
- `creds.remove_target()`: text-splice removal, rest of credentials.toml
  stays byte-identical (comments survive); key files never deleted
- `saage remote cleanup`: per-target y/N prompt (default N), warns when an
  unfinished run references the target, optional --check reachability probe
  (info only — offline everything looks dead, so it never decides)
- `saage remote terminate`: also unregisters the matching target
- `saage remote ps`: narrates each probe ("checking <name> (<dest>)… ok/
  unreachable") so dead targets read as progress

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e in sessions()

tmux ls runs with check=False, so ssh's own rc 255 (connection failed)
produced an empty CompletedProcess instead of an exception: every dead
target looked identical to a live box with no runs. Raise SSHError on
rc 255 so ps/cleanup print 'unreachable'; tmux rc 1 (no server) is still
a genuine zero sessions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ters

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cgpadwick
cgpadwick merged commit c505e9d into master Aug 1, 2026
6 checks passed
@cgpadwick
cgpadwick deleted the feat/remote-list-cleanup branch August 1, 2026 18:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant