Skip to content

Releases: fpenezic/ssh-tool

v0.102.0

Choose a tag to compare

@github-actions github-actions released this 24 Sep 14:36

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, cat of 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

Choose a tag to compare

@github-actions github-actions released this 23 Sep 18:27

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 as name.part and 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

Choose a tag to compare

@github-actions github-actions released this 22 Sep 20:52

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.
  • 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

Choose a tag to compare

@github-actions github-actions released this 22 Sep 15:01

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

Choose a tag to compare

@github-actions github-actions released this 22 Sep 14:07

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

Choose a tag to compare

@github-actions github-actions released this 16 Sep 19:36

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 copying localhost:<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 bare https://.
  • 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 directory setting, 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 --cd flag 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, .rpm and
    .pkg.tar.zst are 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 .rpm targets Fedora: RHEL 10 and its rebuilds
    have no webkitgtk6.0 package at all, so it will not install there.
  • The RPM no longer carries the build machine's hostname. nfpm
    stamps os.Hostname() into the header unless told otherwise, so
    rpm -qi showed 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. See docs/TODO.md.

v0.100.0-rc1

v0.100.0-rc1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 16 Sep 18:57

Pre-release build for testing. Not published to sshtool.app.

v0.99.1

Choose a tag to compare

@github-actions github-actions released this 15 Sep 16:37

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

Choose a tag to compare

@github-actions github-actions released this 14 Sep 20:50
Immutable release. Only release title and notes can be modified.

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

Choose a tag to compare

@github-actions github-actions released this 14 Sep 18:00
Immutable release. Only release title and notes can be modified.

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.