NEW lib/ssh-helper.sh implements the full SSH command surface:
hosts/list show configured remote hosts
add <alias> <user@host[:port]> register a new host
remove <alias> remove + clean cred + socket
pass <alias> set/update password (hidden interactive)
setup <alias> open long-lived ControlMaster
close <alias> close ControlMaster
status [alias] show open masters + cred presence
exec <alias> <command...> run command via master
Architecture:
• $LARRY_HOME/.ssh-hosts.tsv — alias \t user@host \t port (3-col)
• $LARRY_HOME/.ssh-creds/<alias> — raw password, mode 0600
• $LARRY_HOME/.ssh-sockets/<alias>.sock — ControlMaster socket
The password is read from disk by sshpass via -f (file argument), so it
never lands in argv or environment. It is used ONCE to open the master;
all subsequent execs multiplex through the socket with no auth. Daily-
rotating passwords: just overwrite the cred file and re-run setup.
SLASH COMMANDS wired in larry.sh REPL: /ssh-hosts /ssh-add /ssh-remove
/ssh-pass /ssh-setup /ssh-close /ssh-status /ssh <alias> <cmd>.
LARRY TOOLS exposed to the LLM:
ssh_status — list aliases + open-master state
ssh_exec — run command on remote via the master socket
Both tool descriptions explicitly tell Larry the password is unreachable
and to ask Bryan to run /ssh-setup if a master is closed. Tool inputs
and outputs never contain the password. Output capped at max_lines
(default 500) with a "[ssh_exec: exit rc=N]" footer.
Bundle updated: MANIFEST + install-larry.sh both now include
lib/ssh-helper.sh. Auto-update will pull it on next launch.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Self-update overhaul (no more manual reinstalls when lib/ changes):
- New MANIFEST file at repo root lists every file that should auto-sync
(top-level scripts, agents/, lib/, VERSION, MANUAL.md).
- larry.sh self_update() reworked into two phases:
Phase A — local sync: if $LARRY_HOME/.last-sync-version != $LARRY_VERSION,
fetch MANIFEST and refresh every listed file. Stamps version after.
Phase B — remote check: fetch $LARRY_BASE_URL/VERSION; if newer, pull
larry.sh, self-replace, relaunch with LARRY_JUST_UPDATED=1 so phase B
is skipped on the relaunch (phase A then pulls everything else).
- New LARRY_BASE_URL env var (the legacy LARRY_UPDATE_URL / LARRY_AGENTS_URL
still work as overrides).
- Bumped LARRY_VERSION and VERSION to 0.5.0.
OAuth fix (lib/oauth.sh):
- Anthropic's callback returns the code as 'CODE#STATE' (URL fragment, not
query). Previous prompt told users to copy "between code= and the next &"
which produced the wrong substring; the token endpoint then returned a
misleading 'rate_limit_error' on the malformed code.
- Now splits the pasted input on '#', verifies the returned state matches
the one we generated, sends only CODE to the token endpoint.
- Updated user-facing prompt and error hints to describe the real format
and explain the misleading rate_limit_error symptom.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>