Releases: DasDuo/ShuttleX
Releases · DasDuo/ShuttleX
Release list
ShuttleX v1.14.1
Fixed
- A single group (e.g. the whole list when the source is
~/.ssh/config) couldn't be collapsed — its chevron did nothing. It now toggles like any other group: expanded by default when small (≤5 hosts), collapsed otherwise (with many hosts you search instead of scroll), and always collapsible. Searching still expands everything.
ShuttleX v1.14.0
Added
- Duplicate a server in the editor (the new icon next to Edit): inserts a copy directly below, with
-copyappended to the name and everything else carried over. Handy for variants of the same host without re-typing it — e.g. one entry that opens a shell and another that runs a remote command likehtop, or the same server with a different user or port.
ShuttleX v1.13.1
Fixed
- Pressing ⌘, opened an empty grey window instead of Settings. It now opens the real settings window — the same one the gear button opens.
- Opening Settings is now consistent from every entry point (gear, ⌘,, the right-click menu): the dropdown panel closes first and the settings window comes cleanly to the front, instead of the floating panel sometimes covering it.
ShuttleX v1.13.0
Added
- Copy SSH command: right-click any server in the menu to copy its
ssh …command to the clipboard — handy for sharing in chat, pasting into another terminal, or dropping into a ticket. Works for every source.
ShuttleX v1.12.0
Added
- Optional server tags (off by default; enable in Settings → General). When on, each server gets an optional comma-separated Tags field in the editor, tags show as small badges in the menu, and search matches them. When off, tags appear nowhere — and any existing tags are kept, not removed. Stored as
tagsin the JSON (written only when set); a remote source may also provide them (strings only, never executed).
ShuttleX v1.11.3
Changed
- The table-import preview now shows at most 50 servers (with a "Showing 50 of N" note) and renders lazily, so importing a large sheet (hundreds/thousands of rows) stays responsive. All rows are still imported — only the preview is capped.
Fixed
- IPv6 addresses in bracket notation (e.g.
[2001:db8::1]) were wrongly rejected by the in-app editor and table import. The character denylist treated[and]as unsafe (shell globbing) — but they pose no risk here: every connection target is shell-quoted when thesshcommand is built, and that is the actual injection guard, not the denylist. Brackets are now allowed, so bracketed IPv6 hosts save and import correctly; genuine shell metacharacters and whitespace are still rejected.
ShuttleX v1.11.2
Fixed
- Opening Settings still crashed in 1.11.1. The cause was
KeyboardShortcuts.Recorder, whoseBundle.modulecan't be resolved in a hand-built, code-signed.app(its accessor only looks next to the executable or at a baked build path — and a resource bundle at the app root can't be signed). Replaced it with a small custom recorder that uses only the package's core API and never touchesBundle.module.
ShuttleX v1.10.0
Added
- Keyboard navigation in the menu: ↑/↓ moves the selection through the results (the list scrolls to keep it visible) and Enter connects the selected server. The search field clears after connecting.
ShuttleX v1.9.0
Added
- Favorites: pin your most-used servers to a ★ Favorites section at the top of the dropdown — hover the star on a row, or use the Favorite toggle in the editor. The section is expanded by default when small (≤5) and always collapsible. Stored as
favoritein the JSON (written only when set); JSON source only.
ShuttleX v1.8.0
Added
- Run a command on a server: a new Remote command field in the editor (
remoteCommandin JSON) buildsssh -t … <command>from the host/user/port — e.g. enterhtop. A Raw custom command toggle keeps the verbatim mode for jump hosts/tunnels. - Reorder servers within a group by dragging them in the editor.
Fixed
- Servers that share a name (e.g. two "AdGuard" with different IPs) are now handled correctly in the editor — editing, deleting or reordering one no longer affects the other. Entries now carry an internal id instead of being matched by name.