You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Terminal now uses the native russh client (fixes the dead Windows terminal): The interactive terminal no longer spawns the system ssh binary inside a local pseudo-console (ConPTY on Windows). It now runs over the same pure-Rust russh client as metrics and SFTP, so the terminal works identically on every OS — the blank, unresponsive Terminal tab on Windows is fixed. The terminal reuses the app's existing key, SSH agent, password, and known_hosts (trust-on-first-use) authentication, so password-auth hosts still connect without prompting and the separate SSH_ASKPASS helper has been removed.
ProxyJump (-J) is not yet supported in the terminal and is refused with a clear message instead of connecting direct; metrics/SFTP never used it. Tracked as a follow-up.
Passphrase-protected keys without an SSH agent cannot be unlocked interactively in the terminal anymore. Use an SSH agent or an unencrypted key. On Windows there is no agent fallback yet, so prefer an unencrypted key there.
The terminal no longer reads ~/.ssh/config directly, so exotic directives such as ProxyCommand no longer apply (the parsed HostName/User/Port/IdentityFile/ProxyJump still do). This makes the terminal consistent with the rest of the app.
Security
Validate public-key format and reject control characters before embedding keys in remote shell commands.
Sanitize sshd_config directive edits and scope the disabled Include to the cloud-init drop-in only.
Store config.toml, hosts.toml, and snippets.toml with 0600 permissions, and remove temp files left by a failed save.
Reject .. traversal and null bytes in SFTP upload/download paths.
Pin all GitHub Actions to commit SHAs and verify release archives against SHA256SUMS in install.sh (with a shasum fallback on macOS).
Bug Fixes
Log files no longer fill the disk: On startup OmnySSH now prunes rolling log files older than 7 days from its config directory. The cleanup is best-effort and never blocks startup, works on every platform via the native config path, and only touches omnyssh.log* files — config.toml, hosts.toml, and snippets.toml are left untouched.
Man page now installs reliably: install.sh failed to install the man page into the system directory (e.g. /usr/local/share/man on macOS) because it never elevated with sudo, so man omny reported "No manual entry". The man page is now downloaded to a temp file first and installed with a sudo fallback, mirroring the binary install.
Remote command exit status is no longer lost when it arrives after EOF.
Multi-file deletes fixed: all in-flight remote deletes are tracked before the panel refreshes, and every error from a multi-file local delete is reported.
Terminal is always restored on exit, even if an earlier teardown step fails.
Docker view scales to many containers: docker inspect is batched to stay under ARG_MAX.
Documentation
Fixed inaccurate docs: --verbose now correctly states logs are written to a log file (not stderr) in --help, the man page, and the README; install.sh prints the OS-specific config directory; corrected the horizontal split keybinding in the changelog (Ctrl+], not Ctrl+-).
More inaccurate docs corrected: --theme is now documented as persisting your choice to config.toml (it always wrote the config back, but the README called it temporary); the [ui] config example no longer lists show_ip, show_uptime, card_layout, and border_style, which are parsed for forward compatibility but not yet wired to the renderer; and the "static binary" wording was corrected since the x86_64 Linux and macOS builds are not statically linked.
Other
Removed the vestigial empty package.json and package-lock.json (left over from an earlier project name); they served no purpose in this Rust project.
Removed the unused config/default.toml template — it was never read by the app, and the README already carries the canonical config example.
CI now fails if the committed doc/omny.1 man page drifts from src/cli.rs, so the generated man page can no longer go stale.
Removed dead code with no effect on runtime behaviour: unused functions with no callers (Screen::title, Host::id, key_path_for_host, the superseded host_list render path, and two unused popup renderers), plus three methods that were only reachable from their own tests (FileManagerPanel::clamp_scroll, ProbeOutput::section_names, KeySetupMachine::password_disabled) and those tests.
Made the sshd rollback backup lookup portable so it also works on BusyBox/Alpine hosts.