sshaman
v0.1.2
Published
A lightweight CLI/TUI for managing SSH config aliases without hand-editing ~/.ssh/config.
Maintainers
Readme
sshaman
A lightweight CLI/TUI for managing SSH config aliases — connect, add, list, edit, and remove hosts without hand-editing ~/.ssh/config or memorizing IPs.
npx sshamansshaman reads and writes your real ~/.ssh/config, so every other tool that
uses it (git, rsync, scp, VS Code Remote-SSH, plain ssh) stays in sync
automatically. Existing comments and formatting are preserved, and every
mutation is backed up first.
Usage
npx sshaman
With no arguments, sshaman lists your host aliases in an interactive picker.
Select one and it hands off to ssh <alias>, exiting with ssh's own exit code.
Only literal host aliases are shown — pattern entries like Host * or
Host *.internal are filtered out.
npx sshaman add <alias | target> [flags]
Add (or overwrite) a host block. Any field you don't supply is asked for interactively.
The positional argument can be either a bare alias or an SSH connection string, chosen automatically by its shape:
# Bare alias — the argument is the alias itself.
npx sshaman add web1 --host 10.0.0.9 --user deploy --port 2222 --identity ~/.ssh/id_ed25519
npx sshaman add staging # prompts for the remaining fields
# Connection string — parsed into fields; you're prompted for the alias.
npx sshaman add [email protected] # user=root, host=10.0.0.1
npx sshaman add [email protected]:2222 # + port=2222
npx sshaman add ssh://[email protected]:22 # ssh:// URLs work too
npx sshaman add example.com # bare IP or domain → hostAn argument is treated as a connection string when it starts with ssh://,
contains @, has a numeric :port, or looks like an IP or dotted domain.
Otherwise (a plain word like web1) it's a bare alias. When a connection
string is used, you're prompted for an alias — it can't be left blank.
| Flag | Maps to |
|---|---|
| --host <hostname> | HostName |
| --user <user> | User |
| --port <port> | Port |
| --identity <path> | IdentityFile |
Each field is resolved as explicit flag → value parsed from the connection string → interactive prompt. If the alias already exists you'll be asked to confirm before it's overwritten. Only the fields you provide are written.
npx sshaman edit [alias] [flags]
Change the fields of an existing host block, in place. Without an alias you pick one from a list; with no flags every field is prompted, pre-filled with its current value.
npx sshaman edit # pick a host, then edit each field
npx sshaman edit web1 # edit web1's fields interactively
npx sshaman edit web1 --host 10.0.0.42 # change just HostName, no prompts
npx sshaman edit web1 --port '' # remove the Port directiveSame flags as add. Passing any flag skips the prompts and applies only the
fields you named; an empty value removes that directive (--port ''
interactively: clear the pre-filled value and submit). Fields you don't mention
are left alone, and a summary of what changed is printed.
The block keeps its position in the file along with its comments and any
directives sshaman doesn't manage (ProxyJump, ForwardAgent, …). Wildcard
blocks like Host * can't be edited. If a block declares several aliases
(Host db prod) you'll be warned that the edit applies to all of them — it's one
block. To rename an alias, use rm then add.
npx sshaman ls
Print host aliases (same literal-only filtering as the picker), one per line. No selection, no connect — handy for scripts and shell completion.
npx sshaman rm <alias>
Remove a host block, after a confirmation prompt.
Safety
- Backups before every write to
~/.ssh/config.bak/config.<timestamp>.bak. The backup folder is createdchmod 700; the 10 most recent backups are kept and older ones are pruned automatically. - Atomic writes: changes are written to a temp file and renamed over
~/.ssh/config, so the file is never left half-written. On any failure the original is untouched. - There is no
restorecommand — roll back by copying a file out of~/.ssh/config.bak/yourself if you ever need to.
Development
pnpm install
pnpm test # vitest
pnpm run typecheck # tsc --noEmit
pnpm run build # tsup → dist/index.jsLicense
MIT
