From 0.4.0, Opsty checks for updates by itself about once a day, downloads them quietly, and installs them when you say so. 0.4.0 is the last version you download by hand: if you have 0.3.0 or earlier, download it from the front page and drag it over the old one in Applications. Your settings and history stay where they are.
From 0.4.0, Opsty is freeware: free for any use, and not open source. Releases up to 0.3.0 were published under the Apache-2.0 license.
0.7.0Ready to Show
macOS 13+ · Apple silicon
❯rsync -av site/⇥ tab
❯rsync -av site/
Opsty has a capital O now. The grey text on your line is Tab’s, ⌘K clears the way it does in Terminal, the cursor can be a bar while you type, and the Running list and the Glance give each thing one line. The rest is what a first full day in Opsty, instead of Terminal, turned up: marks left over after tput reset, unreadable inverse text on light themes, links that opened on a plain click, and ⌥Space taken from Raycast.
New Opsty, with a capital O
opsty is now Opsty.The name has a capital wherever you read it: the menu bar, the About box, notifications, Settings and this site. The mark beside it is the app’s own icon, the lamp and the cursor. Nothing you set up changes. Your settings, history, permissions, ssh:// links and the opsty command are all kept, because everything a program reads is still opsty. A copy that updated itself keeps the folder name opsty.app in Finder until you reinstall it from opsty.dev or with curl -fsSL opsty.sh | sh, which installs it as Opsty.app. A Finder Quick Action installed before 0.7.0 still works and keeps its old name, New opsty Tab Here, until you press Update beside it in Settings ▸ Advanced.
Homebrew.brew install --cask opsty-dev/tap/opsty installs the same notarized app. Opsty updates itself, so brew upgrade leaves it alone.
Permission prompts in Opsty’s words.When a program in a tab asks macOS for the camera, the microphone, a folder or the local network, the prompt names Opsty, because macOS asks on behalf of the terminal. It now says that a program running in Opsty is asking, instead of a generic line about the app.
New The grey text is Tab’s
⇥ takes the grey text.Ghost text, the rest of a command you ran before, shown in grey after what you typed, now goes on the line with ⇥, as well as → and End. ⌥→ takes one word of it. Nothing runs: you still press Enter.
The keycap.A faint ⇥ tab after the grey text says which key takes it, and clicking it does the same. It turns amber when the line it would make is one Opsty warns about.
⇥ again completes.Pressed again straight after, ⇥ goes back to what you typed and completes that word as zsh would, and a third ⇥ shows zsh’s list. While the Tab popup is open, the grey text steps aside.
New⌘K clears, as in Terminal
Clear to Start (⌘K).It erases the scrollback and the screen, and the commands’ marks with them. At a prompt your shell then draws its prompt again, with what you were typing. With a program in front, the line it is on stays and nothing is sent to it. A full-screen program such as vim is left alone, and Opsty says so: Not cleared: a full-screen program is in front. On a tab that stopped, it also puts out the red cross, as Clear does. It used to send ⌃L, which only scrolled the screen out of sight.
Clear Scrollback (⌥⌘K).The scrollback only; the screen stays. Both are in the Edit menu now.
A cleared command is still yours.Run again (⌘⏎) and Copy command still work on it, ⌘↑ and ⌘↓ skip it, and copying its output says Its output was cleared.
New The cursor
Shape, bar and blink.Settings ▸ Appearance has a cursor group: Shape (Block, as in Terminal, Bar or Underline), A bar while you type a command, on by default, and Blink. At the prompt the cursor is a bar, like a text field, with the grey text starting right after it; programs get the shape you chose. A program can still pick its own, as vim’s insert mode does, and the next prompt goes back to yours.
New Running, one line each
One line per thing.Each row says what runs, where, one fact (its port, exit 1, ssh) and for how long, in columns that never move. The detail beside the list has the rest, with the page it serves on top. A busy day’s list fits without scrolling.
Where, said short.A server’s folder is its project’s last folder, with the build output dropped and a parent folder added only when two would read the same, such as new/frontend and orig/frontend. In the detail a long path is folded in the middle, and copying it gives the whole path. A start time is said once: for 7h · since 14:01.
One No tab, one Tunnels.Servers no tab started are one group, not one per folder, and background tunnels are another, each row saying where it goes.
Other apps, folded.Ports held by other apps (Docker, an editor, an app’s helper) are folded into one row at the end, 2 other apps, closed until you open it. They are not counted and have no Stop, and macOS’s own are not listed. Whose a server is, Opsty decides by the program file it runs, never by the name it gives itself.
A page that looks broken says why.When a server fails to send its page’s stylesheets, the picture of the page is captioned, such as 2 stylesheets returned 500 — the server’s problem: it looks unstyled in any browser, not only here.
New A shorter Glance
Calls first, then one line each.The Glance shows at most two cards for what needs you, an agent’s question or a stop, with a stop’s command said once. Then one line for each thing running, at most six, and a line that counts the rest and opens the Running list. The selected line shows its one action where its age was: Open, Copy or Go to tab. It is never taller than 560 points.
An answer only to a question you could read.An agent’s answer button is offered only when its whole question fits on the card. A longer one has Open Tab alone, and says The whole question is in the tab.
Solid with Blur off.With Blur off, the desktop behind the Glance showed through it, sharp enough to read another app’s text. It is solid now.
One row of doors.The find field, Show Everything Running, and round buttons for Quick Terminal and Settings, their shortcuts in their tooltips. Start again shows only when things are quiet.
The right-click menu, short too.Its headers are the Running list’s, five rows to a header. A server no tab owns is named with its folder and a tunnel with its host, so no long path makes the whole menu wide.
New Claude Code, in its own words
Opsty answers Claude Code’s question.Claude Code 2.1.295 and later asks the terminal whether it can read a status, and Opsty now says yes. Claude then reports in words whether it is working, waiting for you or done, instead of a ◐ or ✳ in its title. Over ssh Opsty doesn’t answer, and Claude there keeps its title marks. claudeStatus = false in config.toml turns it off.
What it did, in the notification.When Claude finishes behind your back, the notification quotes Claude’s own sentence about the turn, such as npm test passed; 42 tests, instead of the task’s name. When it asks permission and its dialog doesn’t say what for, Claude’s sentence does, such as approve Bash: npm test. The Running list, the Glance, the menu bar and what a tab did while you were away quote the same words.
Fixed
A reset erases its marks.After tput reset, reset, printf '\ec' or a test watcher’s rerun (vitest’s watch mode resets the screen every time), the old commands’ marks, tints and summaries were drawn over the new screen, and were still there 200 lines later. They go with the text now, and a command still running keeps its mark from the top of the new screen. After clear there is nothing left to scroll back to.
Problem marks follow a redraw.A test runner that rewrites its summary, from ✗ to ✓, no longer leaves the old row tinted red.
Inverse text on light themes.less’s (END), vim’s status line and zsh’s menu selection were black on near-black on every light theme. And every program that asked was told the background was black, so Claude Code’s automatic theme, Neovim, bat and delta chose dark colors on a light grid. They are now told the theme’s real background.
Links open on ⌘-click,as in Terminal, iTerm2 and Ghostty, and so does a file path in an error. A plain click only puts the keyboard in that pane. Hovering a link shows where it really goes, which matters when its text says something else.
Graphics memory is released when you switch tabs.A tab you switched away from kept the buffers it had drawn with, four per pane and about 24 MB each for a large one, until macOS happened to reclaim them. One window left open for two days held 425 MB of them, with two panes on screen.
No environment variable on screen.A server that renames itself, as Next.js does (next-server), made macOS’s ps print the first of its environment variables as if it were part of the command, and the Running list, the Glance and the menu bar showed it, so a token could appear there. Such a server is now shown by its new name and the program it runs, and every command line is shown with passwords and tokens removed.
Quick Terminal is off until you switch it on.⌥Space is Raycast’s and the ChatGPT app’s key too, and whichever app started first took it, without a word. Switch it on in Settings ▸ General, and if another app holds the chord, Settings says so at once. A config.toml that already says quickTerminal = true keeps it.
Codex and Gemini CLI, recorded from the real thing.Read from recordings of Codex 0.163.0 and Gemini CLI 0.64.0 instead of from memory. Codex says what it is doing in a status it sends every terminal, and its asking for approval is now your turn rather than idle; its task is the conversation’s name, once it has one. Gemini’s ⏲ counts as working.
Output can’t pose as your shell.Each shell Opsty starts gets a secret, and Opsty listens only to the messages that carry it. A file you cat, a server’s log or a remote host can no longer rename the running command, which Restart and the morning sheet would then have typed.
fish is left alone.Opsty no longer loads anything into fish, which it never supported: its marks arrived twice, and too early. fish runs as it always does, without marks or cards.
Updates respect your macOS.Opsty never offers an update your macOS can’t run, and Settings ▸ Advanced says why, such as 0.8.0needs macOS 14 or later, so this Mac stays on 0.7.0.
Keys at the prompt.End goes to the end of the line; it did nothing. ⌥→ moves a word; it typed ;3C. The grey text works in zsh’s vi mode, never offers a command that spans several lines, and is cut with … when it is wider than the window. And turning Ghost text off now stops → taking it in tabs that were already open.
Privacy What changed for your data
For a program listening on a port that no tab started, lsof is now also asked which program file it runs, to tell an app’s own helper from a server you started. It is asked on this Mac, like everything else lsof answers.
A program that renamed itself keeps only its new name in what Opsty shows, because macOS’s ps prints such a program’s environment after it.
Opsty now answers Claude Code when it asks whether the terminal can read its status. The reply goes to the program in your tab and nowhere else, and what Claude then reports is read like its title and kept only while Opsty runs.
Nothing new is sent. The update check reads the lowest macOS a version needs from the same file it always fetched, and the secret each shell gets stays in that shell: it is never written down or sent anywhere.
The whole promise, file by file, is on the privacy page.
0.6.0Nothing Cut Off
macOS 13+ · Apple silicon
2Thu 9:41
subtank · your turnshop · stoppeddoclife · :3000
Opsty no longer draws over what a program printed, and nothing in its lists is cut off without a way to read the rest. The Running list is now a list and a detail, and a command that stopped says why, quoting the line it read. The launcher’s columns stay put, and Opsty’s own mark sits in the menu bar, with a Glance on a click and a menu on a right-click.
New Output, never covered
Problem rows, marked under the text.Rows a program marks as failed or warned (✗, !, ▲, ERROR, a container that exited) are tinted under the text, with a lit dot in the margin, and the command’s row sums it up, such as ✓ 9 · ✗ 2. The text itself is just as the program printed it, selectable and found by ⌘F. A dev server’s error rows are marked as they arrive.
Show formatted.From the Block menu, the command’s margin menu, a lit dot or the summary, Show formatted lays the output out again beside it: checks by section, tables and logs in columns, JSON as a tree, every line in the order printed. Copying from it gives the lines exactly as printed.
The old lens is gone.The box that was drawn over a command’s output, cut off its last lines and could not be selected, is retired, and lenses = true in an older config.toml is dropped the next time Opsty writes it.
New Running, a list and a detail
Short rows, and the rest beside them.Running is a list of short rows and the detail of the one you select: the full command as typed, its address, the page it serves, its process and its buttons, in one row that keeps its place. ⏎ presses the filled button, which never runs or stops anything; ⌘C copies the selected address or command.
A stop says why.A stopped command’s detail has its command, how long it ran and its exit code, then the line Opsty read with its explanation, or the program’s own last error lines, and Go to the block as the Enter. Run the command above again names what it types, and Clear takes it off the list. A stop’s notification, Why it stopped in the tab’s menu and Show in Running on its failure card open the list there.
Servers no tab owns, and tunnels.Servers with no tab are grouped by the folder they were started in, and background ssh tunnels by the server they go to, each forward said in a sentence. Stop and Disconnect show the kill they send, and no key ever stops or runs anything.
Answer an agent from the list.An agent’s question is quoted word for word in its detail, with its own first answer as a button, sent only after Opsty reads the agent’s screen again.
The page a server serves, when you select it.The picture of a server’s page is in its detail now, taken a moment after you select the server and only while it stays selected, instead of in a second panel when you hover.
New The launcher, lined up
Columns that stay put.Every list has one set of columns, and moving the highlight moves nothing: a command’s shortcut stays, and the ⏎ at the end of the row lights. What ⏎ does is said at the foot, and in All at the head of each group.
Commands in the menu bar’s order.One group per menu while you browse; once you type, one list, with where each command lives beside it. Every matched letter is lit, and the English name shows when that is what matched.
History, once per command.Each command line is one row, with ×3 when it ran three times.
Servers, with what they are.Beside the list, the highlighted host’s lines in ~/.ssh/config, its other names, its tags, the tabs on it and the tunnels to it. A click selects a server; a double-click connects. Clicking Mark as production no longer takes the keyboard out of the field.
Running moved into Tabs.The launcher’s Running scope is gone: tabs are under Tabs, and servers with no tab are under No tab in All, where ⏎ is Show in Running.
New The menu bar
Opsty’s mark.The lamp and the cursor from Opsty’s icon, in place of a generic dot. An empty ring at rest, a turning ring while something works, a lit lamp with the cursor blinking on your turn, and a cross when something stops. An agent working over ssh counts as working.
Click it for the Glance.The agent’s question with its first answer, sent only after Opsty reads the screen again; why something stopped, with Restart naming its command and Why?; what works; every server and tunnel with its one action; and Start again, what you usually start in each folder, put in a new tab and never run.
Right-click it for the menu.The same rows as the Running list, under the same names, each opening to its actions, every one naming what it does: Open, Copy Address · localhost:5433, Stop · kill 48211. Then Show Everything Running, Quick Terminal, New Window, Settings… and Quit Opsty.
Fixed
Explanations quote the line they read,reading from the end of the output. A phrase inside another program’s log is no longer read as “macOS blocked access”; with no match, Opsty quotes the command’s own last error lines rather than guess.
A stop’s red cross stays until you act:run something in the tab, press Clear, or close its failure card. The Running button, the list, the menu bar and the Dock count the same things, and a finished command never counts.
Restart if it stops is offered only for something meant to stay up:a server that listened on a port, or a dev server, watcher or worker. A chain of steps, such as a release script, is never offered it.
A command’s time stays on its own row,even when a blank row comes before its output.
Privacy What changed for your data
The picture of a server’s page is taken when you select that server in the Running list, a moment later and only while it stays selected, instead of when you hover. It is still loaded from your own Mac.
The menu bar’s Start again reads which commands you usually start in each folder from history.db, on this Mac. Nothing new is kept, and nothing new is sent.
The whole promise, file by file, is on the privacy page.
0.5.0Room to Move
macOS 13+ · Apple silicon
doclifesaju
subtank
Opsty now has as many windows as you want, and tabs and panes move between them without restarting anything: drag a tab out of the strip to give it a window of its own, drop it on another window to bring it back, or move a pane out of its split into a tab. Closing something by mistake is no longer final, and the shortcuts are the ones your hands already know.
New Windows
A second window, and a tenth.⌘N opens a window with one tab in the folder you were in. Every window is equal: closing one leaves the others alone, and the last one closed leaves Opsty running, ready for the next.
Tear a tab off.Drag a tab down out of the strip and let go on the desktop: it becomes a window where you dropped it. Its shell, scrollback, Ledger marks and whatever runs in it carry on; an agent mid-turn never notices. Move tab to new window in the Window menu does the same.
Bring it back.Drop a tab on another window's strip and a gap opens where it will land; drop it on a pane and it becomes that split's other half. Merge all windows gathers every window's tabs into the one in front.
Every window comes back.With Reopen last tabs on, Opsty reopens each window where it was, on the display it was on, with its tabs and splits.
Show all tabs.⇧⌘\ lists every tab in every window, the ones that need you first, with what each is doing. Type to filter; ⏎ goes there.
New Panes
Unsplit without losing a shell.Move pane to new tab takes a pane out of its split and gives it a tab of its own, still running. Split into tabs does it for every pane at once, and Join as a split with puts a tab back.
A handle for every pane.Bring the pointer to the top of a pane's left margin and a small grip appears: click it for the pane's menu, or drag it to another tab, another pane or out of the window. Right-click the margin, a tab or the + button for their menus.
Maximize a pane.⇧⌘⏎ lets one pane fill its tab until you press it again. The tab says 1 of 3 so the others are not forgotten, and a hidden pane whose agent asks you something still calls.
The rest of the toolkit.Equalize panes (⌃⌘=, or double-click a divider), move between panes by direction (⌥⌘← and the other arrows), grow one (⌃⌘→ and the other arrows), and swap two panes by dropping one on the middle of the other.
New Closing, and taking it back
Undo instead of a question.Close a tab with a dev server running and it goes at once, but the server keeps running, hidden, for ten seconds, with Undo: the tab comes back exactly as it was. An idle shell closes without a word, as before.
Reopen closed tab.⇧⌘T brings back the last tab you closed: still running if it is within the ten seconds; otherwise in its folder, with its old scrollback above the new prompt. Recently closed tabs are also under the + button.
⌘W closes what is in front.The pane; in a tab with one pane, the tab; in a window with one tab, the window. Close tab (⌥⌘W) and Close window (⇧⌘W) are in the Shell menu, and closing a window that still has something running names each thing before it stops.
Changed The shortcuts everyone else uses
Splits are ⌘D and ⇧⌘D,as in iTerm2, Ghostty and Warp; ⌘\ still splits right. ⇧⌘\ is now Show all tabs, as on every Mac.
Write to the agent moved to ⌥⌘⏎,because ⇧⌘⏎ maximizes a pane in every other terminal, and now here.
Tabs:⇧⌘] and ⇧⌘[ next to ⌃⇥, ⌘9 is the last tab, ⇧⌘I renames one, and ⌥⇧⌘[⌥⇧⌘] move it along the strip. The Session menu is now called Shell.
Fixed
Clicking a pane makes it the one ⌘W closes.Until now, clicking into the other half of a split gave it the keyboard but not Opsty's attention, so ⌘W, ⌘K and ⌘\ acted on the pane you had left.
⌃⇥ switches tabs.It used to walk every pane of every tab, so the next ⌘W could close a pane you could not see.
A tab's × closes the tab.With one busy pane in a split, it closed only that pane.
History no longer mixes up commands from different days,which could give yesterday's command today's exit status.
Forget the saved window stays forgotten,instead of being written again by the next keystroke.
0.4.0Worth Switching To
macOS 13+ · Apple silicon
Opstynowsubtank · Claude Code · Bash commandnpm install papaparse · Do you want to proceed?YesOpen Tab
Opsty now answers back. When an agent asks you something while you are in another app, answer it from the notification. The Running list now finds the servers no tab started, too. Come back after a while and each tab says what it did while you were gone. And Opsty now updates itself: this is the last version you download by hand.
Updates Opsty keeps itself up to date
Updates, without stopping your work.About once a day Opsty asks dl.opsty.dev whether there is a new version and downloads it in the background, with no notification and nothing over the grid. It never restarts by itself, because a restart would stop your dev server, drop your ssh session and interrupt an agent mid-turn. When an update is ready, a small button in the title bar says so; it lists exactly what a restart would stop and offers Restart and bring it back, Install when I quit or Later. After the restart, the Running when you left · earlier today sheet offers to start what was running, and one line says which version you are on now.
Check for Updates… is a real check.In the Help menu its label follows what the updater is doing, and once an update is ready it says Restart to Update to 0.4.1… Settings ▸ Advanced shows your version and when it last checked, with Check now. Settings ▸ Privacy turns the automatic check off; Check now still works.
The last download by hand.0.3.0 and earlier cannot update themselves. Download 0.4.0 once, drag it over the old copy in Applications, and from then on updates come to you: the first as a full download, later ones only the parts that changed. Opsty updates itself only when it is in an Applications folder.
New Answer it, and know what happened
Answer from the notification.When Claude Code stops to ask permission while you are in another app, the notification quotes its question word for word and offers Claude’s own first answer as a button. Clicking it sends that answer, but only if the same question is still on Claude’s screen; otherwise it just opens the tab. When an agent has simply finished, the notification has a reply field instead, and what you type goes to its prompt. Codex and Gemini get the reply field. Settings ▸ Helpers can turn the answers off and keep the notifications.
While you were away.Come back to the window after five minutes or more and one line per tab says what happened: turns taken, files changed, errors that came and went, and which tab needs you first. Hover a line for its timeline. It goes the moment you type, and hovering the tab shows it again.
What did that change?While a command or an agent runs in a folder on your Mac, Opsty notes the names of the files created, changed or deleted there. Hover the command’s mark for 12 files changed; click it for the list, and pick a file to place git diff -- <file> on your line. Names only, never contents, and never inside Documents, Desktop, Downloads or iCloud Drive.
The exact conversation, every morning.Two Claude Code tabs in one folder used to come back as claude --continue twice: the same, most recent conversation. Each tab now remembers its own and comes back as claude --resume with that conversation, named on the morning sheet.
Two agents, one folder.When two agents are editing the same checkout, Opsty says so once, and offers to open a split with git worktree add … placed and read back, so one of them can work on its own copy.
Agents on your server call you too.Claude Code running on a server over ssh now lights the tab’s lamp and calls you back when it is your turn, from the title it already sends. Nothing is installed on the server.
New Everything you left running
Every server, wherever it came from.The Running list now looks at every program your account runs that is listening on a port, not only your tabs’. A server an agent started in the background sits under that agent’s tab; one no tab owns, like the old node still holding :3000, is listed on its own, with its folder, when it started and Stop. “Port 3000 is already in use” names whatever holds it, and offers to stop it and run yours, with the command on the button.
Errors while it’s still running.When Vite, Next or tsc --watch prints an error and keeps going, the error gets a red mark and its tab a count. ⌘↓ walks to it, a card explains it in one sentence and names the program it came from, and when the program reports the fix the mark turns gray.
Peek at a port.Hover over a port on the list to see a picture of the page it serves. The page is loaded from your own Mac, in a hidden window that is allowed to talk to nothing else.
Keep it up.Arm a row on the list and, when that command stops, Opsty runs it again (the command it shows, in the same tab), saying so each time. Five stops in two minutes and it gives up, shows the error that keeps repeating, and offers its fix on a fresh line.
Forwards on the list.ssh -L forwards, and the LocalForward lines in your ~/.ssh/config, appear under their ssh session as addresses you can open or copy. Forward a port… is a small form that places the ssh -N -L command in a new tab.
Drop a file on a server tab.Dropping a file on an ssh tab used to type a path from your Mac into the server’s shell. Now Opsty opens a split on your Mac with rsync -av … host:~/ placed and read back; nothing is typed on the server.
New For anyone new to the terminal
Paste from AI, one step at a time.Paste a block of commands from a chat and it lands on zsh’s line as usual, not run. Opsty offers to walk it: the $ prompts and comments come off, each step is read back, and you press Enter for each one. If a step fails, the walk waits.
What is this?Select a word you don’t know, like EACCES in an error or -avn in a command, for one line on what it means, with its source: the manual of the program that actually runs, or the system’s own error table. No source, no explanation.
Touch ID for sudo, offered.The first time sudo asks for a password, Opsty points out, once, that macOS can use your fingerprint instead, and can place Apple’s one-line setup on your line when the command finishes. Opsty never edits the file itself.
Six more command cards.pushd, popd, export, source, alias and unset, the shell’s own commands, which AI instructions often ask for, checked against zsh’s manual, zshbuiltins(1). That makes twenty-six.
New Around the edges
A lamp in the menu bar.An empty ring at rest, a turning ring with a count while something works, a filled dot when something needs you, from any app. Its menu is the Running list.
Quick Terminal.⌥Space drops Opsty down from the top of the screen over whatever you are doing, with the tab that needs you in front; press it again and it is gone. The shortcut is in the menu and can be changed or switched off.
Copy for an AI chat.A command’s margin mark has Copy for an AI chat: the command, folder, exit code and the useful part of its output as Markdown for a chat, with tokens and keys removed by the same rules as history, and it says how many. Or copy just that block as a picture.
Rewind.⇧⌘← opens a timeline under the pane, with commands as ticks and errors in red. Drag back to see the tab as it looked then, read-only, even an agent’s full screen that has since been redrawn. esc returns to now. Kept in memory, never written to disk.
Tabs you can drag.Drag a tab along the bar to reorder it, or onto a pane to split it. Its shell, scrollback and running server are untouched.
Bring your look.Settings ▸ Appearance imports your Terminal or iTerm2 colors. Opsty runs its own contrast check on each profile, offers to nudge an unreadable color to the nearest readable one, and says which it changed. The original is never touched.
Opens from anywhere.A Finder Quick Action opens a tab in a folder; so does dropping a folder on the Dock icon, or opsty . from another terminal or editor. Opsty can also open ssh:// and x-man-page:// links: a link places its command and reads it back, and never runs it. Each is offered in Settings ▸ Advanced, and nothing changes until you click.
New A new feel
Settings is its own window.⌘, from anywhere opens it, with five panes: General, Appearance, Helpers, Privacy and Advanced. A change applies to every window at once, and the opacity slider previews on the terminal window itself.
One glass for everything that floats.The Tab popup, the command helper, failure cards, the Running list, sheets and toasts now share one material: a clear edge around a dense, readable center, a small lip that points at the line it belongs to, and a selection that slides between rows. Each is measured once it is drawn, so none covers the line you are typing.
One launcher.The command palette, History and Connect are one field now, with scopes: All, Commands, History, Servers and Running. Every old door opens it on its own scope: ⇧⌘P on Commands, ⇧⌘H on Servers, ⇧⌘F on History, and a new search button in the title bar on All. Each row says what Enter will do.
Fixed What was broken
In the command helper, the highlighted row could walk off the bottom of the list as you pressed ↓, and a row under a resting mouse could take the keyboard back. Every list now keeps its row in view and follows the mouse only when it moves.
The cd card named /usr/bin/cd’s manual. cd is the shell’s own command; its card now cites zshbuiltins(1).
With ghost text on the line, the read-back described the line without it, which looked like a contradiction. It now also says what taking the ghost text with → would do.
Dropping a file on an ssh tab typed a path from your Mac into the server’s shell.
The Tab popup and the command helper were placed by guessed sizes and could land over the line.
The opacity slider’s recommended mark hid under the slider’s thumb. It sits above the track now.
Build Under the hood
Electron 44.6.0, electron-builder 26.17.0 and electron-updater 6.8.10, every version pinned exactly, in step with LonelyDuck’s other Mac apps.
Each release now ships a zip and an update feed beside the disk image; installed copies fetch the zip, and the disk image is what you download.
From 0.4.0 Opsty is freeware: free for any use, on any number of Macs, and not open source.
Privacy What changed for your data
Opsty now makes one network request of its own: the update check, about once a day, to dl.opsty.dev. It sends no account, no per-install number and no version of Opsty or macOS. Downloading an update names the file it fetches, and fetching only what changed can name the version you had. Settings ▸ Privacy turns it off.
Port previews load a page from your own Mac; every request that would leave it is cancelled.
lsof now asks about every program your account runs that is listening on a TCP port, not only your tabs’ programs, and ps about every process’s parent, so the Running list can name servers no tab owns. ps and lsof are still the only programs Opsty starts on its own, with name lookups off; when it downloads an update it also runs sysctl and uname once, and installing the update runs macOS’s ditto and Squirrel’s ShipIt. Settings ▸ Privacy goes back to asking about your tabs only.
New reads, each named on the privacy page: the names of files that change in a folder while something runs there; the names and dates of Claude Code’s conversation files for a tab’s folder, never their contents; three files in /etc/pam.d the first time sudo asks for a password; and, only when you click Import…, Terminal’s and iTerm2’s preferences.
New writes: themes/ in ~/.config/opsty; the updater’s cache in ~/Library/Caches and a few small files in ~/Library/Application Support/opsty; and, only when you click, the Finder Quick Action in ~/Library/Services and Opsty as the app for ssh:// and x-man-page:// links. running.json now also keeps which Claude Code conversation a tab was in.
Copy for an AI chat removes passwords, tokens and keys from a command’s output, as history does from commands. Rewind’s snapshots, the away summary and changed-file names stay in memory and are never written.
Opsty is now the terminal you don’t have to watch. Leave a dev server, a coding agent or an ssh session running and look away: every tab says what it is doing, Opsty tells you when one needs you, and the next time you open it, it offers to start what was running. The explanations from 0.2.0 stay, and now read back what you paste.
New What you can do now
Tabs that say what they are doing.After each tab’s name, a quieter word: an agent’s task (“Fix login bug”), your turn, a server’s port (:5173), stopped or done. The lamp has a shape for each (a turning ring while an agent works, a violet pulse when it is your turn, a red cross when something stopped), so none is color alone.
Agents recognized, with nothing to install.Claude Code, Codex and Gemini CLI are known by the program in the tab, and what they are doing is read from the window title they already set for every terminal. No plugin, no hook, no change to their settings.
A notification only when you are elsewhere.When an agent finishes or asks you something, a program rings or sends a notification, or a long command stops or finishes, and you are in another app or another tab, a macOS notification names the tab. Clicking it opens that tab. The Dock icon counts what is waiting. Settings ▸ Privacy ▸ Notifications ▸ When a tab needs me.
The Running shelf.Running in the tab bar, or ⇧⌘R: every server, agent and ssh session in any tab, with its port, address and how long it has been up, and Open, Go to, Stop and Restart. Closing a tab that is serving a port now says which address will stop answering.
The port card names the tab.“Port 3000 is in use by your tab ‘shop’.” Go to that tab, or Stop it and run here, which sends ⌃C there and runs your command again once the port is free.
A server that stops is news.A command that ran for five seconds or more and then failed is treated as something that stopped: the tab says stopped, a notification gives the exit code and, when Opsty recognizes the error, the reason, and the Running shelf offers Restart.
Welcome back.The next time Opsty opens, it offers to start what was running: dev servers ticked, agents offered unticked as claude --continue or codex resume --last. Start opens each in its own tab and folder. Nothing on a host marked as production is ever recorded. Settings ▸ Privacy ▸ Notifications ▸ Offer to start what was running.
Made for the agent you run in it.⇧↵ is a new line inside a program instead of submitting a half-written prompt. Write a message (⇧⌘⏎, or the button under the grid whenever an agent is in front) is an ordinary Mac text box where Korean composes normally, sent as one paste and then Enter. ⌘V with a screenshot on the clipboard reaches the agent as ⌃V. Copy as clean text (⇧⌘C, Edit menu) drops the indent, trailing spaces and soft wraps a terminal draws. Use ⌥ as Meta is a visible switch in Settings ▸ Advanced ▸ Keyboard, off by default.
Pasted commands are read back.When a line you pasted is one Opsty warns about (rm -rf, git reset --hard and the rest), the warning begins You pasted this ·, before you press Enter. And curl … | sh now has its own sentence: “Runs a downloaded script before you can read it. Make sure you trust the address.” Opsty says so and never holds your Enter.
Clickable links.Opsty asks programs to print their links as links, and a link to a file opens the file.
Fixed What was broken
A tab you were not looking at was resized to 5 rows × 11 columns while hidden, so Claude Code redrew itself for eleven columns and a dev server’s logs from that time wrapped at eleven. Hidden tabs keep their size.
⇧↵ was Enter, so in Claude Code, Codex and Gemini it sent a half-written prompt.
The “your turn” lamp never lit: nothing set it.
The title a program sets, where an agent says what it is doing, was replaced by the program’s name within a second.
Clicking a notification brought the window forward but not the tab it was about.
The Ledger’s marks, such as “● running 12.0s”, were drawn over full-screen programs, Claude Code’s interface among them.
An Opsty started from inside Claude Code passed Claude’s session markers to every shell, so Claude Code run in Opsty took itself for a sub-session and stopped saving its transcript.
Build Under the hood
Electron 44.5.1, TypeScript 7.0.2 (the native compiler), Biome 2.5.14 and Vite 8.3.0, every version pinned exactly.
Third-party license notices ship inside the app, as THIRD_PARTY_NOTICES.txt in Opsty’s Resources folder.
The shells Opsty starts get FORCE_HYPERLINK=1, and lose any agent-session variables Opsty itself inherited.
Privacy What changed for your data
Opsty now starts macOS’s lsof, as well as ps, to learn which TCP ports the programs in each tab are listening on. It asks about those programs only, with name lookups off, so it still makes no network request.
A new file, ~/.config/opsty/running.json, holds the commands running when Opsty closed: never a production host’s, with secrets removed. Switching off Offer to start what was running deletes it at once.
Notifications are macOS’s own, shown on this Mac.
The whole promise, file by file, is on the privacy page.
0.2.0The first public release
macOS 13+ · Apple silicon
The first public release. Fewer things, drawn well: three reasons to install it, a small set of things around them, and one material for all of it. Earlier builds were only ever run by the author and a few testers; the fixes below are measured against those.
New What’s new
Frost, a new look.One row of chrome (tabs, and three buttons: Connect, History and ⚙), frosted like Finder and Safari, over a text area that stays nearly solid so it is always readable, and stays frosted when you click into another app. Blur off lets the desktop show through sharp instead, like Terminal with its blur at 0. Reduce Transparency makes it solid.
Eight themes in four families.Lamp, Fjord, Ember and Ink, each in a light and a dark version that follows macOS, with an opacity slider down to 30% that marks where text stops being readable and turns amber below it. They replace the eleven themes of earlier builds.
Fonts and spacing.A font menu that lists the monospaced fonts on your Mac, each drawn in its own face; Korean fits two cells in any of them. Rows are as tight as Terminal’s by default, and Line spacing loosens them.
Command cards.Type one of twenty everyday commands and a card opens under the line. Its parts (options, source, destination) are tabs you click; one list shows what fits the part you are on, with each option explained; browsing folders types nothing until you choose one. A last line says in plain words what Enter will do: for rsync and cp, whether the folder itself or only its contents is copied, as a choice you can flip. Each card says where its words came from and which manual on your Mac its options were checked against. Whatever you choose is typed into your shell as keystrokes.
Failure cards.Twenty common errors are explained in one plain sentence, with one fix placed on the line and never run. Mistype a command’s name and Opsty asks whether you meant the one you have.
The Ledger.Every command gets a green or red mark in the margin, with its exit code and duration at the end of its row. Hover it to copy the command, copy its output, or put it back on the line to run again. Enter runs it; ⌘↑ and ⌘↓ move between commands.
History.Search everything you ran, grouped by day, in Korean too: 배포 finds 배포했습니다. Enter puts a command on the line; it does not run it. ⇧⌘F.
Connect and production.Your servers from ~/.ssh/config, searchable; a row opens ssh in a new tab. Mark as production is a button now, not a file to edit by hand, and the tab bar turns red for as long as you are on that host. ⇧⌘H.
Find in scrollback.⌘F searches what is on the screen and above it.
Fixed What was broken
Tab with only one possible answer doubled what you had typed: cd sr became cd srsrc. zsh now inserts it, exactly as it would in Terminal.
The Tab list showed junk rows first, left spaces and parentheses in chosen names unescaped, and had no descriptions for rsync’s options. Rows now come from zsh’s own matching, are inserted by zsh with its own quoting, and carry zsh’s descriptions; a second Tab gives you zsh’s own list.
Pasting, esc., undo and other edits the shell did not report left Opsty’s help working from an old line, so the next click typed garbage.
The command card swallowed esc at the prompt, its labels looked like buttons but did nothing, and choosing a folder kept the picker open and added the next choice as an extra operand.
The glass was nearly opaque and turned flat gray whenever you clicked into another app. Rows were loose: 1.8× the text size, against Terminal’s 1.2×. The font was a text box.
A shell opened from the Dock or Finder had no locale, so the line editor counted bytes instead of characters. It now gets your Mac’s own UTF-8 locale, as in Terminal.
Command rows came back after clear, ⌃L or ⌘K and covered the prompt.
⌘F opened an invisible dialog that swallowed everything you typed afterwards.
Every Copy button failed in the installed app.
Commands containing backslashes were recorded with the backslashes doubled, so Run again ran a different command.
Every tab was called “zsh”. Tabs are now named after their folder and have a close button.
Notes and cards pinned to the bottom of a pane covered the prompt, and sometimes the very error they were explaining. Everything that floats is now placed by one layer that keeps clear of the line you are typing.
A dark strip along the bottom of the window, no margin on the left, and a grid one row taller than its box, which made the whole window scroll.
Opsty’s shells kept a second, separate history, so ↑ never found what you ran in Terminal. They now use your shell’s own history file.
Removed or later Taken out of this release
Lenses, the tables drawn over command output: later.
Compare with the previous run: later.
Pins and incident notes, and exporting them: later.
The cockpit (the header, footer and side drawer for people who run servers all day) and tunnels: later.
The update check: removed. Help ▸ Check for Updates… opens this page instead.
Windows and Linux, and fish: later. 0.2.0 is for the Mac, with zsh and bash.
Intel Macs: not in 0.2.0. It is built for Apple silicon (M1 or later) only.
Opsty’s own zsh: removed. A new tab opens your own login shell, with your dotfiles, as Terminal does.
Privacy What changed for your data
Opsty makes no network requests at all. The update check is gone.
History keeps the command, folder, host, exit code and duration, and no longer the output.
Passwords, tokens and keys in common formats are removed before a line is written. Earlier builds promised this without doing it.
opsty.dev no longer loads fonts from Google.
The font menu reads the names of the fonts installed on your Mac when you open it: nothing else, and nothing leaves the Mac.
The whole promise, file by file, is on the privacy page.