Download

The desktop app, st for the terminal, and the mobile apps. Every link is the latest version, and what changed in each one is in the changelog below.

Downloaded 1,145 times (since 2026-10-29)

Desktop app

This computer's sessions and the other machines on your account, in one window. st is inside it, and it updates itself.

212 downloads

Homebrew
brew trust --tap sophonz-labs/tap && brew install --cask sophonz-labs/tap/sophonz

macOS, Apple Silicon only. The app updates itself, so brew upgrade leaves it alone. brew trust comes first because Homebrew asks before it loads a tap that is not its own.

st v0.4.2· 924 downloads

One binary that shares a terminal session. Run it and it prints a link and a QR code; browsers and the apps join that session.

macOS
brew trust --tap sophonz-labs/tap && brew install sophonz-labs/tap/st
Linux
curl -fsSL https://dl.sophonz.io/install.sh | sh
Windows
irm https://dl.sophonz.io/install.ps1 | iex

On macOS, brew trust comes first because Homebrew asks before it loads a tap that is not its own.

Install guide

Mobile

For iPhone and Android. They remember your machines and put a terminal on the screen with a key bar on the keyboard.

Without Google Play: the APK · 9 downloads

The apps

Changelog

What changed in each release, gathered from the commit history.

  1. v0.4.2

    Pages from another site can no longer change your machine

    Only this machine's own pages can change it. A page on another site could open a terminal connection or send a request that changes something (close a session, write a setting) while you were signed in to your machine's web terminal in the same browser. st now refuses every request that changes something, and every terminal connection, unless it comes from the machine's own page or from an app. The desktop and phone apps are unaffected. Reading is unchanged.

    One owner check for everything. Every service that changes something asks the same owner check, so a future read-only link is refused by all of them at once.

    Files for the desktop. The desktop can browse folders and preview files on this machine, or on another of your machines through its existing connection. It can save a text file it opened: an existing UTF-8 file of up to 1 MiB, only if the file on disk is still the one that was read. A file changed since is refused and nothing is written. The new file replaces the old one in a single step, keeping its mode. Secret files stay protected by the machine's existing setting.

    Decision gates in any terminal. st gate list, show, answer and cancel work outside tmux, through this machine's running st. A gate can be answered from the desktop or the phone.

    CI across the repository. The CI board shows the repository's latest 50 GitHub Actions runs, on every branch and tag, with each run's branch or tag. A workflow with no run in that window says "No recent run".

    8 changes in this release
    • Proxy: no write and no websocket from another origin, on every route (#300)
    • st: one owner predicate for every service, and /api/fs/v1/write for the desktop's editor (#298)
    • Show repository-wide CI boards across branches and tags (#297)
    • Pace redraw fixture against elapsed time
    • Isolate hook forwarding tests from launcher ancestry
    • Pin browser root components before reading
    • Allow decision gate responses outside tmux
    • Add bounded owner file browser read API
  2. v0.4.1

    A Pro machine is reached through sophonz's relay by itself

    A Pro account's machine takes sophonz's relay without a token to type. Its heartbeat asks for one, and the account answers with the machine's own relay. st tries it once and moves the share onto it. The machine's address then stays the same across restarts, instead of a new quick-tunnel address each start.

    • What you chose wins. A Cloudflare quick tunnel or the tailnet picked with st route, or a relay of your own set with st relay set, keeps the managed relay unused. st route relay picks it. st relay reset chooses a quick tunnel and stays there, even before the relay arrives.
    • A relay that is the same as before is neither tried again nor reconnected to. A new one that does not take the machine leaves the share as it is, and it is tried again with the next report.
    • When the plan ends, st goes back to a quick tunnel at once. A machine taken off the account signs out and stops sharing, as before. The relay is the account's: signed out, or signed in as someone else, st does not use it.
    • If the relay refuses the machine when st starts, the share runs on a quick tunnel until the next report says what is true now. st route says so, and why.
    • st route and st relay show the relay as sophonz's, from your Pro plan. The relay's token is never shown or logged.
    • /api/version says relayAuto: 1. An app that sees a Pro account without it can ask you to upgrade st.

    opencode 2. st's opencode plugin loads in opencode 2, which refused the old one with "Plugin must export a default definition…", and opencode 1.3.4 and later keep working with the same file. st hooks install turns off opencode 2's shared background service so that each opencode window is its own pane. st starts opencode with --standalone where it starts it. Without that, every window's turns showed under the first one. st hooks shows the old plugin as outdated, and automatic updates rewrite it.

    Codex. st hooks install turns off Codex's shared app-server, and st starts Codex with --no-daemon, so that each Codex window is its own pane. A session still on the shared app-server is not given another window's turns. A Codex whose sandbox keeps its shell from st runs st's commands through one MCP tool, st. A shell that cannot reach st says so. A Codex approval prompt is read the same at any window width, so an answer from the phone goes through.

    The web terminal. A page left open past its sign-in says the sign-in expired. It offers to open this machine again or go to the dashboard, above the token field. A split window has a Compose button in the active pane's corner, and none in a pane too small for it. The machine's links sit inside its block in the sidebar. A Codex pane finds its conversation again after st restarts.

    The vault page. A notification about a brief opens it, with its .briefs folder in the tree.

    18 changes in this release
    • relayAuto is said wherever there is a tunnel, not only where there is orchestration
    • Managed relay: a switch records what the keeper is about to start, so a report before it starts does not cycle again
    • Managed relay: a relay child taken over after a sign-out is known by its own route's account, and route keys hold no token
    • Managed relay: a tunnel taken over at st restart or an upgrade says what it is
    • Managed relay: a tunnel running on it goes when nobody signed in may use it, and comes back when its account signs in again
    • A Pro machine takes sophonz's relay from its heartbeat, by itself
    • opencode 2's shared service off: st hooks install sets "disabled": true, and st starts opencode with --standalone (#292)
    • opencode 2 loads st's plugin: one default export with server and setup, and the shared service's events go to no pane (#291)
    • Login page: an expired sign-in says so, and offers this machine again and the dashboard above the token field (#290)
    • Codex's shared app-server: st turns its auto-start off, starts every Codex with --no-daemon, and gives a daemon session's hooks to no pane (#289)
    • st mcp: a sandboxed Codex runs every st skill through one MCP tool (#287)
    • A shell that cannot check st says so, and leaves agent.json (#288)
    • Sidebar: the machine's links inside its block, and one 4px corner radius (#286)
    • Compose corner button: the desktop's look (muted, hover) and none in a pane too small (#285)
    • Vault page: a notification's brief opens, with its .briefs folder in the tree (#284)
    • Agent watch: a Codex approval reads the same at any width, so a phone's answer to it goes (#283)
    • Web terminal: a Compose button at the active pane's corner when the window is split (#282)
    • Chat: a Codex pane finds its rollout after st restarts, before its next hook (#281)
  3. v0.4.0

    st serves the machine's vault, and st ui shows the machine in one screen

    st serves the vault page. A machine's documents open as a vault: a file tree, notes in Live, Read or Source, the graph, and the vault's own plugins. Every screen opens the same page from st, at /vault on the machine's link: the desktop app, the phone apps, the web terminal and any browser. ?scope=<session> or ?scope=<session>/<window> opens one session's or window's folder as the vault's root. An edit shows on every other device that has the note open within a fraction of a second, through a share's tunnel too, and a file an agent writes arrives within the 2-second scan. Two devices saving at once do not write over each other.

    • Live edits with the formatting shown, Read is the reading view and Source is the markdown as it is. The switch sits in the note's header; ⌘E toggles Read.
    • Tables are edited where they are: click a cell, Tab and Enter move, a right-click adds, moves and deletes rows and columns. A table wider than the page scrolls in its own box.
    • Callouts are drawn and fold, and $…$, $$…$$ and fenced math are typeset.
    • ⌘G opens the graph of the whole vault, and the local graph shows the note in front with its neighbours.
    • Settings › Appearance sets the body width and turns CSS snippets on and off; a note's cssclasses apply.
    • Plugins are your own: put one in the vault's plugins folder and turn it on in Settings › Community plugins. Plugins run in a sandbox with none of st's cookies or tokens. st's docs show how to make one, with a working example.
    • On a phone the page has a phone layout: drawers for the sidebars, a bottom bar, an editing toolbar above the keyboard. It opens on a note, with the folders it is in on a line under the title.
    • The page shows a progress bar from the first moment, and through a tunnel the first note appears in under a second once cached.
    • A document notification opens that note.
    • Folders whose names start with a dot stay hidden. st's .briefs folders can be shown from Settings › Files and links, a choice kept per machine.

    A note made in the vault is a document. st keeps its id in .st/ rather than in the note, so it is in st doc ls and on the phones. st doc --folder critic puts the document in critic/ on disk. GET /api/docs says which session or window folder each document is in (vaultFolder). /api/version says docs: 5, vault: 1 and vaultReady.

    st ui shows this machine in one terminal screen. It starts on a tree of your machines, sessions and windows, this machine first, and lists windows, panes, the coding agents in them, orchestration runs, CI, the vault's notes, plan usage and the machine's CPU, memory and swap, refreshed every two seconds. enter or a attaches, on another machine too; from inside tmux 3.3 or later it opens in a popup and Ctrl-b d comes back. o adopts the selected agent as a worker and R releases one, each after y. c opens a window's newest GitHub Actions run. : runs any st command. The header shows the sophonz wordmark and each weekly limit by name (weekly sonnet, weekly opus).

    Agents. A working agent is teal in st ui and the web terminal, apart from the orange of an agent that asks for you. A program that reports its own status (OSC 7501) is believed, and st ui marks that state as reported. st worker wait --check-in comes back with how the workers are and leaves them running. st --skill prints the agent's guide in one read. A send another machine turns down says why. st plugin install, and st after an upgrade, update Claude Code's copy of the plugin and the Codex skills where they were installed.

    The web terminal. The machine row's Doc opens the vault in a tab, and a session or window row has a Doc button for its folder. The built-in sophonz and Light themes take the desktop app's colours, every theme paints the page around the terminal, and the selected session, window, chart row and document are cyan in sophonz and Light so they read clearly.

    "This machine" means st's token, not the loopback address. A page in a browser on the same machine connects from loopback too, so st doc's origin claims, st hook and st gate ask are trusted only with st's own token, which st's programs always send.

    Release candidates. st upgrade --channel rc follows release candidates and st upgrade --channel stable follows releases. The choice is kept on the machine, and /api/upgrade and /api/version say which channel is in use. An st on a candidate is not taken back down; this release arrives on top of it.

    39 changes in this release
    • Web terminal: selected rows are cyan in sophonz and Light (desktop #148's pick) (#274)
    • Web terminal themes = desktop #144: sophonz's new default look, every theme paints the page (#271)
    • Vault: the host's colours from the first paint; Browse closed; how to make a plugin (#270)
    • Plugin: follow st up; guides: retired runs, gates, refused sends, st ui (#269)
    • Agent state: say where it came from in st ui; why Claude Code does not report in tmux (#267)
    • st worker send: a refusal from another machine says why (#266)
    • Probes: run st against an upstream psmux commit (master 7deee900 answers as v3.4.0 does) (#265)
    • st ui: the per-model weekly limit by its model's name (#264)
    • st ui: the wordmark st prints when it starts, at the top right of the header (#263)
    • st ui: CI of each window's checkout, opened in the browser with c (#260)
    • st ui: the wordmark in one row where the two-row logo does not fit (#261)
    • st ui: adopt and release (across machines too), and the vault's notes as source (#259)
    • st ui: starts on the machine tree; attach comes back on Ctrl-b d; a small logo (#258)
    • Web terminal: working in its own color, apart from asking's orange (#257)
    • Vault page on a phone: the note's folders on a line of their own (#256)
    • Vault page on a phone: the note first, and the folders it is in (#255)
    • st ui: the machine in the terminal, as k9s shows a cluster (#251)
    • Vault page: open the note named by ?note= (a notification's document) (#253)
    • Vault page: the file explorer is open when the vault first opens (#250)
    • Vault page: dot folders never in the tree, .briefs from Settings, and Settings › Appearance (body width, CSS snippets) (#248)
    • Vault page: a loader from the first byte, a faster start, and wide tables scroll in their own box (#247)
    • Vault page: Live / Read / Source switch, live over the tunnel, a phone layout, sidebar buttons (#245)
    • Web terminal: Doc opens the same vault as the desktop app (#242)
    • Live Preview: no active line without focus, \| in table cells, callout spacing, math typeset with KaTeX (#241)
    • Vault page: the graph view, global and local (#240)
    • Live Preview: tables edited in place, callouts and math drawn (#239)
    • Vault page: without ?mobile=1 the user agent decides (#238)
    • GET /api/docs: vaultFolder, the session or window folder a document's file is in (#232)
    • Agent watch hears OSC 7501: a program that reports its status is believed (#234)
    • st worker wait --check-in: come back with how the workers are, leaving them running (#236)
    • "This machine" is the token, not the loopback address (#225)
    • st --skill: the agent's guide in one read (#235)
    • Live Preview draws tables: a widget while the cursor is outside, the rows inside (#231)
    • Vault page: Browse and install community plugins, fetched by st (#230)
    • Vault page on a phone: drawers, a bottom bar, full-width dialogs, Platform.isMobile; plugin bundles cached (#229)
    • Vault page: the .briefs eye toggle is the machine's setting (stacked on #227) (#228)
    • st serves the vault page: /vault, the vault by path under /api/docs/vault/, and the page itself in web/vault (#227)
    • st upgrade: an rc channel, so a release candidate is followed and never downgraded (#226)
    • st doc: a note made in the vault becomes a document, its id kept in .st only (#223)
  4. v0.3.116

    Decisions filed in critic/ are in critic/

    st doc <file> --folder critic now puts the document in the vault's critic/ folder. Until now it said "in critic/" and left the file in the folder of the window it was written from: --folder set the label the apps sort by, and only a settled decision gate's record was placed in critic/ on disk. So a decision a coordinator filed there was in critic in st doc ls and the apps, but not in critic/ when you opened the vault. Now the file goes to critic/<name>.md at the top of the vault.

    A document filed that way before this release is still where it was written. st doc mv <id> critic takes it to critic/, and moving it to another folder later brings it back to its window. The move is made by the st that is running, so run it once that st is this version.

    critic has no folders inside it. A decision is not a session's or a window's, so there is nothing to sort it by below critic: --folder critic/sub, st doc mv <id> critic/sub and st doc mkdir critic/sub are refused, and so is renaming or moving critic itself.

    What did not change: the document keeps its source, so one you wrote with st doc still says it came from cli. Everything not filed in critic stays where it was, in its session and window folder, with briefs in that window's hidden .briefs/, and a file you moved yourself in the vault is not moved back.

    1 change in this release
    • st doc: --folder critic puts the document in the vault's critic/ (#220)
  5. v0.3.115

    A refusal is not a failure, and finished work counts as done

    Two things said something was wrong when nothing was.

    An update st turns down on purpose now says so. There are six reasons st will not replace itself -- it is a development build, it is the copy inside the desktop app, Homebrew owns the file, it is a kept earlier version it fell back to, the machine is signed out and its tunnel address is the only way in, or ST_VERSION pins it -- and each one hands you the thing to do instead. None of them is a breakage, but an update had only done and failed to end in, so all six arrived as failed and the instruction beside them read like an error. The status now carries why when st turned the update down, and leaves it off when an update was really tried and broke. The desktop app, iPhone and Android read that and stop calling it a failure: each says it cannot update from there, in its own words, and shows st's own sentence under it. That sentence has not changed. An st from before this field sends no why either way, so a missing one is also what an older machine's refusal looks like.

    A worker's st worker done is no longer dropped as late. st worker send wrote down the time after the keys went in, and the send answers only once it has watched the prompt arrive, which takes up to 1.6 s. An agent that submitted faster than that looked like it had taken the prompt before the work was sent, so its report was written and not counted. That left the pane's @st-done unset, which is what st worker wait reads, so finished work stayed unfinished and a coordinator waiting on it never came back. The time is now taken before the keys go in. On a busy machine it hit four times in one session.

    2 changes in this release
    • st upgrade: a refusal says why in the status, so it is not shown as broken (#216)
    • st worker send: @st-sent is when the keys went in, not when st was done (#215)
  6. v0.3.114

    The vault shows what you keep, and every decision is a file

    st doc migrate gave you a vault, but it gave you all of it: 591 documents in one list, 583 of them briefs sent between agents. The ones you wrote were lost among them.

    Briefs move into the window's hidden .briefs/. A vault app does not index a dot folder, so what it shows you now is the documents you and your agents meant to keep -- eight, where it showed 591. st doc ls and the apps still list the briefs; nothing was deleted and no file changed a byte. The pane folder is gone with them: a document sits at <session>/<window>/, because a pane is where an agent happened to be sitting, not what the document is about.

    Every decision gate is kept as a document in critic/. The question, every option with the one that was chosen, the written answer, when it was asked and answered, and which session, window and pane asked it. st gate list forgets the oldest past 200; the folder does not, and a gate that has not been written yet is not forgotten. That folder is what the next agent picks the work up from, so ask a decision through a gate and write the question to stand on its own.

    The layout move has no undo. st doc migrate --undo still does what it always did -- it takes every document out of the vault, back to ~/.sophonz/docs -- but it will not put the pane folders back. Copy ~/.sophonz/vault/machine before you run the migration if you want a way back; the move writes what it did to .st/relayout-<time>.json either way.

    prompt-opened now says gate in the clear, true for a decision gate and false for every other prompt, so a phone can be told to alert on decisions only and stay quiet for the rest. What the gate asks stays sealed.

    3 changes in this release
    • TestCloseWindow: wait for session recovery to be told, and count atomically (#214)
    • st doc: briefs hidden in .briefs, no pane folder, decision gates kept in critic/ (#211)
    • agent watch: prompt-opened says gate true or false, in the clear (#212)