SSH Config Editing
Schooner treats ~/.ssh/config as the source of truth. It reads and writes the file with a lossless AST parser — your comments, blank lines, indentation, and Match blocks survive every operation.
The lossless parser
Most SSH config tools parse the file into a data structure and write it back from scratch — destroying your formatting in the process. Schooner uses an AST (Abstract Syntax Tree) approach:
- Parse the file into a tree that represents every token, comment, and blank line.
- Apply the requested mutation (add, edit, or delete a
Hostblock) to the tree. - Serialise the tree back to text — the unchanged parts are written byte-for-byte identically.
This means a file that looks like this before a Schooner edit:
# Work servers
Host bastion
HostName 10.0.0.1
User admin
# Main entry point for the cluster
IdentityFile ~/.ssh/work_key
…will look exactly like that after Schooner adds a new host below it (minus the new Host block).
Supported directives
Schooner reads and writes all common SSH config directives including ProxyJump, ProxyCommand, IdentityFile, LocalForward, RemoteForward, Match blocks, and Include directives.
Include files: Schooner reads included files for display purposes but currently only writes to the main ~/.ssh/config. New hosts are always added to the top-level file.
External change detection
Schooner watches ~/.ssh/config for changes made by external tools (vim, nano, another app). If it detects a modification while the app is running, it will:
- Show a notification or banner: "Your SSH config was modified externally."
- Open a merge dialog showing the external changes alongside Schooner's in-memory view.
- Let you choose: Accept external changes, Keep Schooner's version, or Review diff.
You will never lose a change silently.
What Schooner does not touch
- Your
~/.ssh/known_hostsfile (except to read it for fingerprint verification) - Any file outside
~/.ssh/ - Schooner-specific metadata (nicknames, tags, notes) — that lives in
schooner.sqlite, never in the SSH config