Releases: fpenezic/ssh-tool
Release list
v0.102.0
Added
- Colours in the SFTP file list. Folders are blue, hidden files are
dimmed, and interrupted transfers (.part) and editor or browser
leftovers (.swp,.tmp,.crdownload,name~) are marked with a
"partial" or "temp" label. Archives, scripts, packet captures, config
files and symlinks each get their own icon colour, and a file owned by
someone other than the user you are logged in as shows its owner in
orange. Each rule can be switched off from the new Colors menu at the
end of the file pane toolbar; the choice is remembered on this machine.
Fixed
-
Fast output no longer lags behind in the terminal. A command that
prints a lot at once (seq 1 10000000, a big log,catof a large
file) used to take about twice as long to appear on screen as it took
to run, because every small piece of output was sent to the window
separately. Output that arrives in a burst is now sent in larger
pieces, and the terminal keeps up with the server. Typing and
full-screen programs respond exactly as before. Applies to SSH and
local tabs. -
A clear error when a server has no working SFTP. On some NAS
firmware SSH works but SFTP does not (the server is set up to run an
SFTP program it does not have), and opening the file pane failed with
"error receiving version packet from server: server unexpectedly
closed connection: unexpected EOF" - which reads like a network
problem. It now says the server has no working SFTP subsystem, that
SSH itself is fine, and whether the server closed or refused the SFTP
channel. The original error is kept in brackets.
opkssh
- A browser sign-in gives up after 90 seconds instead of five
minutes. If the sign-in page is left alone, the connect or Sign in
now fails after 90 s with "sign-in timed out" instead of waiting five
minutes and then reporting "context deadline exceeded". Start it again
if you needed longer. The Sign in now button on a credential also
lines up with the fields below it instead of sitting at the far edge
of the window.
v0.101.0
File transfers
- SFTP is as fast as scp. Transfers used to keep only two small
requests in flight at a time, so the round trip to the server set the
speed, not your link: on a host where scp managed 5 MB/s, ssh-tool
stayed under half of that. Uploads and downloads now keep up to 64
requests in flight and match scp. Folder transfers get the same speed. - An interrupted transfer picks up where it stopped. A file now
arrives asname.partand only takes its real name once every byte
is there, so a cancelled or dropped transfer can no longer leave a
cut-off file that looks complete. Transfer the same file again and it
continues from the.part. Before continuing, the end of the.part
is compared with the source, and if the source has changed in the
meantime the transfer starts over instead of producing a mix of two
files. Uploading over an existing file on the server now replaces it
in one step. - Speed and time left. Each transfer shows its current speed
(averaged over the last few seconds, so it does not jump around) and
an estimate of the time left. When it finishes, it shows the average
speed. A transfer that stalls drops to 0 instead of showing its last
speed. - Several transfers at once get a summary and Cancel all. With two
or more running, a line at the top shows the overall progress, the
combined speed and the time left, plus a button to cancel them all.
Finished transfers stay listed until the last one is done and then go
together, so the overall percentage never goes backwards. - Shift-click and Delete in the file pane. Shift-click selects a
range the way it does in Explorer (Ctrl+Shift adds the range to what
is already selected), and the Delete key deletes the selection after
the usual confirmation.
Issues and expiry warnings
- The issues badge opens a list. It used to show a count, with the
details only in a hover tooltip, and clicking it opened a Settings
page without saying which issue it was about. Now it opens a panel
where each issue has a short explanation and a button that takes you
to where it gets fixed. - Credentials about to expire show up there. Any credential with an
expiry date appears 14 days before it runs out, and in red once it
has. Until now the only warning was a small label in the Credentials
view. - So do opkssh certificates, measured against their own lifetime.
Some providers issue certificates for a few hours, others for a
week, so a fixed number of days would not fit both. A certificate is
flagged with a quarter of its lifetime left and marked urgent with a
tenth left. For certificates opkssh issues without an end date, the
end is the forced re-login set by "Max cert age". - Sign in now. An opkssh certificate can be renewed on the spot,
from the issues panel or from the credential itself, instead of
waiting for the next connect to open the browser. While the sign-in
is waiting for the browser the button turns into Cancel. If a connect
is already waiting for the same sign-in, the click reuses it rather
than opening a second browser tab.
Fixed
- A torn-off tab keeps its connection's name and icon. A saved
local connection (a WSL shell, for example) moved into its own window
showed up as plain "wsl" with the default icon, and only looked right
again after docking it back. The same happened after reloading the
window. Every tab in a separate window, SSH ones included, was also
missing its connection icon. Both are fixed.
v0.100.3
All three were found by using the app, and all three had been quietly
wrong for a while rather than newly broken.
Fixed
- Renaming a tab now changes the tab. The new name was saved, but
the tab bar rebuilds its label from the connections inside the tab and
only fell back to the tab's own name when the tab had no panes at all- which a connected tab never is. The window title does read the name
directly, so the rename showed up in the taskbar and nowhere else,
which made it look like it had renamed the application. A renamed tab
now keeps its name in the bar, across a restart, and inside a saved
workspace; tabs you have not renamed still follow their connections.
- which a connected tab never is. The window title does read the name
- The last open tabs no longer travel between machines. Which tabs
you have open describes one machine and is meant to stay there, kept
out of the synced profile by name. When split-pane tabs arrived the
snapshot's format changed, and the list of things to keep local was
not updated with it, so since v0.99.0 the open-tab list has been
syncing: pull on another machine and it would arrive with the
first machine's tabs. Nothing failed, which is why it went unnoticed.
The stale copy clears itself the first time you change a tab - your
open tabs are not lost in the process. - Marked hosts stay visible in Ctrl+K. With a full result list, the
row of marked hosts was squeezed down to a couple of pixels while the
footer still offered to connect them, so the only evidence of what you
had marked was the count.
v0.100.2
No user-facing changes. v0.100.1 attached the apt and dnf repository
build to the release for the first time, and it got as far as signing
the finished trees before failing to publish them: the step set its git
identity in the wrong repository, so the commit had no author. One line,
fixed here.
What that run did prove, since the failure came after all of it: the
signing key imports from its secret and signs unattended, createrepo_c
and the dnf half work (neither could be tested locally), and retention
pulled the previous release's packages while correctly skipping older
tags that carry none.
If this release publishes the repositories, adding them looks like this:
# Debian / Ubuntu
curl -fsSL https://fpenezic.github.io/ssh-tool/ssh-tool.asc \
| sudo gpg --dearmor -o /usr/share/keyrings/ssh-tool.gpg
echo 'deb [signed-by=/usr/share/keyrings/ssh-tool.gpg] https://fpenezic.github.io/ssh-tool/deb stable main' \
| sudo tee /etc/apt/sources.list.d/ssh-tool.list
The landing page at https://fpenezic.github.io/ssh-tool has the dnf
instructions too. The .rpm targets Fedora - RHEL 10 and its rebuilds
have no webkitgtk6.0 package, so it will not install there.
v0.100.1
Small fixes, all from using the app rather than from a test suite, and
most of the same shape: the feature worked, but its result was invisible
or its target was not what you expected.
Added
- Rename a tab from its right-click menu. A tab is named after the
connection it opened, which is no help when half a dozen of them are
local shells with the same name. A renamed tab keeps its name across a
restart and inside a saved workspace. - The password prompt names the account. It said which host was
asking but not which user, so with several connections opening at once
there was nothing to say whose password it wanted. Now
"user@host:port". The tray notification says the same.
Fixed
- A new folder is shown, not just created. Creating one looked like
it did nothing: the tree reloaded and no folder appeared. It had been
created, inside whichever folder was selected, and a collapsed parent
never rendered the new row. New connections always revealed
themselves; folders now do too. - Clicking the empty space below the tree deselects. Without it, a
folder selected earlier stayed selected while looking like nothing
was - so "New folder" put the next one inside it, invisibly. - The create prompts say where the item will land, e.g. "Folder
name? (in Work / Acme)" or "(at the top level)". Where things go
has not changed; it is just no longer a guess. - Ctrl+click marks dynamic-inventory hosts too. On a Hetzner,
Proxmox or AWS host from a dynamic folder it did nothing - worse, it
fell through to an ordinary click and connected. The two kinds look
identical in the list, so there was no way to tell why one row marked
and the next one opened. - Escape clears the search before it closes the palette. Marking
hosts is meant to work across several searches, but the obvious way to
start the next one threw the set away. A second Escape, on an empty
box, closes as before. Marked hosts now also show as chips above the
footer, each removable, so a set collected across searches stays
visible.
v0.100.0
Version one hundred, and still 0.x - v1.0.0 waits for Wails v3 to
leave prerelease, not for the app to feel finished. Between 0.1.0 and
here: opkssh certificate auth, eight dynamic-inventory providers,
userspace WireGuard, five importers, an Android build, and a rather
large number of bugs that only showed up on someone else's machine.
This release is a good example of the last part. Three of its fixes came
from ordinary use rather than from a test: a rename field that would not
let the mouse select text, a second session that opened without a
cursor, and a bookmark that could not be written down because its tunnel
picks a new port on every run.
It also brings proper Linux packages. .deb, .rpm and .pkg.tar.zst
are attached to the release, so installing is one command instead of
downloading a binary and placing it yourself - each one installed,
verified and removed on a real system before it shipped. apt and dnf
repositories are next, which will make upgrades arrive the way every
other package on the machine does.
Added
- Bookmarks on local port forwards. A local (-L) forward could only
be used by copyinglocalhost:<port>into a browser by hand;
bookmarks existed but were reserved for SOCKS proxies. Local forwards
now take them too, in the tunnel popover, the forwards list and the
quick palette. The "Open URL" prompt starts filled in with the
forward's own address rather than a barehttps://. - Bookmarks work on tunnels that pick their own port. A forward set
to port 0 gets a different port on every run, so a saved bookmark
cannot contain the number. Bookmarks now take a{port}placeholder
(and{host}), filled in with the real value each time one is opened;
it is prefilled for you on auto-port forwards. Useful on fixed-port
forwards too, where it means changing the port later does not break
every bookmark that referred to it. - Per-forward browser choice. Each local or dynamic forward picks
how its bookmarks open: your normal browser, a throwaway isolated
profile, or a dedicated profile that remembers logins. The default is
unchanged behaviour for both kinds - your own browser for a local
forward, an isolated one for a SOCKS proxy. The dedicated profile is
the one to choose when two tunnels reach the same software on
different servers and one keeps logging you out of the other. - Local shells start in a sensible directory. New
Start in directorysetting, with a per-connection override on local-shell
connections. Empty means your home directory. - Open several hosts at once from the palette. Ctrl+Enter or
Ctrl+click marks connections in the Ctrl+K palette; Enter then
connects all of them. Marks survive retyping the query, so a set can
be collected across several searches. Hosts are dialled one after
another, because vault, host-key and password prompts are modal and
would otherwise stack up from different hosts at once.
Fixed
- The second session you open gets the cursor. Since v0.97, opening
a connection while another was already up left the new terminal
unfocused - you had to click it before typing. The guard that stops a
background session stealing the keyboard was matching any focused text
field, and xterm's own focus target is a textarea, so every terminal
looked to every other terminal like a field in use. - Switching to the terminal view focuses it. Arriving from Settings
or the toolbar button left the keyboard nowhere. This one was never
wired up rather than broken recently. - Typing in the palette no longer lands in a terminal. Opening a
connection, pressing Ctrl+K again and typing the next host could send
those keystrokes into the session that had just come up. v0.97 fixed
the case where the palette stayed open throughout; this fixes the
rest. A connecting terminal polls for up to 600ms to take the
keyboard, and the palette closes before the connection it started is
dialled, so looking at the document for evidence of typing was never
going to be reliable - with several sessions opening, whichever poll
finished last simply won. Palettes and dialogs now hold the keyboard
explicitly for as long as they are open. - Renaming with F2 lets you select the text. Dragging across the
rename field started dragging the row instead of selecting what you
were trying to overwrite - most annoying right after cloning a
connection, where selecting "Copy of ..." is the entire point. - Local shells no longer open in the install directory. They
inherited the app's working directory, so on Windows a WSL shell
started in/mnt/c/Users/<you>/AppData/Local/Programs/ssh-tool. WSL
needs its own--cdflag for this - a working directory alone cannot
reach the Linux home, since every Windows path maps to some/mnt/...
path.
Packaging
- Linux packages ship with releases.
.deb,.rpmand
.pkg.tar.zstare now built in CI and attached to every release,
named with their version and architecture. Each was installed,
verified and removed on a real system first - Fedora 44, Ubuntu 24.04
and CachyOS. Note the.rpmtargets Fedora: RHEL 10 and its rebuilds
have nowebkitgtk6.0package at all, so it will not install there. - The RPM no longer carries the build machine's hostname. nfpm
stampsos.Hostname()into the header unless told otherwise, so
rpm -qishowed the maintainer's machine name. - One category in the launcher entry. The desktop file listed both
Network and Development as main categories, which can list the app
twice in a menu.
Internal
- apt and dnf repository publishing is wired into the release workflow
and gated on a signing-key secret, so it stays dormant until the key
exists. It serves the same package files the release carries rather
than rebuilding them. Seedocs/TODO.md.
v0.100.0-rc1
Pre-release build for testing. Not published to sshtool.app.
v0.99.1
Added
-
Split tabs survive a restart. Workspaces and reopen-last-session
both kept only the pane you happened to be looking at, so a tab split
four ways came back as one terminal and the arrangement was gone. Both
now save the whole tab: which panes, where each one sits, how wide it
is, and whether it was showing a terminal or the SFTP browser. A tab
split three ways reopens split three ways, at the sizes you left it.Panes sharing one connection (a terminal with SFTP alongside it)
reconnect once, not twice, so restoring a workspace does not quietly
double the session count on your hosts. If a single host is down when
a workspace opens, that pane is dropped and the rest of the tab comes
back rather than the whole tab being lost.Workspaces saved before this release still open, and are upgraded the
next time you save them. -
Tooltips on the session toolbar appear as you reach them. The
toolbar is a row of unlabelled icons - copy host, copy password,
packet capture, log tail, port forwards - and the built-in tooltip
took about a second to show, which meant hovering and waiting to find
the button you wanted. They now appear almost immediately, and once
one is up, moving along the row shows the rest with no delay at all.
Fixed
- Saving an edited workspace was a dead end. The only option was
"Save current as…", and typing the name the workspace already had
failed with a database error instead of saving. Reusing a name now
offers to replace that workspace, the menu leads with "Save changes"
for the one you have open, and every workspace in the list has a save
button that writes the current tabs into it. The overwrite action
existed all along, buried in Settings - Workspaces; it is now where
the work happens.
v0.98.0
Fixed
-
Full-screen TUIs no longer tear themselves apart. Long sessions in
a terminal tab drifted into overlapping rows, swallowed characters and
borders in the wrong column. The PTY is read in fixed blocks, and a
terminal query that happened to straddle one of those boundaries was
passed through to the renderer half-parsed instead of being filtered
out, which killed its parser mid-stream. The filter now carries state
across blocks, so where the read happens to land no longer matters.
Anything that redraws continuously - Claude Code, htop, a text editor -
hit this regularly; a plain shell almost never did, which is why it
looked random. -
Emoji stop pushing everything one column to the right. Table
borders walked sideways and the character after an emoji was eaten
("bug open" arriving as "bug op en"). The terminal measured
characters with Unicode 6 widths from 2010, while the programs drawing
those tables measure them the modern way; each emoji cost a column.
CJK and Cyrillic were never affected, which made the damage look
arbitrary. Also fixed for the emoji that are only wide when a variation
selector follows - the warning sign, gear, heart and a dozen more -
which are narrow even under the newer table but drawn wide by every
current terminal. -
"Press c to copy" now actually copies. A program running in the
terminal has exactly one way to reach your clipboard, and we were
discarding it. Tools reported success while nothing was copied and
there was nothing to paste. Clipboard READS stay refused: they would
let any command on any host you are connected to read whatever you
copied last, which is often a password. -
Clicking a link opens your browser instead of taking over the
window. Some links prompted "Do you want to navigate to..." and, on
OK, replaced the whole app with a remote page - no back button, no way
out but a restart. Two separate holes: links a program marks up
explicitly were falling through to the terminal library's own
navigation prompt, and for the rest the WebView was racing us, which
short URLs survived and long ones did not. Both now go to the system
browser. If opening fails the URL is copied instead, with a notice, so
a click never does nothing. -
Ctrl+click no longer leaves text selected or overwrites your
clipboard. Returning from the browser left a selection behind, and in
Linux copy mode - where selecting copies - opening a link replaced
whatever you had copied, including something a terminal program had
just put there. -
Long OAuth logins work on Windows. URLs past a few hundred
characters never reached the browser at all: they were handed to a
legacy Windows helper that re-parsed them and gave up on the query
string. Short links always worked, so this only showed up on sign-in
pages.
Added
- The app window stays on the app. If anything tries to navigate the
window somewhere else, it opens in your browser instead. The app is
drawn by a browser engine, so a stray navigation would otherwise
discard the running UI entirely.
Known issues
- A URL that a program breaks across lines itself - printing a newline
and indenting the rest, rather than letting the terminal wrap it -
stays clickable only on its first line. Terminal-wrapped URLs are
unaffected, and links a program marks up explicitly carry the whole
address however they are displayed.
v0.97.0
Added
- A "+" at the end of the tab strip. Starting a tab meant knowing
where else in the window to look. It opens a short menu rather than
spawning something on the spot: "Connect to..." first, which opens the
same quick palette as Ctrl+K, then a local shell named after whichever
one you actually use - "New PowerShell", "New bash". Ctrl+click or
middle click skips the menu and opens the shell straight away, the way
a browser's "+" does. The menu shows the shortcut beside each entry, so
it works its own way out of a job.
Fixed
- Typing no longer lands in a terminal you are not looking at. Open a
connection from Ctrl+K, press Ctrl+K again while it is still
connecting, and start typing: the keystrokes went to the session that
had just come up in the background rather than to the palette in front
of you. Connecting is asynchronous and the terminal claimed the
keyboard whenever it finished, without checking whether you had moved
on in the meantime. It now leaves the keyboard alone whenever a palette,
a dialog or any text field has it.