Skip to content

Updates ​

ThinkTerm never installs an update on its own. It checks, it tells you, and it waits for you to decide.

Checking ​

While the desktop app is running it checks GitHub for a newer release by itself: about ten seconds after a launch, if the last check on record is older than the check frequency, and after that whenever that much time has passed again. The command-line tools, the TUI and the session server never check on their own.

Two rows on Settings › Software Update control that. Check Automatically is a switch, and Check Frequency offers Every 12 hours, the default, Daily and Weekly; it is greyed out while the switch is off. A change applies within a minute. Until you use the rows they follow check_for_updates and check_for_updates_interval_seconds in the config file; The update check in Configuration says how the two fit together and how a check is timed.

Settings › Software Update shows the outcome: the version you are running, whether a newer release is known, and how this copy was installed.

  • The button at the top is Install Update when a newer release is known and this copy is one ThinkTerm may replace, with Check for Updates stacked beneath it, and Check for Updates alone otherwise. Check for Updates asks GitHub there and then, whether or not Check Automatically is on: the button reads Checking… while the request runs and Checked for a moment after, and the card above shows what came back. If the request fails the card says Could not check for updates. and the reason is printed below it. thinkterm update --check, below, does the same from a terminal.
  • Last Checked is read-only. It says when the last check on record was made, whether by the app itself or with Check for Updates.
  • What's New opens the notes for the release on offer in your browser. With nothing on offer, View All Releases opens the list.
  • Download source is where updates fetch the release from, on this machine and on remote servers. Automatic, the default, starts with GitHub and turns to a mirror when GitHub is slow or unreachable; GitHub (direct) never uses a mirror; a single mirror can also be picked. Wherever the file comes from, it is installed only if it matches the checksum GitHub recorded.

When a check finds something, a capsule floats in the corner of the window rather than a window taking over the screen; The update capsule describes it. When the automatic check is the one that finds it, a notification is posted alongside — ThinkTerm update available — and clicking it opens that release's page on GitHub in your browser. Check for Updates..., in the ThinkTerm menu on macOS and in the command palette, opens Settings › Software Update, as does the CheckForUpdates action bound to a key.

Version numbers decide whether a release is newer, with one exception, a tie. A ThinkTerm.app packaged by hand on macOS from a source checkout can carry the version number of a release that was published later, from newer code. For that case ThinkTerm compares the time of the commit the app was built from with the time of the release's commit, and offers a release made from the later code as New build available. The notification then reads New ThinkTerm build available, and Settings › Software Update says A newer build of ThinkTerm x.y.z than the one you have. Finding the release's commit time is one more request, to GitHub's list of commits, made once and kept with the saved check. A release package is never compared this way, so it is never told about the very release it is.

A check is one request to GitHub's release API, apart from that lookup, and it carries no credentials. THINKTERM_UPDATE_TOKEN is read if you set it, which lifts GitHub's anonymous rate limit and is what a private fork needs. It is deliberately a different variable from the GITHUB_TOKEN the install script accepts: ThinkTerm's own code never reads GITHUB_TOKEN, so a token you exported for other tools is not sent by a check. The install script an update runs does read it, but only when it has to download the archive itself; see Installing. Privacy and Security lists everything else ThinkTerm sends.

Installing ​

Install Update replaces the files in place. The window in front of you keeps working while that happens, and ThinkTerm goes on running the version it started with.

That last part is the one people misread, so the confirmation says it outright: ThinkTerm x.y.z is installed. Restart ThinkTerm to start using it. Nothing switches underneath a running session.

A release may have come out since the one on offer was found, and installing the older one would only be followed by another update. So Install Update in Settings and the capsule first ask GitHub for the newest release and install that one; the card and the capsule then name it. If GitHub cannot be reached for that second question, the release on offer is installed.

The card at the top of the page follows the install. It reads Preparing to install ThinkTerm x.y.z… while ThinkTerm gets the install script ready, then Downloading ThinkTerm x.y.z… with a progress bar and a line like 63.1 MB of 80.0 MB · 79%, which gains about 12 s left once the download has run for a second. Installing ThinkTerm x.y.z… follows. If something goes wrong the card says The update could not be installed. and the reason appears below it, with what the installer printed when it got that far.

ThinkTerm downloads the archive itself and checks it against the SHA-256 GitHub recorded when the file was uploaded before the install script sees it. A download that does not match is deleted and nothing is installed. If GitHub has no checksum for the archive, the script fetches and judges it itself, as it does when run by hand, and there is no progress bar.

The desktop app fetches through the system's proxy, or the one the environment names, SOCKS included. thinkterm update fetches with the system's curl, which takes the proxy the environment names.

Once the install has finished, the card offers Restart ThinkTerm, but only where restarting ends no terminal. A shell that ThinkTerm runs itself — in the app's own process, or over a direct SSH connection — goes down with it, and terminals kept in a session server do not. While any pane of the first kind is open there is no button, and you quit and reopen ThinkTerm when it suits you. The same goes for Windows: the installer leaves ThinkTerm running, and the card waits for the installer to finish and then offers the same restart.

A session server that was running before the update is moved to the new version when ThinkTerm next starts: the running server hands its panes to the new build, and the terminals in it carry on. A server that is newer than the app starting — an app left behind by an update of the server — is left alone, and that window runs terminals of its own. The ones in the server are still there; they come back when ThinkTerm is updated, or end if you stop the session server in Settings instead.

The update capsule ​

When a newer release is known, a capsule floats in the bottom-right corner of the terminal area in each window: a rounded pill reading Update available and the version. A click does what Install Update does, when this copy is one ThinkTerm may replace. For any other copy it opens Settings › Software Update, which names whoever owns the files. The capsule keeps out of the way of a menu, the command palette and dialogs.

It then follows the install in place of the card. Downloading and a percentage appear, with a progress ring turning round its icon, then Installing. When the install is done it reads Restart to update where restarting ends no terminal, and a click restarts ThinkTerm. Where restarting would end a terminal it reads Update installed and a click opens the Settings page. If the install fails it reads Update failed with Retry, and a click tries again. A click does nothing while the update downloads or installs.

A close button opens on the capsule when the pointer rests on it. Dismissed, the capsule folds up and flies into a dot on the Settings button in the sidebar, where it stays until the next launch; the dot turns red if the install failed, and the Settings button then opens Settings › Software Update instead of Settings. Closing the capsule while the update downloads does not stop the install.

Who is allowed to replace the files ​

ThinkTerm only updates copies it installed itself — the ones that came from the install script. Every other way of installing has an owner: a package manager, Homebrew, Nix, the AppImage's own updater, or the person who ran cargo build. For those, ThinkTerm names the owner instead of writing over its files.

How this copy was installedWhat ThinkTerm does
Install scriptInstalls the update, keeping the same variant
ThinkTerm.app placed by handReplaces it where it sits, and adds the command-line tools under ~/.local/bin
AppImagePoints you at AppImageUpdate, or the new AppImage on the releases page
HomebrewTells you to run brew upgrade thinkterm. The Homebrew cask is not counted here: it puts ThinkTerm.app in /Applications, so the app treats it as placed by hand and replaces it in place
NixTells you to update through your Nix configuration
System package managerTells you to install the new package with apt, dnf, or whatever installed this one
Windows installerDownloads the new installer for this machine's architecture and runs it
Built from sourceTells you to pull the repository and build again
Not recognisedRefuses to replace it, and says to update it the way it was installed

Where it will not replace the files, thinkterm update does more than name the owner: on macOS and Linux it prints the way out, which is to run the install script once and put that machine under script-managed installs. Every update after that is the button or the command. And if the installer runs but refuses the machine — glibc too old, musl, an architecture with no build — it says so, with the commands for building that release from source, rather than reporting a failure with no cause.

From the command line ​

thinkterm update follows exactly the same rules as the button in Settings.

bash
thinkterm update              # check, then ask before installing
thinkterm update --check      # report whether a newer release exists, install nothing
thinkterm update -y           # install without asking
thinkterm update --version X  # install release X instead of the latest, downgrades allowed

Neither path reimplements the installer. Both download the release archive and check it as described under Installing, then hand the job to install.sh, which is the one place that knows the archive layouts and the swap between the desktop and server variants. An archive ThinkTerm has downloaded goes to it with --from, alongside --version and the --prefix the install was made under. The script is fetched from the default branch rather than from the release being installed, so a fix to the installer reaches every existing install at once instead of waiting for the next release. Windows has no install script; there, both download the new installer and run it.

thinkterm update lets the script write straight to your terminal, so on a server install the script's own handover applies: a running mux server passes its sessions to the new build, as described under Upgrading and removing. Install Update in Settings captures the script's output instead, and the desktop app moves its session server over the next time it starts.

Updating a remote server ​

A client and a server refuse to talk across a protocol change. The usual way that happens is your desktop being upgraded while the server on some host keeps running last month's build.

ThinkTerm already holds an SSH session to that host, so it can repair the mismatch itself rather than sending you off to log in by hand. On a version mismatch during attach it says which versions the two sides run, and what it does next depends on the host.

Some mismatches it cannot repair, and it says so before asking anything. Two it knows from your own configuration: a domain configured to run ThinkTerm from a fixed path, and a client that is itself a development build with no release to match. A third is a server that is newer than this client. It is left exactly as it is, because it would not hand its sessions to an older build, and the message says to update ThinkTerm here instead.

Otherwise ThinkTerm opens an SSH session to the host and reads what is installed there. Nothing has been requested from GitHub yet and nothing on the host has changed. A host whose glibc is too old for the variant that would go there — below 2.31 for the server variant, below 2.35 for the desktop — one that uses musl, or one with no release for its architecture is reported at this point, before any question, with how to build from source. A host on glibc 2.31 to 2.33 gets the server build with OpenSSL built in. The variant follows what the host has: a desktop install there keeps its GUI, and on Linux so does a desktop app from a distro package, which writes no install record. It gets the desktop variant under ~/.local, its launcher moves to the new install, and the app and the server stay on one version. If the host's glibc is too old for the desktop variant, the question says that only the server is updated and the app stays at its own version. A macOS app bundle on the host is left alone, because it updates itself.

Then it asks once. The question says which version goes on the host and as which variant, that it is installed as the SSH user under ~/.local with no root, what will be sent over SSH, and anything that comes along, such as the desktop app. A client built with uncommitted source changes is not refused for that; the question carries a warning that the released version may still not match it. Answer n and nothing has been changed anywhere: ThinkTerm prints the command for you to run on the host yourself.

Only on yes does ThinkTerm go to GitHub, to look up that release. It is the version this client runs, not necessarily the latest. If the lookup fails, ThinkTerm says Could not resolve release x.y.z, gives the reasons and stops. Otherwise it sends the host an install script and the release's checksums over the SSH session, and the host downloads the archive itself; ThinkTerm does not carry the download. The script is a signed copy fetched online when it can be verified within four seconds, and the copy built into ThinkTerm when not, so nothing unverified runs. Download source applies, so a slow GitHub gives way to the mirrors as described in Install. The installer's output, with a byte count and rate for the download, is relayed into the connection window.

What happens to the running sessions then depends on one setting, on the same Settings › Software Update page and on by default:

Keep sessions when updating a remote server — the running server hands its panes to the new version instead of stopping; nothing running in them ends.

A handover that fails part-way is tried again, up to three times. A server too old to hand its panes over falls back to the question below. With the setting off, ThinkTerm asks before stopping the old server, because stopping it ends every session it holds. That is never done unasked, and if you decline, the old server keeps running until you stop it and reconnect.

The handover itself is the same mechanism described in Remote — a running server passing its panes to a new binary without the sessions noticing.

  • Remote — how sessions survive disconnects, restarts and upgrades
  • Command Line — the rest of the thinkterm subcommands
  • Install — the install script that every update runs