CoreTerm
Changelog
All notable changes to CoreTerm, newest first. Dates are the day the version was published.
The rule for numbers: patch for fixes and wording, minor for new features or changed behaviour. Anything handed to anyone gets a number of its own — a build shared twice under one number is a build nobody can identify from a bug report.
0.10.1 — 15 August 2026
Changed
- CoreTerm now lives at
ssh-client.coreserv.de. The download page, the update check and the package repositories all answer there.
Nothing has to be changed on an existing install. The old address is still served — not as a redirect, but as the same thing under both names — because the update endpoint is compiled into the application: every copy released before this one asks the old host for as long as it is installed, and the same goes for an apt, dnf or pacman entry written before today. Both keep working.
From this version on the new name is asked first, with the old one still listed behind it, so an update also arrives if one of the two is unreachable.
0.10.0 — 15 August 2026
Added
- Ctrl and the mouse wheel over a terminal changes the font size. It writes the setting rather than zooming, so it survives a restart and every tab agrees — a webview zoom would have scaled the whole interface, and in a Tauri window there is no Ctrl+0 to undo that. Six to forty: below six the wheel that got you there can no longer be aimed at the terminal.
- The font is picked from a list instead of typed. Each entry is set in itself, with the same sample characters underneath —
0Oo1lI, braces, arrows — because those are what actually differ between monospace faces, and a name is not a preview.
Only fonts this machine has are offered. There is no API for that, so it is measured: a font that is not installed renders exactly as wide as the generic it falls back to, and one that is installed does not. A name can still be typed under *Enter a name…* for anything the measurement cannot see.
Whatever is chosen keeps the bundled CaskaydiaMono NFM behind it, so Powerline separators and Nerd Font icons come from the patched font at the width of a character cell — which is the thing 0.2.1 was about, and which used to be lost the moment anyone put another font first.
0.9.1 — 13 August 2026
Fixed
Two things 0.9.0 got wrong, both reported straight back.
- The hover details were built out of native tooltips, which in this webview wait about a second, draw in the system's style rather than the app's, and disappear if the pointer moves a few pixels. Something that takes a second to appear is something nobody waits for, so it read as not being there at all. They are drawn by the application now: a quarter of a second, the app's own look, and laid out as labelled rows rather than a run of text.
- **The search in the keys list only appeared once there were more than four keys.** The reasoning was that a short list is its own search. The effect was that someone looking for a search box did not find one and concluded there was none, which is exactly what happened. It is there from the first key, and the stored credentials below it have one too — by name, account or host.
- Going up a folder is a double-click again. 0.9.0 made
..respond to a single click, which fixed the repeat problem by changing what the row does; the ordinary folder behaviour is what was wanted. The clicks are now paired by the app rather than by the webview, and the pair is reset after each one, so click-click, click-click goes up two levels without the mouse having to move — which was the original complaint.
0.9.0 — 13 August 2026
Fixed
- A folder download of more than about a thousand files lost most of them. Found while testing the change below, and much the worse of the two.
Every SFTP server keeps a bounded table of open handles, and a recursive download opens one per file in a tight loop. The library closes a file when the handle is dropped, but cannot wait for that close to be acknowledged — and that turned out not to be enough. Measured against a real server: the first 1019 files arrived, and files 1020 through 2401 all came back "handle limit reached".
Before this release that ended the transfer, so it looked like a download stopping for no stated reason part-way through a large folder. Handles are now closed and awaited after every file, on the error path too. The same tree: 2400 of 2401, and the one that failed is the one nobody can read.
The same leak was in uploads and in opening a file in the editor.
- One unreadable file abandoned everything after it. A
.tmpthat was there when the tree was walked and gone by the time its turn came — which on a live server is not an edge case — ended the whole download, with no way to see which files had made it.
A file that fails is now stepped over and counted. The transfer runs to the end, the bar shows how many were skipped as it goes, and the summary afterwards lists what was left behind and why. Uploads behave the same way.
- A recursive download showed nothing for the first several seconds. The remote tree is walked before anything moves, so the progress total is honest rather than a number that grows — but the walk creates the local folders as it goes, so directories appeared on disk while the window stayed empty. It now reports the scan while it happens, naming the directory it is in and how many files it has found.
- Going up a folder needed the mouse moved between clicks. The
..row wanted a double-click, so the third and fourth click of a quick sequence continued the same multi-click instead of starting a new one, and nothing happened until the pointer moved. It is a single click now:..cannot be selected, dragged or deleted, so the double-click that protects real files was protecting nothing here. - The status bar is gone when monitoring is off, rather than sitting there saying so. It exists to show what the far end is doing; with monitoring disabled it had nothing but the name already in the tab.
Added
- Markdown in the editor, with a real parser rather than a pattern list — code fences, tables and lists stay apart properly. Also added, from grammars that were already in the bundle and simply unused: HTML, CSS/SCSS/LESS, Rust, Go, Lua, Perl, Ruby, PHP, C/C++/Java/C#, PowerShell, and diffs. TOML gets its own grammar instead of being read as an INI file.
- Hovering a session shows what the row has no room for: the account and port, which key or which kind of authentication, the jump hosts, the folder, the startup command. The keys list does the same — type, fingerprint, comment, and how many sessions use it — and gets a filter of its own once there are more than four.
- Push and Pull in the sync settings. *Sync Now* merges, which is right almost always. These are for the rest: when two devices have diverged and one of them is simply the one you want, the answer is to say which, not to merge harder. Each replaces the other side outright and asks first, naming what is about to be lost.
0.8.2 — 13 August 2026
Fixed
- A colour picked while creating a session was thrown away. Opening the session again and picking the same colour a second time made it stick, which is a fair description of a feature that does not work.
The dialog builds one set of values and hands it to either "update this session" or "create a new one". The create branch spread those values into a new object and then, on the line below, set the colour back to nothing. Both branches read from the same place, so the colour was correct right up to the point where it was overwritten — and only ever on the first save, which is exactly why it looked intermittent rather than broken.
Fixed
- The file browser sat on "Loading…" forever on a Pterodactyl/Pelican (wings) server, and on anything else that offers file transfer and nothing else.
The listing was never the problem. Against a real wings server the directory came back in nine milliseconds — and then the browser waited, because after every successful listing it asks the host who the numeric owner and group ids belong to, and it asks by running getent over a second channel. Wings accepts that channel, accepts the command, and then says nothing at all: no output, no exit status, no end-of-file. Nothing in the client had a deadline, so it waited for a reply that was never coming, with a complete directory listing already in hand.
Three things now stand between that and a hang:
- A session opened as SFTP only does not ask. It deliberately has no shell; running a shell command on it was a contradiction, and the servers such a session exists for are exactly the ones that mishandle it.
- The name lookup has five seconds, after which the columns show the numeric ids — which was always the documented fallback, and is a complete answer in its own right.
- Every command the app runs over a connection now has a hard limit and reports what happened instead of waiting. That covers the host-monitoring probe, *Run on several hosts*, and deploying a public key, all of which could hang the same way against the same servers.
Note
On such a server the Owner and Group columns show –. It reports no ids to put there and has no user database to ask; nothing is missing that could have been shown.
A session no longer has to be a shell. The New Session dialog opens with a choice of three.
Added
- SFTP-only sessions. Files, no terminal. The connection authenticates and stops there: no PTY is requested, no shell channel is opened, and the file browser fills the window instead of the sidebar strip.
What this is *not*: the thing that makes a transfer-only server reachable. Measured against OpenSSH with ForceCommand internal-sftp and PermitTTY no, the files were always reachable — a normal session got a terminal that printed "This service allows sftp connections only.", closed, and sat there dead beside a working file list. That terminal is what goes away. Two other things go with it: the monitoring that such an account will refuse, and the shell channel it has no use for. On SFTP servers stricter than OpenSSH, which refuse the session channel outright, it is the difference between connecting and not.
- Serial consoles. A COM port or tty, a baud rate, and the terminal you already have. Default 9600 8N1 with no flow control, which is what the great majority of console ports still use; data bits, parity, stop bits and flow control are behind "Framing" for the ones that do not.
The port list is filled from what is plugged in, and the field stays editable — a session is usually saved before the adapter is connected, and on Linux enumeration only sees what the kernel chose to expose. Right-click in the terminal for *Reset device (pulse DTR)*, which is how most boards are restarted over USB.
Everything the terminal already does applies: scrollback, the paste guard, copy on selection, a separate window, and R to reopen the line after the cable comes out.
Notes
- On Linux a serial port belongs to the
dialoutgroup (uucpon Arch and Fedora). Without membership, opening one fails with "Permission denied" — the message says so and gives the command. A port held open by another program says *that* instead, which is a different problem with a different fix. - Nothing was added to the package dependencies. Port enumeration can be done through libudev; it is done by reading
/sysinstead, so the.deband.rpmstill depend on nothing but the webview and GTK. - Existing sessions are untouched and open exactly as before. Sessions saved before this version carry no type at all, and are read as SSH.
- A session export carries the type and, for serial, the line settings. They describe a cable rather than a machine and hold no secret, so unlike a password there is nothing there to leave behind.
0.7.0 — 9 August 2026
Removed
Both of the temporary things the rename left behind are gone.
- The second update address. Installations from before the rename polled
…/openmobassh/latest.json, which was served alongside the real one so they would still find updates. Nothing is left on a pre-CoreTerm build, so it is no longer written — and the directory is gone from the server. - The vault migration. The first start of CoreTerm copied the vault, its backups and the sync settings out of the old data directory, because the directory name is derived from the application identifier and that changed with the name. Everyone has made that trip. If you ever restore a backup of an *OpenMobaSSH* vault, copy it across by hand:
`` Windows %APPDATA%\io.coreserv.openmobassh -> %APPDATA%\io.coreserv.coreterm Linux ~/.local/share/io.coreserv.openmobassh -> ~/.local/share/io.coreserv.coreterm ``
0.6.1 — 6 August 2026
Fixed
- "SFTP error: Limit exceeded: Handle limit reached". Every connection shares one sftp-server, and that server keeps a bounded table of open file and directory handles.
read_dirin the SFTP library opens a directory handle and closes it after the listing — but returns early on a read error *before* the close, so a directory that cannot be fully read leaks one handle. Recursive walks over trees with unreadable subdirectories do that repeatedly, and eventually the server refuses to open anything at all: the file list goes blank and stays blank until the session is closed.
The leak is in the library and cannot be closed from here. A new channel is a new sftp-server with an empty table, and that can: a listing that fails this way now throws the session away and tries once more on a fresh one. A dropped connection reads the same and is handled the same, so a session that died quietly reconnects instead of staying broken.
One retry, not a loop — if the second attempt fails too, the fault is the path or the server, and repeating would turn a clear error into a hang.
- Download on a folder did nothing. Not an error, not a transfer — nothing. The frontend filtered directories out of the selection before asking the backend, so the menu entry existed and led nowhere. Folders are walked now, the tree is recreated under the destination you pick, and the progress total counts the real files because the walk happens before the first byte moves. Symlinks are not followed: one pointing at
/would walk the whole filesystem. - Dragging a file out gave no sign when the copy finished late. A native drag hands the operating system a real path, so the file has to be on disk before the drag begins — the protocol has no "fetch it when I drop". If the button was released while the copy was still running, the gesture simply did nothing and the reason was invisible. It now says the copy is ready and that a second drag goes straight out. See the note below.
Note on dragging large files out
There is no way to make the download start *after* the drop. What the OS receives at the start of a drag is a list of paths, and it copies from them itself at drop time; nothing asks the application for the bytes. Windows has a delayed-rendering mechanism for exactly this case, but it is Windows-only, has no Linux equivalent, and is not something the drag plugin exposes.
For a large file or a folder, use Download instead: it asks where to put it, runs in the background with progress, and can be cancelled.
0.6.0 — 5 August 2026
Added
- Export sessions, without the way in. Right-click a session for *Export…* or a folder for *Export Folder…*. The file carries what someone needs to reach a machine and recognise it — name, host, port, username, which kind of authentication, jump hosts, startup command, colour, folder — and carries no password, no passphrase and no key. It is plain JSON, so it can be read before it is sent.
The key *id* is left out too: it points into the exporter's vault and would mean nothing, or something wrong, elsewhere. The key's name travels as a hint instead, and the import picks up a local key of that name if there is one.
- Import them back. *Import Sessions…* on the tree background, or *Import Into Folder…* on a folder. It shows what the file contains and where it will land before creating anything, and it only ever adds — nothing existing is matched, merged or replaced. A folder of the same name in the same place is reused, so importing the same file twice does not stack "Customer A" inside "Customer A".
- Drag sessions and folders into other folders. Including into subfolders. A folder cannot be dropped into itself or into its own subtree — that would detach the branch from the root and it would simply vanish — and the attempt is marked in red rather than quietly ignored. Dropping onto a session means "into that session's folder"; dropping on empty space means the root.
0.5.0 — 5 August 2026
Changed
- Session colours are named after the colour again. They used to be called Production, Staging, Development, Internal, Customer and Archive. That presumed a taxonomy: someone whose folders are one per customer has no "staging", and had to translate "I want the green one" into "so, Development". They are now Red, Yellow, Green, Cyan, Blue, Purple and Grey — what the dot actually looks like.
Added
- Say what a colour means to you. Settings → Connection → Session colours takes an optional label per colour, shown after the colour name: "Green — Development". Left empty, only the colour appears. It travels in the vault, so it is the same on every machine — a red dot meaning "production" on one and nothing on another would be worse than not having it.
- A seventh colour, a real blue. The palette had a teal called "blue" and no blue at all.
Note
Existing colours are untouched. The stored IDs did not change — only what is printed next to them — so nothing needs re-applying.
0.4.1 — 5 August 2026
Fixed
- Setting a colour on a whole folder did nothing.
session.colorholds an ID —red,amber— which everything that draws a colour resolves through one shared list. The bulk dialog shipped with a hand-written palette of hex values instead, so it wrote something no lookup could match. An unknown ID reads as "no colour" by design, which is why the setting appeared to be stored and then simply ignored. The list is now derived from the shared one, so the two cannot disagree again, and the picker shows the actual colour next to its name.
If you already applied a colour this way, apply it again — the old value is still in the vault and still means nothing.
- The key picker in that dialog was squeezed into the margin. Its width lost to the
w-fullthat the shared input style already carries: Tailwind resolves competing utilities by stylesheet order, not by the order they are written. The two selects are stacked now, which needs no width at all.
0.4.0 — 5 August 2026
Added
- Apply settings to a whole folder. Right-click a folder in the sessions tree and pick *Apply to All Sessions…*. Sets the authentication method and SSH key, the username, the port or the colour across every session in it, optionally including subfolders. Each row is opt-in: only what you tick is written, so nothing silently flattens whatever differed between sessions.
- Reconnect a dead session with
R. When a session times out or drops, the terminal says so andRdials the same host again. The key is ignored while a session is alive, so it can never swallow a keystroke that was meant for the shell. - Select files with the mouse. Drag a rectangle over empty space in the SFTP browser to select what it touches; hold Ctrl to add to the selection. Dragging *from* a file still drags it out to the desktop, unchanged.
Ctrl+Aselects every file in the SFTP browser, andEscclears the selection. Both are scoped to the file list, so neither fires while you are typing in the terminal — whereCtrl+Ameans "start of line".- This changelog, and a version history on the download page.
Changed
Enterconfirms a multi-line paste. The guard interrupts a paste you already asked for, so agreeing with yourself should not need the mouse.Shift+Entertakes the safe branch and pastes as one line;Esccancels.
0.3.0 — 4 August 2026
Changed
- The client is now called CoreTerm. "Moba" is the distinctive part of MobaXterm, and carrying it in a directly competing SSH client is a trademark risk rather than merely derivative. "Open" promised open source, which this is not.
- New application icon.
Added
- Your data moves itself. The data directory is derived from the application identifier, which changed with the name, so the first start of the renamed app would otherwise have shown an empty vault. CoreTerm copies the vault, its backups and the sync settings across before anything reads them. It copies rather than moves: the old directory stays as a backup with a note in it saying where the data went and that it can be deleted.
- Package repositories for Arch/CachyOS/Manjaro (pacman), Debian/Ubuntu/ Mint (apt) and Fedora/Nobara/RHEL/openSUSE (dnf, zypper). Package-manager installs are exactly the ones the built-in updater must not touch, so they now update the normal way —
pacman -Syu,apt upgrade,dnf upgrade— without the application having to be running.
Notes for people upgrading
- On Windows the old *OpenMobaSSH* entry stays in the programs list and has to be uninstalled by hand: the installer carries a new name and therefore knows nothing about the old entry.
- On
.deband.rpmthe new package replaces the old one automatically. - Installations from before the rename still find updates: they poll a different address, which is served alongside the new one for the time being.
0.2.1 — 4 August 2026
Fixed
- Powerline characters were too wide. The symbols-only font shipped in 0.2.0 removed the empty boxes but got the size wrong: at font size 14 a terminal cell is 8.20 pixels wide while that font advances a full em — 14.00 pixels. Every separator was 1.707× too wide and pushed the line apart.
That is not a defect in the font. A symbols-only font belongs to no text font and must pick some width; matching a particular one is precisely what it cannot do. Patched Nerd Fonts exist for this, with the icons redrawn onto the host font's cell. CoreTerm now ships CaskaydiaMono NFM — Cascadia Mono, patched — so the text looks the same as before and ten separators in a row occupy exactly ten cells.
A font you set yourself is left alone. For icons there too, use a patched Nerd Font build of it; the font setting says so and offers a way back.
- "Show" on the update banner now opens the update section directly. It used to open the settings on whatever section was last used, leaving you to find the update yourself — the one thing the button existed to spare you.
Added
- The download page carries every package with checksums. It previously had only the two that can update themselves, which broke the download link for exactly the
.deb/.rpm/Arch installs that depend on it.
0.2.0 — 4 August 2026
The first version with a number and an update mechanism.
Added
- Updates. The app asks whether there is anything newer after every vault unlock, and therefore after every start. Settings → Updates shows the installed version and a button to look now. Switching it off means no request is made at all — not one whose result is merely hidden.
Every package is signed, and the public key is compiled into the application: a compromised update server cannot hand out a version of its own, only withhold updates or serve an old one.
The app installs updates only where it owns its own files — the Windows installer and the AppImage. A package from pacman, deb or rpm belongs to the package manager, which keeps checksums for it and expects to be the one that changes it.
- Remote port forwarding (
-R), alongside local and dynamic. - A help page for port forwarding, behind the question mark, with a worked example of each direction.
- Run one command on several hosts at once.
- Snippet library, and a command run automatically after login.
- Colour per session, shown in the tree, the tab and the terminal edge.
- Generate an SSH key and deploy it to a server, appending to
authorized_keyswithout disturbing what is already there. - A prompt when a host key has changed, instead of a refusal you cannot act on.
- SSH agent support, and the default key is now also tried for sessions configured for password authentication.
- Copy on selection can be switched off in the settings.
Fixed
- The terminal felt jerky. It was not the terminal but the number of messages: one per SSH packet crossing the process boundary, each with its own encoding and framing. A
journalctlproduces thousands per second. Output is now gathered for 8 ms or 64 KB, whichever comes first. - Deleted folders came back after a restart.
- Right-click paste on Linux.
- Network rate is shown in Mbit/s, not MB/s.
- 13 security findings from an adversarial review of the whole codebase, including an algorithm-downgrade hole in host key checking and a path traversal in SFTP downloads.
0.1.0 — 3 August 2026
First release. SSH and SFTP in one window, sessions in an encrypted vault (AES-256-GCM, Argon2id), port forwarding, a file browser that follows the terminal's working directory, and synchronisation of the vault between machines.