Changelog

# Changelog

All notable changes to Transit are documented in this file.

The format is based on Keep a Changelog,

and Transit adheres to Semantic Versioning.

How this file feeds the release pipeline:

published at <https://downloads.transitai.app>.

scripts/extract-changelog.mjs X.Y.Z to pull the matching ## [X.Y.Z]

section verbatim into the GitHub Release body and the download page's

release notes. A missing or empty section fails the release — so move

items out of [Unreleased] into a dated ## [X.Y.Z] section *before*

tagging. scripts/bump-version.mjs X.Y.Z is the companion that bumps the

version files in lockstep.

section AND the raw CHANGELOG.md uploaded to the downloads bucket, via

scripts/lib/strip-html-comments.mjs) — so repo-internal notes like the

CLAUDE.md §18 cost-impact records may live here as `` blocks.

An unbalanced comment marker fails the release. Comments are internal, not

secret: this file is still in the repo, so credentials never belong here.

[Unreleased]

[6.5.6] - 2026-09-03

Added

.rpm for ARM64 alongside the existing x86_64 packages — four Linux

downloads per release. Both are built natively, with the same

distro support as before (.deb: Ubuntu 24.04+ / Debian 13+; .rpm:

Fedora / RHEL 10 with EPEL). The install script picks the right

architecture automatically, and the downloads page lists each one

explicitly. Linux still has no in-app auto-update, so updating means

re-running the install script or downloading the newer package.

[6.5.5] - 2026-09-03

Fixed

signatures.** Follow-up to the v6.5.4 fix. Some devices negotiate a fully

modern key exchange yet still require the legacy SHA-1 ssh-rsa signature

for *user-key* authentication and never advertise which signatures they

accept. Because the key exchange is strong, the weak-crypto prompt never

appeared, so RSA key auth dead-ended. Transit now recognizes this case and

surfaces the same per-device weak-crypto prompt used for legacy key

exchange; approving it (optionally "Remember for this device") completes

the connection with the SHA-1 signature the device wants. As before, the

SHA-1 signature is never used without that explicit approval, and an

ed25519 key still avoids the prompt entirely.

[6.5.4] - 2026-09-03

Fixed

Gear that predates RFC 8308 never announces which RSA signature flavors it

accepts, and Transit's best-effort guess (rsa-sha2-512) was a signature

such devices cannot verify — so key auth failed in Transit while the same

key worked from OpenSSH. With weak crypto allowed for the device (the same

opt-in this gear already requires for its SHA-1 key exchange), Transit now

signs with the legacy SHA-1 ssh-rsa, matching OpenSSH's assumption for a

silent server. Without the opt-in nothing is downgraded, and a rejected key

now explains the likely cause — and the opt-in remedy — instead of a

generic "server rejected the credential".

[6.5.3] - 2026-09-02

Added

default, unchanged from before. Turn it off and a tab's ✕ (and a pane's

Disconnect) closes on the click, with no dialog. Customer request:

some people just want the ✕ to mean close.

Two prompts are kept either way, because they are not the same risk.

Close all tabs and quitting the app take down the whole workspace at

once. And a Files tab with transfers still in flight keeps its

confirm because that one warns about losing work rather than about

disconnecting — a preference about closing sessions should not quietly

start cancelling transfers.

Fixed

it at connect so long show output doesn't stall behind --More--,

and on EOS the command was sent, echoed into the scrollback — so it

looked like it had run — and then silently discarded by the device,

every session.

A live SSH shell channel is not a live CLI. EOS runs its CLI as a

separate process and discards anything typed before its prompt appears

rather than buffering it, so bytes sent the instant the shell came up

landed nowhere. Transit now waits for the device to actually look

ready — output gone quiet and a prompt-shaped tail — before sending

the paging init, bounded so a device with an unrecognizable prompt is

no worse off than before. Connect is not slowed: the wait happens in

the background.

Reported by a customer and reproduced in the lab. Not strictly

Arista-specific — any CLI slow to present a prompt could lose the init

the same way; EOS is simply slow enough to expose it every time.

<command> | no-more to return one command's full output with no

--More--, and Transit's per-vendor command gate was denying it — the

pipe stage was simply never added to the Arista allowlist, and the gate

default-denies what it doesn't recognise. It is read-only by

construction (it suppresses the pager; it cannot write a file or escape

a mode, which is what separates it from tee / redirect / append,

which stay blocked), so the denial was an omission rather than a

judgement.

This matters for capture reliability, not convenience: the agent waits

for output to go quiet, and a --More-- prompt is silent while it

waits for a keypress, so a paginated command stalls to the timeout and

returns truncated output. | no-more cannot be lost to device state

the way a terminal setting can.

Added

difference between zero and non-zero.** A non-zero count is red — the

thing you are actually hunting — and a zero count is green, an

affirmative all-clear. Both shapes vendors print are covered: the

count-before form (5 input errors, Cisco/Arista show interface) and

the count-after form (Framing errors: 3, Junos `show interfaces

extensive`), including a mix of both polarities on the same line.

This also closes a plain gap rather than just adding a keyword: the

plural never matched at all. The severity pattern's word boundary

could not hold between the r and the s, so error highlighted and

errors did not — and errors is the form every interface counter

uses, which made the most-read line in troubleshooting the one line

that never lit up. Requested by a customer.

Changed

Vitest 4.1.11, ESLint 10.9, zod 4.5, lucide-react 1.35, react-hook-form

7.86, TanStack Query 5.102, and the testing-library set.

Two updates were deliberately held back: TypeScript 7

(@typescript-eslint/eslint-plugin still peer-caps TypeScript below 6.1,

so taking it breaks npm ci outright) and react-resizable-panels 4 (a

two-major jump on the library behind terminal pane tiling and the Files

dual-pane — it gets its own change with its own smoke test rather than

riding in a routine refresh).

log, thiserror, serde_yaml_bw, base64, uuid, time, trybuild, rcgen, and

flate2.

Six updates in the same Dependabot group were not taken, because each

is semver-breaking (for a 0.x crate the minor is the breaking axis) and

none belongs in a routine refresh: russh 0.63, sha2 0.11,

portable-pty 0.9, age 0.12, fontdb 0.24, and

system-configuration 0.8. The group as Dependabot proposed it did not

compile at all — see the PR for the kem/ml-kem trait mismatch.

Neither refresh changes user-visible behaviour; the full frontend suite,

the Rust workspace suite, and the production build all pass on the new

versions.

Fixed

yanked from crates.io. Bumped to 0.10.2 (a patch inside the same

compatibility range). No functional change — the crate arrives

transitively through the SSH stack and Transit never names it.

Internal

8.2 warns that __dirname is unsupported by the configLoader: 'native'

mode slated to become the default in a future major, so this is the

forward-compatible spelling.

[6.5.2] - 2026-08-31

Added

or focus the handle and use the arrow keys (Shift for a coarser step);

double-click or press Home to snap back to the default 280px. The width is

clamped to 180px–50% of the window and remembered across restarts.

The fixed 280px rail truncated device names for anyone with a deeply nested

inventory — each level of grouping indents the row 12px, and a host:port

column holds a floor on the right, so a device three groups down had barely

a hundred pixels of name to work with. Reading the tree meant hovering rows

for their tooltips.

One width is shared by all five rail views (SSH, Terminal, Files, APIs,

PCaps) rather than one per view — the rail is a single column, and per-view

widths make the layout jump every time you switch surfaces. (Consolidating

on one default makes the PCaps rail 8px narrower than before at its default

width; every other view is unchanged until you drag.)

Changed

sidebar's, so both edges behave identically. The chat panel also picks up

the keyboard resize, the double-click reset, and the focus ring it did not

have before; its clamp (320px–70%) is unchanged.

[6.5.1] - 2026-08-30

Fixed

heartbeat with stat -f %m — BSD syntax. On GNU coreutils -f means

--file-system, so the read returned a multi-line filesystem report

instead of a timestamp and $((NOW - BEAT)) killed the supervising shell

with "Illegal number" on its first loop iteration, before it could reach

its own cleanup. Captures produced zero packets and reported only the

generic "nothing matched the filter, no traffic, or it failed to start".

Not a permissions problem: the unprivileged→pkexec elevation ladder was

working correctly the whole time. macOS and Windows were unaffected.

defaulted to ~/.local/share/Transit/captures, and Debian/Ubuntu confine

tcpdump with an AppArmor profile carrying audit deny @{HOME}/.*/** mrwkl

— an explicit deny, which in AppArmor beats every allow rule — so no file

could be created anywhere beneath a hidden folder in the home directory.

AppArmor mediates above uid, so this failed identically as root: the audit

record reads operation="mknod" denied_mask="c" fsuid=0. **The Linux

default is now ~/Transit/captures**, a visible folder the same profile

permits. macOS and Windows keep the locations they already used, and

nothing is migrated because a live capture could never have written to the

old path.

An unwritable output folder and an unusable interface both report

"Permission denied", and Transit treated both as "needs elevation" — so it

raised a pkexec prompt whose elevated retry then failed exactly the same

way. The user authenticated and still got an empty capture. Output-path

denials are now told apart from interface denials and reported with the

folder that refused, instead of being escalated to a prompt that cannot

help.

built --with-user=tcpdump, so a capture started as root drops to that

unprivileged user before writing; every -C rotation file after the first

is then created inside a directory owned by the invoking user and fails

with "Permission denied". Linux captures now pass -Z <user> so the files

land owned by the person who asked for them. macOS is unchanged — its

tcpdump does not drop privileges.

privileged branch returned its child without the fast-fail and stderr

check the unprivileged attempt already had, so a declined or unavailable

authentication surfaced as a mystery empty capture.

[6.5.0] - 2026-08-28

Added

another inventory device (jump_via, SecureCRT's "Firewall" concept):

Transit logs into the jump host with its own saved profile, opens an

end-to-end-encrypted tunnel, and verifies the target's host key through

it — the jump box never sees the target's password or traffic, unlike

hand-typed nested ssh. Chains up to 4 hops; per-hop trust prompts;

works for terminals and the Files (SFTP) pane; assignable in bulk

("Edit N devices → Jump host"); the AI agent's per-vendor command gate

adjudicates the *target's* policy through the tunnel. Imports now carry

ssh_config ProxyJump / SecureCRT Firewall Name into the field when

they match an imported or existing device.

bastion you trust and let git/ssh there authenticate with your local

agent (1Password's per-use prompt works as usual). Clearly warned in the

device dialog; deliberately excluded from bulk edit and settings

bundles; live sessions keep their connect-time setting.

Security

rejected** unless the device opted into agent forwarding (the bundled

SSH library's default would have accepted them); threat-model entries

T52 (jump hosts) and T53 (agent forwarding) added.

[6.4.0] - 2026-08-26

Added

existing .deb. Built on almalinux:10 with EPEL, whose older glibc means one

package covers EL10 and every live Fedora. On EL10, enable EPEL first — it is

the only Enterprise Linux source of webkit2gtk4.1; Fedora has it in base.

EL9/RHEL 9 is not supported (no webkit2gtk4.1 in EL9 or EPEL 9, and

libsoup2/libsoup3 cannot coexist in one process). Like the .deb, the .rpm

has no in-app auto-update — updates are download-and-reinstall.

top-level tab. Splitting was previously one-way: closing the pane was the only

way out.

terminal the button bar and Clear Terminal will act on.

Fixed

fired into the tab's primary (left) pane regardless of which pane held the

cursor, and the post-send focus hand-back then dragged the cursor there too.

Both now follow the focused pane. Reported by a customer on Windows.

instead of the focused pane. Same root cause as the button-bar bug.

in a split tab.

[6.3.1] - 2026-08-24

Changed

providers.

Fixed

internal threshold that decides when the AI stops to ask whether to keep

going was miscalibrated for some models, so chats could stop short of

where they should have. This threshold is internal and is never shown in

the app.

[6.3.0] - 2026-08-21

Added

history": your open AI chats come back after a restart — transcript,

model, and tab name included. Off by default; when on, each chat is

saved to a folder you choose after each turn (turns you stop midway

included), passes Transit's redaction filter again on the way to

disk, and closing a

chat deletes its file. Restored chats always come back with fresh

approval state: command auto-approvals, device scopes, and API

auto-approve never persist.

"Save code blocks to file": every code block the AI writes gets a

Save button. Saving always opens the system save dialog — you pick

the destination each time (starting at a folder you choose), and the

AI itself has no way to write files: the button click is the entire

authority, and the app never marks a saved file executable.

Cmd/Ctrl-click to toggle) → right-click → Edit N devices…, or

right-click a group folder → Edit all in group — one dialog changes

vendor, auth profile, accent color, bold accent, syntax highlighting,

quick copy/paste, and terminal font across the whole selection. Every

row defaults to Leave as is, so only what you pick changes, and the

batch is all-or-nothing: if any device fails, nothing is written.

swatch backed by the OS color picker — any #rrggbb, beside the seven

theme-aware presets (a custom color is the same in light and dark; the

presets keep adapting). Button-bar buttons accept custom colors too.

inserts a new line (⌘/Ctrl+Enter still sends, as before). The new

Settings → Agent Chat tab hosts the toggle for anyone who prefers

the old ⌘/Ctrl+Enter-only mode for hand-typed multi-line prompts.

Fixed

agent.** On Linux desktops, "start one with eval $(ssh-agent -s)" hid

the real problem — GNOME Keyring, systemd's ssh-agent socket, and

gpg-agent all compete for SSH_AUTH_SOCK. The hint now points at the

durable fix (mask the competing user services and pin the agent socket

in environment.d, then re-login), documented in

docs/security/secrets.md under "Linux: agent contention".

[6.2.1] - 2026-08-20

Fixed

Shell discovery version-probes every candidate it finds on PATH, and on

a Mac without the Xcode Command Line Tools, /usr/bin/python3 is Apple's

installer shim — merely running --version on it pops the OS "install

the command line developer tools" dialog. Discovery now asks

xcode-select -p first (which never triggers the dialog) and skips the

shim entirely when the tools aren't installed; a real Python elsewhere on

PATH still appears in the launcher.

[6.2.0] - 2026-08-19

Added

controller dialog (auth pre-filled for classic Authorization: Token <key>

tokens; NetBox 4.4+ nbt_… v2 tokens use Bearer — the dialog hint covers

both) and a bundled, curated investigation collection: ~31 GETs across

Circuits / Devices / Sites / IPAM, generated from NetBox's own OpenAPI

schema by scripts/gen-netbox-collection.mjs, which validates every path

and filter param against the spec. Includes the circuit-outage walk

(circuit → terminations → devices at the site → interfaces → IPs) and the

everyday lookups ("who has this IP?", "prefixes containing", devices by

site/role/tag/search). The AI agent reaches NetBox through the same

structurally GET-only, host-pinned propose_api_call as every API session.

Setup + worked example: docs/integrations/netbox.md.

non-secret text to the key in the header value —

auth = { scheme = "api_key", header = "Authorization", value_prefix = "Token " }

is the NetBox classic-token shape, and the same field serves any

Authorization: <Word> <key> API. Existing sessions are untouched: an

empty prefix sends the bare key, byte-identical to before, and the field

is omitted from the TOML when empty.

beside SecureCRT/MobaXterm/CSV: pick your NetBox API session, and Transit

pages the device list (read-only, through the same host-confined client)

and diffs it against your inventory on a stable per-device NetBox id —

New devices import through the standard review grid (per-row

vendor/group/auth, bulk edit, collision handling; site → group,

platform → vendor with BYOP fall-through, tags + role carried);

Changed devices offer per-field accept/skip for host/vendor/group

drift; Stale rows (gone from NetBox) default to Keep, with explicit

per-row Unlink or Delete — deletes are re-confirmed by name before the

one atomic commit. Nothing is ever written to NetBox, nothing syncs on a

schedule, and the AI agent has no path to any of it (threat-model T49).

Fixed

notes: HTML comments in this file are now stripped from every published

copy of the release notes (the v6.1.1 notes on the downloads page rendered

one as visible text; the live copies were scrubbed).

tags (as NetBox-synced devices are) squeezed its own name down to a

sliver. The name and host get the full row; the tags remain in the row's

hover tooltip and in tag filtering.

selects, the PCaps interface picker, the NetBox sync auth picker) now set

an explicit text color — WebKitGTK doesn't cascade the app's color into

form controls, which rendered them white-on-white in light theme and

near-invisible in dark.

[6.1.1] - 2026-08-15

Added

driven by 2026-08-14 live testing across cloud and local models):

the session roster shows how much scrollback each session holds

(scrollback: empty means run a command first); command results say WHY

their capture ended — capture="silence" warns that a quiet device may

still be producing output (no more invented ping results), with timeout

and session-closed variants; refusals teach the next move (policy

denials open with "Transit's policy gate denied this command — the device

never received it" and point at the vendor's policy section, so a refusal

is never mistaken for device behavior; context-overflow errors say how to

recover); read_scrollback

gains a match filter (literal substring + context lines + an honest

total_matched, including 0 = appears nowhere) so investigations stop

re-reading whole rings; pruned-history breadcrumbs name the session,

device, and command they replaced; and every built-in vendor policy now

carries a phrasebook — known-good command forms in that vendor's own

syntax, rendered into the assistant's instructions and build-tested so

every entry passes that vendor's policy gate.

Changed

session listing, the assistant's prompt, and every command/read result now

use a short, stable per-chat alias; results are also stamped with the

device they actually came from (<session id="s1" device="R4">), and the

assistant's session roster shows how many commands have executed on each

session this chat — so "which devices have I actually checked" is a fact

in front of the model, not a memory it has to keep. Long internal ids are

still accepted if a model (or an old transcript) sends one. Driven by

2026-08-14 live testing: local models mangle 36-character session ids

under multi-session load.

env TRANSIT_TURN_TOKEN_CEILING) caps how many tokens the assistant may

generate in a single response, ending runaway responses that previously

streamed until a manual Stop. Applies to cloud and local models; local

models keep their existing half-context-window clamp (the smaller wins).

[6.1.0] - 2026-08-13

Added

Mono.** Pick either in Settings → General; no install required, and they

look identical on every machine. On macOS this is the only way to use a

font Apple didn't ship: the system web engine refuses fonts you install

yourself, which is why a font you can see in other apps never appeared in

Transit's picker.

preferences and saved connections to one file you can carry to another

machine. Passwords are never included — they stay in your OS keychain —

and neither are host-key fingerprints, so the new machine still verifies

each device itself the first time it connects.

command policy, instead of a sample you had to install yourself. Because

a UniFi device gives you a Linux shell rather than a fixed vendor CLI,

every AI-proposed command needs your click — the "always allow" shortcut

is deliberately unavailable for UniFi devices.

Ctrl+Shift+C and Ctrl+Shift+V. Plain Ctrl+C still interrupts the running

command, as it always has, even when text is selected.

Window → Sort Tabs Alphabetically. The Window menu also gains

Jump to Session…, which opens the command palette (Cmd/Ctrl+K) where

every open session is listed by name.

Choose "AI prompt" when creating a button and its text lands in the chat

box for you to review and send — a saved-prompt palette next to your

saved-command one.

connect. A new Ask me each time (interactive / MFA)** option on an auth

profile stores nothing: Transit relays the device's own login prompts, you

answer them, and what you typed is used for that one connection and then

discarded. No keychain entry, no file, nothing to leak from a stolen laptop.

This is also the first Transit release that can sign in to gear behind

multi-factor authentication — TOTP, RSA and Duo codes, and PAM /

CyberArk account-selection menus. Those challenges change every time, so a

saved password could never answer them; until now those devices could not

be reached at all.

The prompt shows exactly which user@host:port is asking and quotes the

device's own wording separately from Transit's, so a device cannot dress

its prompt up as one of ours. Fields mask or show according to what the

device asks for, so a menu choice stays readable and a password never does.

Devices set to interactive sign-in are skipped by Launch all — each one

needs you at the keyboard — and are reported in the launch summary instead

of stacking up dialogs.

Changed

tab.

Removed

to warn that keystrokes could act on a TUI the terminal had failed to

paint — a rendering problem that no longer happens. What was left was a

banner that appeared every time you opened nano.

so a card promising a future opt-in toggle for it only raised the

question it was meant to answer.

[6.0.2] - 2026-08-12

Changed

Every open session is a valid target, and an ask that spans sessions ("is

BGP healthy on these sessions?") means investigating each relevant one

before concluding. Cloud models already behaved this way — verified

unchanged — so this aligns the written contract with the expected

behaviour, which matters most for local (BYOM) models that tended to stop

at a single session. One-time note: this refreshes the assistant's cached

prompt once per user on first use after updating.

[6.0.1] - 2026-08-10

Fixed

shipped the sixth tool (query_capture) but the assistant's instructions

still said it had exactly five tools, never described what query_capture

does, and never listed the captures you had open — so models sometimes

ignored an open capture or fumbled the first query. The instructions now

describe all six tools, and any open capture is named in the assistant's

view of your workspace (with [pcap] agent_access = false still removing

it entirely).

carry a kind (ssh / console / api) in the assistant's session

roster and in list_open_sessions, so it can reliably pick

propose_command for SSH/console sessions and the GET-only

propose_api_call for API/controller sessions — previously it had to

guess from the vendor, and a UniFi gateway reachable both ways made that

a coin flip.

output of an approved propose_command reaches the model wrapped in the

same <session id> tags as scrollback reads, closing a defense-in-depth

gap the 2026-08 prompt-contract review found (the policy gate + approval

modal were, and remain, the primary control). Capture answers were

already framed; the assistant's injection guard now explains both

framings.

[6.0.0] - 2026-08-08

Added

goes, and reproduce a problem — then send us the file. Useful when something

fails on a machine we cannot get to, which is most of them. Off unless you

turn it on, keeps a week of daily files so it cannot fill a disk, and the tab

states plainly what is never written to it: no passwords, keys or tokens, no

host keys, no terminal output or command text, no packet contents, and

nothing exchanged with an AI model. It records that an operation happened and

whether it failed — not the data it carried.

PCaps — captures traffic from a network interface on your machine and

opens any .pcap, .pcapng or .pcap.gz file for analysis, as a tab

beside your SSH, console, API, local-shell and file-transfer sessions. Pick

an interface, optionally set a capture filter, and press Start; or open a

capture someone sent you. While it records, the sidebar shows how much has

been written and for how long — and says so plainly when a capture has been

running a while and written nothing, which is what a filter matching no

traffic looks like.

The explorer gives you three resizable panes — packet list, field tree, and

bytes — with a view filter in Transit's own syntax

(tcp.port == 443 and ip.src == 10.0.0.0/24 and dns.rcode != 0) that

validates as you type. Alongside them, an analysis drawer with

Findings, an overview digest, conversations, and a protocol breakdown.

Findings are the part worth knowing about. Transit computes them from

the capture rather than inferring them: MTU black holes, retransmission

rates per conversation, zero-window stalls (with how long the sender was

stalled), connections that were *refused* as distinct from ones that got no

answer at all, duplicate IP addresses claimed by two MACs, DNS failure

rates and unanswered queries, fatal TLS alerts, HTTP server errors,

cleartext credentials crossing the wire, and routing loops. Each one comes

with a one-click filter that shows you the evidence.

And the assistant can read the capture. Ask it why a transfer is slow,

what broke a TLS handshake, or which host is retransmitting, and it will

work through the same analysis you can see. It reads dissected fields and

computed summaries — never packet payload, which is not something it can

ask for. A single config flag ([pcap] agent_access = false) keeps the

explorer and turns off the assistant's view of it, for anyone who wants

packet analysis without the AI reading their traffic.

Transit ships no capture driver: it drives the capture tool your operating

system already has (tcpdump on macOS and Linux, pktmon on Windows). If

your machine already permits packet capture — as it does if you have

Wireshark installed — you will not be asked for a password at all.

Captures are bounded by size, file count and duration, so one you forget

about cannot fill your disk, and a Headers only option records enough

for flow and protocol analysis while capturing no payload whatsoever.

The capture folder is shown in the sidebar and opens in your file manager

with one click, and Settings → General → Capture folder moves it

somewhere with more room.

Set [pcap] enabled = false in config.toml to remove the surface

entirely.

[5.0.0] - 2026-08-04

Added

SecureFX-style dual-pane file browser against the devices already in your

inventory: your machine on the left, the device on the right, as a tab beside

your SSH, console, API and local-shell sessions. It rides the inventory you

already have — same groups, tags and per-host colors in the sidebar, same auth

profiles, same host-key trust prompt and weak-crypto opt-in — so opening file

transfer to a device you can already reach is one click ("Open file

transfer"), including "Launch all" across a multi-selection or a folder.

Browse either side with sortable columns, a hidden-files toggle, an editable

path bar that always shows the path the server actually resolved, multi-select

(click / Cmd-click / Shift-range), and directories of ten thousand entries

that still scroll smoothly. Create folders, rename, refresh, and delete —

deletes are permanent and a folder delete says exactly what it will take with

it.

Transfers go both ways, with a live queue at the bottom of the pane:

per-file progress, transfer speed, time remaining, which file a recursive copy

is on, and Cancel on anything still queued or running. Four ways to start one

double-click a file to send it to the other pane, the toolbar arrow (or

right-click) for a whole selection, drag rows between the panes, or **drag

files in from Finder / Explorer** to upload them. Folders copy recursively,

modification times are preserved, a cancelled download cleans up its partial

file, and anything deliberately skipped is reported with a reason instead of

quietly disappearing. When something already exists at the destination Transit

asks once for the whole batch — Overwrite all / Skip existing / Cancel —

never file by file. Closing a tab or quitting mid-transfer asks first; an idle

browse session never nags. If the link drops, the tab keeps both folders and

offers Reconnect in place.

It is a free, human-only surface: the AI agent is structurally blind to

it — there is no file tool (the tool surface stays at five), the Files session

state is wired into none of the agent's session seams, and the new

transit_files crate is banned outside the app binary at the dependency-graph

level, so no future refactor can quietly hand the agent a filesystem.

Filenames the device sends are validated before they can influence a path on

your disk, and a recursive download never follows a symlinked directory on the

device. A [files] enabled = false config switch removes the whole surface for

locked-down / MDM deployments, which doubles as a DLP answer. SFTP today (on

Junos, enable set system services ssh sftp-server if it isn't already); SCP

for SFTP-less gear is designed as a fast-follow on the same queue.

New transit_files crate (russh-sftp); threat-model T43.

[4.4.0] - 2026-08-04

Added

— next to SSH and APIs, opening a real local shell (zsh / bash / fish /

PowerShell / cmd / WSL / python·node REPLs) in a PTY, as a tab alongside your

SSH and console sessions. The launcher **discovers the shells installed on your

machine and shows their versions ("look under the hood"); click one (or +**

for your default) to open it. Full terminal experience — keystrokes, real

window resize, clear-terminal, multiple tabs, session logging/export, and a

close-confirm on a live shell. When a shell exits, **press Enter to start a new

one in place** (scrollback preserved).

It is a free, human-only surface — the AI agent is structurally blind

to local shells (it can never see or run commands in them). A

[terminal] enabled = false config switch removes it entirely for

locked-down / MDM deployments. New transit_localpty crate (portable-pty);

threat-model T42.

panes side by side or stacked, nested to any depth (like Windows Terminal /

tmux) — across SSH, serial console, and local-shell sessions. Built on a

PaneNode layout tree (react-resizable-panels); closing a pane never resets

an untouched pane's scrollback.

an edge — left/right tiles beside, top/bottom tiles below. The edge

drop-zones highlight as you drag, and the dragged session (SSH or local shell)

moves into that tab's grid. Any pane is reachable, so you can fill a full grid

from separate tabs.

Changed

(package-lock.json's root + packages[""], and src-tauri/Cargo.lock's

workspace crates) alongside the three declared version files, so a release

bump can no longer leave a stale lock for CI to catch later. No user-facing

change.

[4.3.1] - 2026-08-03

Security

GHSA-m65r-rprj-r5rg. Transit was not exposed to that advisory — it

affects russh's *server* side (a server accepting channel callbacks for a

channel id it never opened) and Transit is only ever an SSH client, so no

Transit release could reach the vulnerable path. Updated anyway, because

shipping a dependency with a published advisory isn't worth the explanation.

The release also adds backpressure to the channel write path, which *is* the

path Transit uses to send your keystrokes.

Fixed

controller host meant Transit tried 443 and failed with a bare `HTTP

transport error`, which reads like a broken controller. A refused connection

on the implicit 443 now answers the actual question — *"nothing is listening

on unifi.example.com:443 — did you mean unifi.example.com:8443?"* — and a

silently dropped one names the other likely cause (firewall / cloud security

group / VPN, and that Transit connects directly and ignores any HTTP proxy).

An explicitly typed port is never second-guessed, and a self-signed

certificate still routes to the trust-the-fingerprint prompt rather than this

hint.

Network API surface is now "Self-hosted controller" in the controller

dialog (and "Self-hosted" in the APIs sidebar). The three UniFi surfaces

differ by whether traffic is relayed through api.ui.com, not by whether the

controller is on your LAN — so a Network Application running on a cloud VM

(Azure, AWS) always belonged here, but the old label and its two LAN example

addresses read as on-link-only. The host field now says so outright and names

the port that trips people up (:8443 for a self-hosted Network Application,

443 for UniFi OS consoles). No change to the stored network_local kind —

existing controllers are untouched.

[4.3.0] - 2026-08-01

Added

Cisco Meraki, Juniper Apstra, HPE Aruba Central, **Cisco ACI

(APIC), Cisco Catalyst SD-WAN (vManage), FortiManager**, or

FortiAnalyzer and Transit drops in a curated, investigation-focused

request collection — 447 endpoints across the seven, derived from each

vendor's official Postman export and named for the calls a network engineer

actually makes (device + uplink status, clients, health, interfaces, events,

rogue APs, fabric anomalies, control connections…). Pick the vendor and its

base URL + auth scheme are pre-filled; where a key is used it's stored by

reference in your OS keyring and injected at send time, exactly like UniFi —

the host stays pinned to the controller.

AI agent can drive it too — GET-only and host-pinned, as always.

Login credentials for the auth scheme and store the username +

password once, then run "Log in first" — Transit fills the credentials

into the login request at send time and captures the returned session

token into a variable automatically, and the rest of the collection

carries it for you. Your password is read from the OS keyring (or

1Password / an env var) inside the app's backend and is never handed to

the UI, so it can't be read out of the window or left on disk. These are

human-first; the agent can ride a still-valid session when a static token

is configured.

the "what do I have?" calls that yield the ids everything else asks for —

Meraki's organizations / networks / devices / switch stacks, Aruba's

groups + guest portals, Apstra's config templates, SD-WAN's vSmart

policies — so you're never stuck with a request that needs an id you have

no way to look up.

endpoint), bundled for your use — the GET-only agent structurally

can't call them.

The collections are a human convenience: the agent stays GET-only and

host-pinned regardless of collection content, and you can edit, extend, or

import your own alongside them.

Security

written to disk.** Variables named like a credential (password,

client_secret, …) are hidden behind a reveal toggle, held in memory for

the session only, and carry the same "session" badge as a captured login

token. Any such value a previous build had persisted is purged the next time

Transit starts (rewritten out of local storage, not just ignored).

is an error rather than a substitution, for every controller regardless of

how it authenticates — a credential in a URL would be recorded verbatim into

the session history the AI agent can read, and into the controller's own

access log.

Fixed

collection's paths were written absolute (/organizations/…) while the

Meraki base URL carries an /api/v1 prefix; an absolute path replaces the

base path, so the host-pinning check refused all 167 requests — for the

Postman client as well as the agent. Paths are now relative, matching the

UniFi local collections, and a test now resolves every path in every bundled

collection against its controller's base so this can't recur.

literal <string> placeholders instead of variables, so it posted the text

<string> and failed to authenticate.

variables.** It listed a fixed UniFi set on every controller, so Meraki's

{{organizationId}} — the id nothing works without — wasn't there at all.

The menu is now built from the open controller's own collection, and no

longer requires a variable to already have a value before it can be set from

a response.

went out with no session cookie, so every agent call against ACI, SD-WAN,

Apstra or Aruba came back 401/403 while the same call worked in the Postman

client. The agent now rides the session you established — it still

cannot log in itself (that's a POST, and the agent is GET-only), so if the

controller's token expires, re-run "Log in first" and it picks straight back

up — and because APIC's token refresh is itself a GET, the agent can keep

its own session alive. Meraki was never affected.

{{password}} variables (they previously differed per vendor), so the

credential handling above applies uniformly.

[4.2.0] - 2026-07-31

Added

now organized into a settings-style left-nav (Connection / Organization /

Appearance / Terminal), and Appearance gains a per-device terminal font

(family + size, overriding the global font for that device's sessions only)

and a Bold accent toggle that renders the device's color as a louder

background tint on the session tab — not just the thin edge — so a prod box is

unmistakable at a glance. All optional and stored per-device in your inventory

(they travel with transit.toml). (Requested by Jeff Kish.)

collections of saved requests you build yourself — expand a controller in the

APIs sidebar to New collection, Save the request in the builder into

one (name it, pick or create the collection), and click a saved request to

reload it. Import Postman brings in an existing Postman v2.1 collection

(folders and all); auth headers are stripped on the way in and a saved

request never stores the API key (it's injected for you at send time).

Collections persist locally, per controller. (Part of v4.0.0 UniFi API

support.)

sessions**. Open a controller and the agent immediately sees the session —

it reads the request/response history (redacted) via list_open_sessions /

read_scrollback, and can propose read-only GET requests without you

having to send anything first. Each GET passes a GET-only, host-pinned gate

and then an approval modal you click — or you can **opt into auto-approving

GETs** for a chat (the gate still runs on every one). It can never send a write

(POST/PUT/DELETE), reach any other host, or see the API key; its GET and

the response land in the controller's history for you to see. (Part of

v4.0.0 UniFi API support.)

controller with vendor Generic and a base URL, and Transit's Postman-style

tab + investigation agent work against any JSON/REST API — choose the auth

scheme (API key with a custom header name, Bearer token, HTTP Basic, or none).

The credential is stored by reference and injected server-side exactly as for

UniFi, and the host stays pinned to your base URL. http:// is allowed with a

warning (handy for local/dev gear) — prefer https over a network. The agent

is still GET-only and gated on generic controllers, with per-request approval

every time (no always-allow shortcut for a custom vendor).

API pane shows the full request/response log the agent reads — your sends plus

the agent's approved GETs — with a Copy button, so you can see exactly what an

investigation saw.

toggle; Headers lists the response's header set (name/value) and Copy copies

whichever view you're looking at. (Headers are a human-only view — they are

never sent to the AI agent.)

Adding or editing a controller is now a left-nav dialog (Connection /

Authentication / Organization / Appearance), and an accent color tints the

controller's session tab — so a client's production controller is unmistakable,

exactly like an SSH device.

the strip to reorder it; a plain click still just switches tabs. Split panes

keep their pairing.

color swatch (the same palette as per-host colors), and a colored button

renders with a subtle theme-aware background shade — group a "VOIP" set from

a "Routers" set at a glance, within a single bar. (Requested by Jeff Kish.)

Changed

Every id in a bundled request path — siteId, deviceId, and the rest, not

just consoleId — is now a {{variable}} you set once in the pane's Variables

bar and reuse across requests (right-click a value in a response → **Set

selection as variable** to fill it), instead of a single-brace {id} you had

to retype inline every time. And sending with a variable still unset now shows

a clear "Set a value for {{siteId}} before sending" prompt, instead of the

confusing "request path escapes the controller's API base" error (an empty

{{token}} was reaching the URL and being refused by the read-only security

gate). (Part of v4.0.0 UniFi API support.)

efficiently.** A big API response is now truncated intelligently — keeping

whole JSON items plus a "showing N of M — narrow with a query" note, instead

of chopping the body mid-structure into something the model can't parse — with

a larger 32 KB per-response budget. The agent is also guided to not re-read a

GET whose result it already has, to treat a 404 as "that path isn't on this

controller — don't retry it," and to look for a more specific endpoint rather

than re-fetching a summary. Together these help investigations on API sessions

converge instead of looping. (Part of v4.0.0 UniFi API support.)

keystrokes could act on an unpainted UI) now **stays dismissed for the rest

of the session** once you close it, instead of re-appearing every time a

full-screen tool re-opens. The warning still fires on the first entry per

pane — where the surprise lives — but a nano-heavy session is no longer

nagged on every open (the classic path to warning-blindness). A fresh tab

warns again. (Requested by Jeff Kish.)

Fixed

UniFi hostId/consoleId values are long hex strings, and the redaction

filter's bare-hex catch-all (meant to net raw secrets in terminal output)

was blanking them as [REDACTED], so the agent couldn't build follow-up

request paths. API (JSON) responses now pass those IDs through while every

key-labeled secret (WLAN PSK, SSH password, RADIUS/API keys) stays redacted;

terminal/CLI redaction is unchanged.

Security

controller's secrets never reach the model: credential fields are matched

case-insensitively and by shape (device SSH passwords, WPA passphrases, CA

keys, RADIUS/shared secrets are caught regardless of exact spelling), and

a value containing an escaped quote can no longer leak its tail. Humans

still see raw responses; redaction applies only on the path to the AI.

[3.3.1] - 2026-07-24

Security

0.61 → 0.62.4 (the SSH transport — GHSA-g9hv-x236-4qp3 / cqjc-rmpq-xprq /

5xvq-cp9x-6p6r), quinn-proto 0.11.14 → 0.11.16 (GHSA-4w2j-m93h-cj5j),

and brace-expansion 5.0.7 → 5.0.8 (GHSA-mh99-v99m-4gvg, build tooling).

No functional change — the russh bump was compile-, test-, and

live-smoke-clean.

[3.3.0] - 2026-07-24

Changed

Operator BYOK), replacing Claude Opus 4.8. Opus 4.8 is retired and

transparently aliased to Opus 5 server-side, so existing chats and older

builds keep working with no interruption. Pricing is unchanged ($5/$25 per

MTok); tier budgets and ceilings are unaffected.

[3.2.1] - 2026-07-23

Added

Compare captures / diff output… opens the capture/diff dialog with that

tab's session pre-selected. It's the same tool that's always been in the

command palette (Cmd/Ctrl+K) — now discoverable without knowing the palette.

[3.2.0] - 2026-07-23

Added

theme-aware palette (Add / Edit device → Accent color). The color shows

as a left-edge accent on the sidebar row, the session tab, and the terminal

pane — a quick "am I on prod?" cue. Optional; devices with no color are

unchanged, and the palette adapts to the active theme's light/dark mode.

(not just the current one), shows a live match counter (e.g. 3/17),

and searches the full 32K-line scrollback the terminal retains — no longer

capped at the front 10K lines.

file…** streams that session's output to a file you pick, each line

timestamped (UTC); a red dot marks a logging tab and Stop logging ends

it. Output is redacted at the write boundary (best-effort, per chunk — like

scrollback export) so a log never captures a device secret in cleartext.

diff output** runs a command in an open session, saves its (redacted)

output, and diffs two captures — the same show run over time, or two

devices side by side — to spot config drift.

check") and run it against a session in one sweep from the Captures dialog —

each command's output captured for review or diffing. Human input, like the

broadcast bar (not policy-gated).

datacenter-3) in the Add / Edit dialog — orthogonal to the folder

hierarchy, shown as chips on the sidebar row. (Tag-based sidebar filtering

is a fast-follow.)

header of a serial-console session asserts a ~300ms serial BREAK to

interrupt a boot sequence or drop to ROMMON — the classic recovery move

that was previously impossible from the app. Console sessions only.

back in and Transit re-opens the dropped session automatically — same tab,

output resumes — instead of leaving a dead "ended" tab. A session you

closed yourself is never reconnected.

Changed

(View → Broadcast Input) was red; it now uses the brand's Transit Blue to

stay on-brand with the rest of the app. The destructive "Interrupt all (^C)"

button keeps a red accent as a blast-radius cue, and the live

"Sending to N of M" device count remains the primary safety indicator.

character-width tables, so CJK text, box-drawing, and emoji no longer drift

columns out of alignment.

this build doesn't recognize (usually a file written by a newer Transit),

the loader now tells you to upgrade Transit instead of showing a bare serde

"unknown field" error.

[3.1.0] - 2026-07-22

Added

add your own Anthropic or OpenAI API key and chat with the same

Sonnet 5 / Haiku 4.5 / GPT-5.6 Terra / GPT-5.6 Luna lineup Operator

includes — billed to your provider account, proxied through Transit

Cloud with the same policy gate, approval modal, and redaction as every

cloud model. The model picker now renders BYOK-unlocked models on tiers

with no bundled cloud models, shows a "Cloud — unlock with your API

key" hint listing what a key unlocks, and the empty chat state offers a

one-click jump to Settings → BYOK. (Requires the Transit Cloud rollout;

Opus 4.8 / GPT-5.6 Sol remain Operator-and-up BYOK models.)

131,072- and 262,144-token context windows (matching the backend's

validated ceiling and Ollama's own settings range) — the previous UI

stopped at 65,536. The big options are labeled with a RAM/VRAM warning:

the model's KV cache grows with the window.

Changed

selection accents now use the brand's Transit Blue (#2A83FE) instead of

teal; the terminal cursor follows. Teal remains in the terminal's ANSI

bright-cyan slot, and the focus ring was already Transit Blue. Pick

"Transit Classic" in Settings → Appearance if you prefer the neutral

pre-refresh look.

[3.0.1] - 2026-07-21

Fixed

tier-gated BYOK + Local models tabs pushed the count past what the

horizontal strip could hold), the dialog clipped its right edge:

row controls (theme picker, font-size steppers) were cut off and the

About tab was pushed out of view entirely. Settings now uses a

left-hand navigation rail that scales with the section count; the

dialog is a fixed-size workspace and each section scrolls

independently, so the navigation always stays visible.

[3.0.0] - 2026-07-21

Added

endpoints.** Chat with models running entirely on your own hardware: the

agent's policy gate, per-command approval modal, and output redaction

apply to local models exactly as they do to cloud ones, and local

conversations never touch Transit's cloud. Zero-config loopback Ollama

support (tools-capable models are auto-detected and grouped under

"Local — your hardware" in the model picker), plus custom endpoints for

remote Ollama or OpenAI-compatible servers (vLLM, LM Studio, llama.cpp,

LiteLLM) — off this machine HTTPS is required, verified against the OS

trust store so enterprise-internal CAs work, with optional bearer tokens

stored write-only in the OS keychain. A cloud-signed offline pass keeps

local models working for up to 7 days without connectivity, so the AI

now works where the terminal always has: on-site, disconnected, and

air-gapped-adjacent networks. Configure under Settings → Local models

(available on every paid tier). Ollama's :cloud-tagged models are

deliberately excluded — they proxy inference through ollama.com, and

local means local. Transit refuses a conversation that would overflow

the local model's context window instead of letting it silently drop

its instructions.

[2.9.0] - 2026-07-15

Added

Transit_<version>_amd64.deb (x86_64; Ubuntu 24.04+ / Debian 13+)

alongside the macOS and Windows installers, hosted at

downloads.transitai.app with a stable

/download/linux-deb always-latest link and the same SHA256SUMS.txt

integrity story. In-app auto-update remains macOS/Windows-only — the

Tauri updater can't swap a .deb — so on Linux the update banner and

periodic checks are disabled and Settings → Updates links the downloads

page instead. Browser sign-in round-trips correctly into the running app

(the package ships a desktop entry that passes the transit:// callback

URL through to the app — Exec … %U).

[2.8.1] - 2026-07-15

Added

several connections with Shift-click (range) or Cmd/Ctrl-click

(toggle), then right-click → Launch all (N devices); or

right-click a group folder → Launch all in group to open every

connection under it, subgroups included. Tabs appear as each device

connects, a *Connecting… X of N* banner with a Stop button

tracks progress, and one failed device doesn't stop the rest —

failures roll up into a single summary toast. Connects run

sequentially so first-contact host-key prompts and legacy-crypto

approvals appear one at a time.

[2.8.0] - 2026-07-12

Added

preserved unchanged as a selectable theme (Settings → Appearance)

for anyone who prefers the original neutral look.

Changed

Default theme now wears the Transit AI brand palette: ink-black

surfaces with subtly raised panels, teal primary buttons, electric-

blue focus rings, and matching terminal accents (teal cursor, brand

blue/cyan ANSI colors). Applies only to the default theme — if you

picked any other theme it is untouched, and the old default lives on

as Transit Classic. The Max-tier account badge also trades

violet for teal (the brand retired purple).

path, so changing the username or passphrase no longer forces

re-browsing for a key file the profile already points at.

[2.7.0] - 2026-07-10

Added

VOIP bar and a routers-and-switches bar) and flip between them with

the new up/down arrows on the left of the button bar, or jump

straight to one by clicking the bar's name. Right-click the bar for

New / Rename / Delete bar. Your existing buttons carry over

automatically into a "Default" bar; with a single bar the strip

looks exactly as before.

(next to the model picker) restricts that chat's AI to the devices

you check, the same way the broadcast bar's target list works.

Scope a chat to the two switches you're debugging and the AI can't

see, read, or propose commands against anything else — enforcement

is in the Rust core, not just the UI, and a device you untick mid-

run is cut off immediately (even if an approval dialog was already

open). Default is unchanged: new chats see all devices. Pairs

nicely with multi-chat tabs — one chat per project, each scoped to

its own gear.

GPT-5.6 Luna (Easy), GPT-5.6 Terra (Medium), and GPT-5.6 Sol

(Advanced). Sol is included on Pro and Max; on Operator it unlocks with

your own OpenAI key (BYOK), the same way Opus 4.8 does with an Anthropic

key. GPT-5.5 and GPT-5.4 mini retired — existing chats and stale

selections are served transparently by the closest 5.6 successor, and

the picker refreshes automatically.

[2.6.3] - 2026-07-09

Added

adapting pasted config templates before they're sent — swap a hostname,

VLAN, or IP across dozens of lines without leaving the confirm step.

Open it with the Find & replace button or Cmd/Ctrl+F while the

dialog is up. Matching is literal (no regex), with a live "2 of 17"

match counter, Match case and Whole word toggles (whole-word

treats / . : - as boundaries, so replacing 0/0/1 doesn't also

hit 0/0/10), Enter / Shift+Enter (or F3 / Shift+F3) to step through

matches, and Replace / Replace all with a one-click Undo.

Escape closes the find row first, the dialog second. The dialog is

wider and the editor no longer soft-wraps long config lines (it scrolls

horizontally instead). The safety property is unchanged: what you paste

is exactly what's sent — edits, replacements and all.

[2.6.2] - 2026-07-07

Added

changes since the last connect (re-image, RMA, firmware re-key), Transit

shows a changed-key warning dialog with the pinned and new fingerprints

side by side instead of a dead-end error that pointed at hand-editing

known_hosts.toml. Replacing the pin takes two deliberate steps — tick

"I've verified this key change is legitimate", then the red

Replace & connect — and the pin is rewritten only after the

connection also authenticates, so a failed login never displaces a

good pin. Declining (or any attempt to dismiss the dialog) leaves the

old pin untouched and fails the connect with the familiar mismatch

error. There is intentionally no "remember" shortcut: every key change

gets its own confirmation.

[2.6.1] - 2026-07-07

Added

Anthropic key enrolled — the model runs on your own key, so it's

available without upgrading. The chat model picker shows Opus only

when BYOK is active for Anthropic; a hint points at Settings → BYOK

otherwise. Turning BYOK off (or clearing the key) mid-chat switches

the chat back to Sonnet with a notice, and a cloud rejection now

reads "Opus needs your own Anthropic key" instead of a generic

plan error. Requires the matching cloud release.

[2.6.0] - 2026-07-07

Added

the cloud's trial block; a bottom-left banner shows "N days left in your

trial" with an Upgrade Now action, and Settings → Billing gains a trial row +

Upgrade Now. Inert while the cloud's TRIAL_ENABLED flag is off — no UI

change for current users.

Changed

stack in a single column that packs toward the corner — no more floating

gaps when one of them is dismissed or snoozed.

[2.5.0] - 2026-07-06

Added

chats at once — a tab strip with a + button (also ⌘/Ctrl+T or the

command palette's "New chat"), each tab its own conversation running its own

agent loop. Double-click a tab to rename it; the model picker is per-chat.

Chats keep running in the background — a long agent task in one tab keeps

going while you work in another, or even while the chat panel is collapsed.

surfaces a stacking, clickable card (bottom-right) and a tab dot

amber when it needs command approval, green when its task finishes. Click

the card to jump straight to that chat. Approval always happens in that

chat's own modal (never a stolen pop-up), so two chats needing approval at

once can't collide.

unfocused tab raises a notification card.

[2.4.0] - 2026-07-06

Added

(SecureCRT-style). Enable it from View → Broadcast Input: a bar appears

at the bottom where a line you type is sent to every open session

simultaneously (press Enter). It targets all live sessions by default, with

a selector to exclude specific ones (e.g. a production box) and a live

"Sending to N of M" device count. A mouse-only Interrupt all (^C) button

sends Ctrl-C to every target — normal Ctrl+C in a terminal still goes only

to that one session. The bar is deliberately loud and red: it's human input

going to many devices at once, so the visible count is your confirmation.

Fixed

strip scrolls.** After opening enough sessions for the scrollable tab

strip's arrows to show (v2.3.4), the whole workspace could shift a few

pixels left — clipping the first character of the sidebar entries, the tab

labels, and the terminal prompt (e.g. AZ104-SW06-22> showed as

Z104-SW06-22>). Cause: the tab strip's "keep the active tab visible"

logic used scrollIntoView, which scrolls *every* scrollable ancestor;

combined with a stray pixel of horizontal overflow in the shell layout, it

nudged the entire app sideways. The reveal now scrolls only the tab strip

itself, and the layout is hardened so nothing but the tab strip can scroll

horizontally. (Previously the only workaround was toggling the button bar

off and on, which reset the scroll.)

[2.3.5] - 2026-07-05

Changed

switch firmware builds emit a key-exchange field that isn't valid

ASCII/UTF-8 (which the SSH standard doesn't permit), causing the

handshake to fail before any connection can be negotiated. Transit now

reports this as an actionable message pointing at a device firmware

update, instead of a cryptic low-level "character encoding invalid"

error. There is no in-app workaround — the malformed data arrives before

Transit can act — so a firmware update on the device is the resolution.

[2.3.4] - 2026-07-05

Added

menu disconnects every open session and clears the strip in one action,

with a single confirmation summarizing how many are still connected (or

no dialog at all when every tab has already ended). Requested by a user

running dozens of switch sessions at once.

chevron buttons appear (MTPuTTY-style) to page through them; the active

tab always scrolls into view, and trackpad/horizontal-wheel scrolling

works too. Previously the strip clipped tabs off the right edge.

horizontally scrollable row with the same chevron affordance, instead of

wrapping into extra rows that ate terminal height.

[2.3.3] - 2026-07-04

Fixed

opt-in.** The legacy (weak-crypto) path now requests Diffie-Hellman

group-exchange bounds a 2048-bit-era server can satisfy (min/preferred

2048; previously russh's default min 3072). BDCOM-based FS.com campus

switches that offer only diffie-hellman-group-exchange-sha1 answered

the old request by disconnecting mid-handshake — the same error as

before the opt-in, so "Connect Anyway" appeared to do nothing. 2048-bit

GEX matches the group14-sha1 strength the legacy list already

accepts; the strict path keeps russh's defaults.

Changed

device refuses the SSH handshake with a protocol-level disconnect

message, Transit surfaces that text (sanitized, length-capped) in the

connect error instead of a bare "server disconnected during handshake"

— so the error names the algorithm slot the device couldn't match,

whenever the device says so.

error no longer advises "allow weak crypto when prompted" (it can only

appear after weak crypto was already allowed); it now explains that the

device refused even the legacy algorithm set and points at device SSH

settings/firmware or a firewall/ACL.

[2.3.2] - 2026-07-04

Fixed

started showing the weak-crypto prompt for switches that drop the SSH

handshake (Cisco SG300/SG500, FS.com S5500), but the retry still failed with

"handshake … interrupted before algorithm negotiation completed (key exchange

init failed)." The cause was key-exchange preference: the legacy algorithm

list offered Diffie-Hellman group-exchange before the fixed groups,

and these switches answer a group-exchange request with a 1024-bit modulus —

below the 2048-bit floor our SSH library enforces — so the exchange failed (or

the switch dropped the connection) every time. Transit now prefers the

fixed-group group14-sha1/group1-sha1 exchanges (which these switches also

advertise) over group-exchange on the legacy path, so the opt-in completes the

handshake. Weak crypto is still never used without the explicit per-device

prompt, and the strict default handshake is unchanged.

[2.3.1] - 2026-07-03

Fixed

The Transit menu carried macOS-only Hide / Hide Others / Show All items on

Windows and Linux, where they have no equivalent — on Windows, "Hide" hid the

window with no Dock, tray, or "Show All" to restore it, so Transit kept

running invisibly and only Task Manager → End task recovered it. Those three

items are now macOS-only; on Windows/Linux the Transit menu is **About +

Exit**, and you minimize/restore the window the normal way. (Thanks to the

customer who reported this on Windows Server 2019.)

[2.3.0] - 2026-07-03

Added

sidebar — the empty area, a device, or a group folder — and choose

Export sessions… to save every connection to a CSV. The file uses the

same columns Transit imports (`name,host,port,username,vendor,group,

key_path`), so it round-trips: export from one machine, import on another

(or back up your inventory). As with import, **secrets are never

exported** — the CSV carries only usernames and key-file paths, never a

password or key passphrase.

Fixed

works.** Some older gear — Cisco SG300/SG500 small-business switches,

FS.com S5500 switches — drops the SSH connection during the handshake

instead of negotiating, because it offers only SHA-1 key exchange

(diffie-hellman-group1-sha1, diffie-hellman-group-exchange-sha1) or

ssh-rsa host keys. Transit used to surface this as a dead-end "Key

exchange init failed" / "Disconnected" error with no way forward. It now

recognizes it as a possible legacy-crypto requirement and shows the same

per-device weak-crypto opt-in prompt used for other legacy devices —

approve it (optionally "remember for this device") and the connection

retries with the legacy algorithm set. Weak crypto is still never enabled

silently, and a genuinely unrelated failure surfaces its real error after

the retry rather than being masked.

item did nothing on Windows (it worked fine on macOS). It now opens the

About page (Settings → About) with the version and license. macOS keeps

its native About panel.

[2.2.7] - 2026-07-02

Added

(sidebar → Import, or ⌘K → "Import connections…") now reads MTPuTTY

server lists (mtputty.xml) and MobaXterm bookmarks (MobaXterm.ini

or a .mxtsessions export) alongside SecureCRT, OpenSSH ssh_config,

and CSV. Hosts, ports, usernames, folder hierarchy, and key-file paths

come across; SSH sessions import, and anything else (telnet/RDP/VNC/

serial, or MTPuTTY entries whose details live in a PuTTY saved session

in the Windows registry) is listed in the preview as skipped so nothing

disappears silently. As with every import source, **stored passwords are

never read or decrypted** — they stay in the source app, and you map

each deduped login to a Transit auth profile once.

Changed

the workspace.** Previously, a signed-in account with no active plan saw a

full-screen "Subscribe to use Transit AI" panel in place of the entire app.

The workspace (terminal, sessions, inventory) now always renders; the

subscribe prompt lives inside the chat panel, since only the AI assistant

requires a plan. Use Transit as a standard SSH/serial terminal at no cost.

[2.2.5] - 2026-07-01

Security

read-only command gate: it now denies native output redirection

(> / >>), catches a blocked pipe stage even when it is hidden behind

a quote (network CLIs don't parse shell quoting the way the gate's

allow-matcher does), tightens NX-OS | sort (write/exec flags),

backports the Cisco/Arista show tech-support <destination> block from

IOS-XR, and blocks Junos monitor … write-file. Every agent-proposed

command already requires explicit per-command user approval (Rule 3);

these refinements harden the automated gate that runs ahead of it.

redaction filter to more credential shapes: IPsec pre-shared keys

carrying an encryption-type token (`pre-shared-key local|remote 0|6

<psk>), modern OpenAI project keys (sk-proj-…`), SNMP community strings

on snmp-server host trap targets, credentials embedded in

connection-string / URL userinfo (scheme://user:PASSWORD@host), HTTP

Basic Authorization headers, and wireless/WPA pre-shared keys.

reliably intercepts keyboard paste (Cmd/Ctrl+V), so multi-line content is

always reviewed before it reaches the device.

from memory after use; the inventory loader rejects plaintext secrets

regardless of TOML key spelling (bare, quoted, or dotted); the SSH

connection's compile-time thread-safety assertion now covers its full

captured set; and the release build's symbol scan fails closed on a

stripped binary.

[2.2.4] - 2026-07-01

Changed

connection-import file cap (SecureCRT SCRTConfig.xml / OpenSSH

ssh_config / CSV) from 8 MiB to 64 MiB, and the inventory file cap

from 256 KiB to 4 MiB (~10k+ devices). Importing hundreds-to-thousands

of sessions no longer trips a "file is too large to import" error or an

inventory-size ceiling.

[2.2.3] - 2026-07-01

Security

device-output → AI redaction filter beyond device credentials to

cover common cloud/SaaS API tokens (GitHub, Stripe, Slack, OpenAI,

GitLab, and Google API keys), plus cleartext line/console and VTP

passwords and modern password-hash formats, so more secret material

is masked before it can reach the AI. Redaction remains one layer of

defense-in-depth alongside the per-command policy gate and approval

modal.

[2.2.2] - 2026-06-30

Security

redaction of platform-specific credential formats in device output

before it reaches the AI — covering password hashes, VPN pre-shared

keys, and BGP/OSPF/IS-IS/EIGRP routing-authentication secrets across

all supported platforms (Cisco IOS/IOS-XE/IOS-XR/NX-OS, Juniper Junos,

Arista EOS, and Palo Alto PAN-OS), plus a vendor-agnostic catch-all for

standard password-hash formats regardless of the surrounding command.

[2.2.1] - 2026-06-30

Fixed

updates" there correctly detected new versions but offered no way to

install one — it now shows a Download & Install button (with inline

download/install progress) whenever an update is available, matching the

bottom-left prompt.

now means "not right now, maybe next launch" — the prompt re-appears the

next time you open the app while the update is still available. A new

Skip this version action permanently dismisses one specific version

(and only that one — a newer release still notifies you).

[2.2.0] - 2026-06-30

Added

Sonnet for new chats across all plans. It's priced the same as Sonnet 4.6,

with a newer knowledge cutoff (January 2026) and the same 1M-token context.

Claude Sonnet 4.6 remains available in the model picker, and existing chats

keep whatever model you selected.

Changed

The "auto-approve a matching regex" affordance in the command-approval

modal now persists for the life of the chat (cleared when the chat

closes) instead of resetting after every message — approve ^show once

and it holds for the rest of the investigation. It sits behind a

clearly-labeled, collapsed **"Auto-approve matching commands? Expand

here"** disclosure with its own dedicated button — kept deliberately

separate from the primary Approve so it can't be armed by a reflex click

(modal-fatigue mitigation, threat-model T18) — and the regex field is

pre-filled with ^show. The per-vendor policy gate still runs on every command

regardless, and the affordance stays hidden/refused for generic-Linux

(unrestricted) and custom (BYOP) vendors, which require a per-command

click. Also closes a gap where a custom-vendor auto-approve was silently

ignored backend-side.

[2.1.0] - 2026-06-29

Added

Cisco's carrier-grade OS (ASR 9000 / NCS / CRS / XRv), with XR-specific

shell-escape blocks: run (classic 32-bit/QNX task shell), bash (64-bit

eXR Linux root shell), tclsh, script (XR-7.x script run on-box

Python/bash automation), admin (System Admin VM), and attach

(per-node shell). Encodes the two-stage commit config model (configure /

commit blocked; XR has no write verb), hardens show tech-support

against its file-writing forms, and pipe-blocks the write/escape stages

(| file, | redirect, | utility, | tee, | append). Select it per

device via the inventory vendor cisco_ios_xr. Verified by an

allowed/blocked corpus, a no-bypass proptest, and cargo-mutants on the gate.

[2.0.1] - 2026-06-28

Added

Appearance) based on the itinspired.com brand:

leaf-green (#74b843) primary with cyan (#00baff) focus accents — light

on warm white, dark on charcoal.

[2.0.0] - 2026-06-28

This release adds a version-aware Terms & Privacy consent gate. Signed-in

users who have not affirmatively accepted the current Terms of Service and

Privacy Policy — anyone who signed up before the sign-up consent checkbox

existed, and everyone after a future Terms change — are shown a one-time

blocking screen and must click I Agree before using the app. Acceptance is

recorded server-side as an auditable consent record.

Added

the workspace when the signed-in account hasn't accepted the current

Terms/Privacy version. It links to the live Terms and Privacy pages and

records an affirmative "I Agree" before the app unlocks. New accounts that

accept at sign-up never see it; a future Terms revision re-shows it to

everyone exactly once.

[1.6.5] - 2026-06-26

This release rolls up the work versioned 1.6.4 (which was never tagged for

production) together with the multi-line-paste focus fix.

Fixed

Linux.** It previously only fired on macOS: the keystroke was wired solely to

the native menu accelerator, which the focused terminal swallows on

Windows/Linux (only macOS's global menu bar intercepts it first). Worse, when

the terminal had focus the chord was sent to the device as a Ctrl+K

kill-line instead of clearing. The shortcut is now handled in the app itself,

so it clears the active session on every platform — and no longer leaks a

keystroke to the remote device.

Confirming (or cancelling) the multi-line paste dialog left keyboard focus

on nothing, so the cursor went hollow and you had to click back into the

terminal before you could type or press Enter. Focus now returns to the

active terminal on every way of closing that dialog.

[1.6.3] - 2026-06-25

Changed

(e.g. vEX1, or your custom rename) instead of an internal identifier, so

it's clear which open session the agent wants to run a command in. The full

session id remains available on hover.

[1.6.2] - 2026-06-25

Added

on Windows/Linux), or use the new View → Clear Terminal menu item, to clear

the active session's screen and scrollback — the same action already on the

tab's right-click menu.

Changed

unusually high usage trips Transit's safety limit, the chat now shows a calm

banner that explains it's a protective pause (not an outage), counts down to the

automatic unlock (~15 minutes), and offers a one-click Resume now — replacing

the old generic "Transit Cloud is temporarily paused" error. Heavy Operator/Pro

users also see a hint that a higher plan includes more headroom.

[1.6.1] - 2026-06-25

Added

import from SecureCRT / ssh_config / CSV, every login that uses an

on-disk SSH key or an SSH agent can become a working auth profile in one

click. Transit checks each referenced key file (read-only) and, for

encrypted keys, asks for the passphrase right in the credential step —

saving it to your OS keychain (never the inventory file). Creating a

profile by hand is prefilled too: + New opens already set to "SSH key

file" with the detected path and username filled in.

Fixed

narrow centered column, so long SSH key paths are fully visible (no more

truncated /Users/…/id_ed25519).

[1.6.0] - 2026-06-24

Added

profile that points at a private key on disk — pick it with a file

browser, no ssh-agent setup required (a relief on Windows

especially). OpenSSH, PEM, and PuTTY .ppk keys all work; if the key

has a passphrase, enter it once and it's saved to your OS keychain

(never the inventory file). The key file stays where it is — Transit

stores only its path.

[1.5.1] - 2026-06-24

Fixed

tabs.** Typing a line without pressing Enter, switching to another

tab, and switching back could leave the prompt text and cursor

corrupted (e.g. R1#This is a line came back as R1#This i). Hidden

tabs are no longer re-measured while collapsed, so the in-progress

input line survives the round trip.

[1.5.0] - 2026-06-23

Added

Cloud now trusts your operating system's certificate store by default, so it

keeps working on networks that inspect TLS traffic — a firewall's CA installed

in your system keychain/store is honored. A new Settings → Network tab adds

a Strict TLS toggle (off by default) that, when on, trusts only the

built-in public certificate authorities and refuses any inspected connection.

Takes effect on the next launch. SSH device connections use a separate trust

model and are unaffected.

verified, the account area now shows a clear message that deep-links to

Settings → Network, instead of an opaque transport error.

Changed

gear next to the account chip, rather than hidden inside the account popover.

Fixed

(e.g. R1 → R2) now puts the cursor in that terminal immediately, instead of

requiring a second click into the pane. The v1.4.1 fix focused the pane the

moment it activated — before it was laid out and before the tab click released

DOM focus — so the focus didn't land; it's now deferred a frame so it sticks.

(The v1.4.1 button-bar focus hand-back was unaffected and keeps working.)

[1.4.1] - 2026-06-22

Fixed

in that terminal immediately, so you can type without a second click into the

pane.

bar now returns focus to the active terminal (the button click no longer

leaves the cursor on the button).

in this group…* from a group's context menu correctly seeds the Group/Folder

field. Previously the field came up blank because the dialog stayed mounted

and ignored the group on reopen.

Changed

*Router1*), *Port* → SSH Port (Transit is SSH-only), *Vendor* → **Vendor

— Policy Gate** (it selects the command policy gate, not just a label), and

*Group* → Group/Folder.

[1.4.0] - 2026-06-19

Added

visible terminal output and resets that session's backend scrollback ring, so

the embedded agent's read_scrollback returns only post-clear output. Works

for both SSH and serial-console sessions. (A keyboard shortcut may follow.)

button now asks first when the session is still connected, so a misclick can't

silently drop the connection. An already-ended tab's Close button is

unchanged (no prompt).

Cmd+Q or the window-close button — while an SSH/console session is still

connected pops a "Quit anyway?" confirm instead of silently dropping the

connection. Anchored to true liveness: a tab you logout/exit-ed from (its

channel is dead, even if the tab lingers) is safe and does not prompt.

toggled from the new View → Button Bar menu. Each button sends a string to

the active session with SecureCRT's "Send String" escape codes — \r (Enter),

\n (newline), \p (1-second pause), \v (paste clipboard), \e/\###

(ESC/octal), \\ (literal backslash) — so one button can fire a full command

plus Enter, or a multi-step macro. Right-click the bar to add a button or hide

it; right-click a button to edit or delete. Buttons persist locally. (v1 ships

a single shared bar; multiple named bars may follow.)

View · Window) — primarily to host View → Button Bar, with the standard

Quit / Copy / Paste / Undo / Hide items so the usual keyboard shortcuts keep

working.

[1.3.3] - 2026-06-18

Changed

and dropdown options for plain-language clarity — "Transit Friendly

Name", "OS keychain (passwords)", "SSH agent (ssh-agent, 1Password,

etc.)", "OS Keyring Friendly Name", "Password Value" — and the username

placeholder now shows root. Display-only; no change to stored

credentials or transit.toml.

[1.3.2] - 2026-06-18

Fixed

macOS.** When a connection pins a key fingerprint and that key isn't in

the agent SSH_AUTH_SOCK points at — on macOS that's Apple's built-in

agent by default, which shadows 1Password — Transit now also checks

1Password's well-known agent socket automatically. The private key never

leaves 1Password, and every signature is still gated by 1Password's

approval. When a key still can't be found, the error now pinpoints the

cause (agent not enabled vs. 1Password locked vs. fingerprint mismatch)

instead of a generic "not available."

[1.3.1] - 2026-06-18

Fixed

notably VMware ESXi, and any host configured with the SSH password

method disabled (PasswordAuthentication no + `KbdInteractiveAuthentication

yes`). Transit now answers the server's keyboard-interactive prompts with

your saved password — exactly as the OpenSSH command-line client does —

instead of failing with "authentication failed … server rejected the

credential." Public-key (SSH agent) connections are unchanged.

[1.3.0] - 2026-06-16

Added

Transit in one pass instead of re-entering it by hand. The Import button

in the sidebar header (and on the welcome screen, or ⌘K → Import) reads

SecureCRT (an exported SCRTConfig.xml), an OpenSSH ~/.ssh/config,

or a CSV, then walks you through three steps: it groups your saved logins

so you map each shared credential once — reuse an auth profile you already

made, or create one (the secret goes straight to your OS keychain) — then

shows every connection in an editable grid where you can bulk-assign vendor

and group, rename, and exclude rows before importing. Transit reads host,

port, username, folder structure, and key-file paths; it never reads or

decrypts your stored passwords. Devices that collide with an existing name are

flagged and skipped until you rename them, and the whole import is atomic —

if anything is wrong, nothing is written.

[1.2.0] - 2026-06-15

Added

changelog, a newly available model, or an important account or policy

notice — as a dismissible card in the bottom-left corner, fetched

alongside your account info. Only the highest-priority unread notice

shows at a time, and dismissing one is remembered. Notices are

delivered from Transit's service, so they reach installed builds

without waiting for an app update.

[1.1.0] - 2026-06-13

Added

GUI: right-click → New group (empty groups now persist), **New

subgroup, Rename, and Delete group** (its connections and

subgroups move up to the parent — nothing is deleted). **Drag a

connection** from one group into another, or onto the "Drop here to

ungroup" zone. Group expand/collapse state is remembered across

launches. Backed by a small groups registry in transit.toml (so a

device-less group survives) layered over the existing per-device group

path; pre-existing inventories load unchanged.

(+/− / value / Reset) alongside the terminal font-size row. It scales

the agent chat panel's message thread — prose, code blocks, and inline

code — independently of the terminal, defaulting to 14px (prose reads a

touch larger than the monospace terminal default). Persisted to

localStorage like the terminal preferences.

[1.0.2] - 2026-06-12

Added

dropdown of the monospace fonts actually installed on your machine —

and filtered to the ones the terminal renderer can really use, so

families the OS ships but withholds from app web content (SF Mono)

no longer appear just to silently fall back. Each option previews in

its own face. Custom… keeps the previous free-text path for

hand-written fallback stacks and fonts that don't advertise fixed

pitch.

you edit the pending text before sending — trim a stray trailing

newline, drop a line, fix a typo — instead of cancelling and

re-staging the whole paste. What you paste is exactly what's in the

box, the line count updates live, and emptying the box disables

Paste.

Changed

Policies tabs stop crowding their controls.

Fixed

real culprit: the sidebar's scroll viewport sized its content to the

widest row, so one long hostname pushed every row's right-aligned

address past the visible edge — the viewport's content wrapper is

now pinned to the sidebar width. Within a row, the address also

keeps a readable minimum width, truncates predictably, and both

fields show their full value on hover.

[1.0.1] - 2026-06-11

Added

type the name of any monospace font installed on your machine (e.g.

JetBrains Mono) and every terminal pane switches live. Falls back to the

stock font stack when the field is empty or the font isn't installed.

highlighting, vendor-specific vocabulary now layers over the generic set:

Cisco IOS / IOS-XE / NX-OS / Arista EOS get syslog mnemonics colored by

severity (%SYS-2-… red, %LINK-3-… yellow, %SYS-5-… cyan) plus

connected / notconnect / err-disabled interface status; Juniper Junos

gets commit complete, the truncated BGP Establ state, and chassis-alarm

classes. Picked automatically from the device's vendor.

Fixed

font size (⌘+ / ⌘− / ⌘0) or family re-fits the pane on the next frame, after

the renderer's cell metrics settle — previously repeated zooming could push

the prompt line below the visible area until the window was resized.

Changed

Opus 4.8 (same speed tier and price). Chats still set to Opus 4.7 are served

by Opus 4.8 automatically; no action needed.

Security

find / grep allow-rules now require PAN-OS's own grammar (a …-log area

for the first three, the literal find command form), so their GNU

namesakes (less /etc/passwd, find / -exec …) can no longer satisfy the

allowlist on a mislabeled device. Defense-in-depth — such commands were

already subject to the approval modal.

[1.0.0] - 2026-06-10

First stable release. Headline features: Bring Your Own Policy, custom

vendors, connection-name-aware AI, and open-session-scoped policy briefing.

Added

the connection name you gave the device (its inventory id, e.g. "R1")

instead of a host:port stand-in, so "what is R1's loopback IP?" resolves

to the right session. The session list the assistant sees also includes

each device's vendor.

over the built-in ones: add read-only allowed commands to a shipped vendor,

or define an entirely new vendor (e.g. Fortinet, MikroTik) with its own

<vendor>.yaml. Point Transit at a policy directory (the Vendor field in

the device dialog accepts a custom name; set the directory via

TRANSIT_USER_POLICIES or the Settings → Policies tab). The directory can

live on a shared drive for team use. Your additions can never weaken the

built-in safety floor — a shipped block (config mode, write commands, shell

escapes) stays blocked no matter what a user policy says — and a custom

vendor still requires per-command approval for every command.

read-only starting points for Fortinet FortiOS and MikroTik RouterOS,

ready to drop into your BYOP policy directory and doubling as worked

examples of the policy schema.

Changed

The system prompt includes only the command policies for vendors you

currently have sessions to (plus an explicit default-deny note for devices

with no policy), instead of every shipped vendor's full policy on every

conversation. Cuts per-turn token overhead and clears the path to a much

larger vendor catalog; enforcement is unchanged — every proposed command

still runs the full policy gate and the approval modal (Rule 3).

[0.3.0] - 2026-06-09

Security-hardening release resolving the findings of an internal code review.

Security

proposed command that tried to hide a second statement behind a newline (or

other control character) is now rejected before it is evaluated, the approval

modal shows the full command faithfully instead of collapsing hidden lines,

and the SSH/serial executors refuse to send control-character payloads.

Command matching is now case-insensitive, so block rules can't be sidestepped

with alternate capitalization.

and coverage for key chain key-strings and PPP passwords, and redaction now

runs over the full buffer before any truncation — so a secret split across a

buffer boundary can no longer slip through to the AI.

the transit:// sign-in callback URL (which carried access/refresh tokens),

and the logging subsystem is now actually initialized.

Fixed

a transient server blip during token refresh no longer signs you out, and

simultaneous refreshes are coalesced.

show a clear message in chat instead of a generic status code.

never showed as closed); one stuck session could freeze the others; and

carefully verifying a new host key no longer risks a spurious connect timeout.

editing a device preserves a remembered "allow weak crypto" choice, and

multibyte terminal output split across packets now renders correctly.

[0.2.2] - 2026-06-07

Added

Anthropic's most capable model, at the same speed tier and price as

Opus 4.7.

[0.2.1] - 2026-06-05

Added

twilight indigo with teal and amber accents). Pick it in Settings →

General → Theme.

[0.2.0] - 2026-06-05

Added

shows a small prompt in the bottom-left corner when one is available. Click

Install & Restart and Transit downloads the update, verifies its

signature, swaps itself in place, and relaunches — no manual reinstall.

Choose Later to be reminded at the next release. Settings → Updates shows

your current status and a manual Check for updates button. (macOS Apple

Silicon and Windows.)

Changed

you type "continue". It now runs continuously through an investigation

and only pauses for a one-click Continue after a long autonomous

burst (~50 commands), with an always-visible Stop and a live activity

readout (commands run · elapsed · tokens). A per-turn timeout guards a

stalled model response. Large command / scrollback outputs are capped,

and older ones collapse to a re-readable note, so long log-parsing

sessions stay responsive instead of degrading.

[0.1.2] - 2026-06-01

Changed

(with an automatic fallback to the DOM renderer on GPU context loss).

[0.1.1] - 2026-06-01

Changed

dirs 6, getrandom 0.4, tauri 2.11.2, and related transitive

updates). Encrypted session export migrated to age 0.11's API with no

change to the on-disk format — exported files stay decryptable with

age -d (scrypt KDF + ChaCha20-Poly1305).

and lint-staged 17, plus minor TanStack Query, React Hook Form, ESLint,

Vite, and Vitest updates. No user-facing behavior change.

[0.1.0] - 2026-05-31

Added

terminal, multi-session tabs, host-key trust-on-first-use, a modern-crypto

handshake with a per-device legacy opt-in, and optional per-device syntax

highlighting and SecureCRT-style quick copy/paste.

per-vendor command policy gate, and a device-output redaction filter on

everything the model sees.

EOS; Palo Alto PAN-OS; plus an unrestricted generic-Linux profile.

bring-your-own-key (BYOK) support on paid tiers.

NSIS -setup.exe installers, distributed via the dev and prod release

channels.

← Downloads