Move a session to another folder
Move a session, agent and all. You ask Claude to start a new project next door, it makes the folder and keeps working there, and the session, its Git panel and its sidebar folder stay behind on the old project. Change Directory in the session menu, or wortel cd <folder> from inside the session, now moves it. The shell changes to the new folder, keeping its scrollback, and Claude picks up the same conversation there. The session is filed under that folder in the sidebar (a new folder if none covers it, the way Open Folder makes one), and the Git panel and Files follow.
It waits for the right moment. A move never cuts Claude off. It happens once the turn has ended, not while Claude waits on a permission or a question, and not while you’re typing into its box. Until then the session’s row says where it’s going. Claude can ask for the move itself, and Wortel tells it straight away what will happen, including any background task that will stop. Run the command again with another folder to change the destination, or with the folder you’re in to call it off.
Claude Code is the agent that can move today. Other agents, and a program running in the foreground like an editor or a dev server, are refused with a reason rather than interrupted.
The right colours after sunset, and a calmer Git panel
Dark stays dark. When your Mac switched to dark mode in the evening, Claude Code could stay on its light colours, with pale diff blocks and a white prompt bar on a dark window. It asks the terminal for its background the moment the theme changes, and Wortel answered with the old one. The new colours are now in place before the question arrives.
The Git panel stays put. The panel shows the folder the session belongs to, and in a worktree session (New Worktree Session, Fork, Open Branch), that worktree’s changes. An agent working in another worktree of the same project no longer pulls it along, and the “changes in …” hint that pointed elsewhere is gone. When you cd into a different project, the panel follows you there, so a commit always lands in the project you’re in. To look at another worktree, pick it from the worktree chip and press Back to return.
Branch names in every repository. In a repository that keeps its branches in git’s newer reftable format, worktree rows said “.invalid” instead of the branch. Wortel now reads the branch from there too, still without running git.
Also in this release: the header no longer has an “Open Session” button while you look at another worktree. Back takes you home, and Open Branch (⇧⌘O) opens any branch in a session of its own.
A new icon, and one banner per question
A new icon. Wortel has new artwork in the Dock, in the app switcher and on its notifications.
One banner per question. While Codex waits on an answer it blinks its terminal title, and every blink put a fresh “Action required” banner on screen for as long as the question stood. The first one is now the only one. The same holds for anything else that repeats itself, like a program ringing the bell every few seconds: it gets one banner, and a new one only when it has something new to say.
Worktrees, made simple
New Worktree Session (⇧⌘N). A new session in a worktree of its own, on a fresh branch from your default branch, ready at once. Once the session has a name, its branch is named after it too. The files a project needs to run but git ignores, like .env, are copied in; list any others in a .worktreeinclude file.
Open Branch (⇧⌘O). One field for any branch, worktree or pull request. Type a name and Wortel goes to the session already there, continues a closed one, opens the worktree, checks the branch out in a new worktree, or creates it. Each row says which before you press Return, so a branch never gets a second worktree. Type #123 or paste a GitHub or GitLab link to check out a pull request.
Closing keeps your work. Closing a worktree session (⇧⌘W, the ×, or exit) puts it away: the worktree, the branch and the agent’s conversation all stay. Find it with ⇧⌘O and it picks up where it left off. When there’s nothing in it worth keeping, the worktree goes to the Trash instead. Clean Up Worktrees now knows a squash merged branch is merged.
Fork Session (⌥⇧⌘N). The session as it is, in a worktree of its own: staged, unstaged and new files, and the agent’s conversation, forked. Try something without touching the original.
Any worktree, whoever made it. Worktrees you made yourself or with another tool show up in ⇧⌘O and open as sessions, and Wortel never deletes one it didn’t make. A repository can choose where its worktrees go, with Worktree Location… in the folder’s menu or git config wortel.worktreePath.
Ports of their own. Every session gets ten ports to itself, the first in WORTEL_PORT, so two agents running a dev server in two worktrees don’t both want port 3000.
Know why a session stopped. A Claude turn that ended on an API error now says it failed, with the error, and one waiting on a question or a plan says it needs you. Both used to read as finished. While any session is waiting on you, a menu bar item shows how many and lists them.
Also in this release: hold ⌘ to see each session’s ⌘1 to ⌘9 shortcut on its row; closing the last session leaves an empty window instead of quitting; drop a folder on the sidebar or the Dock icon to open it; the shell in a worktree session starts in its worktree, never in /; Claude follows the Mac between light and dark again after Wortel restarts; the git panel names other worktrees after the session in them; very long commands show in the title too; and the pull request button in the git panel is gone, with the network check it made every minute.
Agents come back where they were
The right conversation, every time. After a /clear or /resume inside Claude Code, a session that had to be brought back reopened the conversation Claude was started in, not the one it was in. Wortel now keeps track of the conversation while the agent runs.
Nothing left behind. When the process that keeps your terminals running was stopped, an agent that happened to finish closing first was taken as one you had quit, and stayed closed. Each terminal now comes back when its own shell ends, and a resume counts as done only once the agent is running again.
Started the way you started it. A resumed agent keeps --dangerously-skip-permissions, its model, its permission mode, an environment variable in front of it, and a wrapper like devx pi. Before, it came back asking for permission at every step. A command line with more than one command in it is typed for you rather than run again.
Agents found in more places. Aliases, npx and bunx, cd project && claude, and an agent you suspend with Ctrl-Z and bring back with fg are all followed now. ssh host claude and tmux new claude are no longer mistaken for an agent running in Wortel.
Typing exit ends the session. A shell that ended used to leave a terminal that did nothing.
Also in this release: a full restore no longer holds the window up for half a second per session; the process that keeps your terminals is replaced once it holds none when it came from an older version, which is what kept Full Disk Access from reaching your shells after an update; a missed reply can no longer hand one session’s terminal to another; and prompts are faster in zsh and bash.
Colours, and a Fork that shows its work
Colour a session. Right-click a session, or open its ”…” menu, and pick a colour: a bar at the edge of its row marks it, say yellow for a review waiting on CI. Only you take it off. From a terminal, wortel mark yellow does the same, and wortel mark none clears it.
Fork shows its work. The new session appears the moment you press Create, and its page says the worktree is being prepared while you keep working in your other sessions. Its terminal opens when it’s ready. If git refuses, the page says why, with Try Again. Forking a repository that uses Git LFS works now too: Wortel couldn’t find git-lfs when it was installed with Homebrew or Nix.
Permissions. Wortel ▸ Permissions… shows whether notifications are on and whether Wortel has Full Disk Access, with a button to change each. While notifications are off, a hand with an orange dot in the sidebar says so.
Camera, microphone and the rest. A program you run in Wortel that needs the camera, the microphone, your contacts or another app now gets the usual macOS prompt. Before, macOS turned it down without asking.
Clean Up Worktrees, faster. The list appears at once with each branch’s name, checks several worktrees at the same time, and each row says what it’s doing.
Also in this release: a worktree session always shows its branch under its name, never the folder you happen to be in. And dragging a session shows the whole row.
Terminals that come back on their own
Terminals that come back on their own. An app you open from a Wortel terminal can take Wortel’s terminals with it when you force quit it from its Dock icon. Wortel used to keep showing those terminals as if nothing had happened, and the agents in them were lost. Now Wortel notices right away, starts each terminal again and brings every agent back into the conversation it was in. A message says when it happened, what came back, and what didn’t, like a dev server you’ll need to start again.
Branches, and where they are. The branch list now groups branches by what a click can do: this folder, branches checked out in other folders, branches to switch to, and remote ones. A branch an agent has in its own folder shows that folder, and clicking it shows that folder here. When nothing there can be lost, Bring Here moves the branch into the folder you’re in.
Git errors you can read. When git refuses something, the Changes pane and the branch list say what happened and what to do about it, in plain words, and you can dismiss the message.
The pull request in the header. If the branch has an open pull request on GitHub, the header shows it, and one click opens it. A pushed branch with none offers Create PR. This uses the gh command, when it’s installed and signed in.
Stop All. With two or more things running in a session, the heading of its running list offers Stop All.
Also in this release: a branch name typed with spaces for a new worktree session becomes one git accepts. A session whose folder was deleted says so under its name. And Wortel does less work while it’s behind other apps, especially in repositories with many worktrees.
Closing a file takes you back
Closing a file takes you back. Double-click a file in Changes or History, read it, close it, and you’re back where you opened it, not on whichever tab happened to sit next to it. If you switched to another tab in the meantime, the neighbouring tab comes forward, as before.
Menus that say what they’ll do. Check for Updates Automatically and Share Anonymous Usage Data in the Wortel menu now show a checkmark when they’re on. Show and Hide commands for the sidebar, the panes and the side column now name what they’ll actually do, Pin Session reads Unpin Session for a pinned one, and commands that don’t apply right now are greyed out.
Every agent back in its own conversation
Every agent comes back where it was. If Wortel’s sessions end while it’s closed, for example after choosing Stop Running in Background on its Dock icon, reopening Wortel resumes each agent into the conversation it was in. Claude, Pi and Codex come back in their exact conversation, even with two sessions of the same agent in one folder. Other agents continue their latest conversation, as before.
No freeze on reopening. Wortel could hang on launch when a session had been busy while it was closed, for example an agent that kept working. It now reconnects right away, however much happened in the meantime.
A shell that lost its agent gets it back. When an agent ended while Wortel was closed but its terminal stayed open, the session used to come back as a bare prompt. Wortel now starts the agent again in its own conversation.
Updates that land. Updates download quietly in the background. When one is ready, a download icon appears in the sidebar’s bottom bar, and Restart Now takes a second or two, with every session back. Automatic checks are on; you can turn them off in the Wortel menu.
Shortcuts that match other Mac apps. ⇧⌘[ and ⇧⌘] switch tabs, as in Safari and Xcode. ⌥⌘↑ and ⌥⌘↓ move between sessions. ⌃⌘1, ⌃⌘2 and ⌃⌘3 open Changes, History and Files.
Also in this release: Wortel keeps a short log of how each agent exited, so a session that ends unexpectedly can be explained.
A clearer "working", and sections that fold
Working, at a glance. A session with something running used to show a small grey dot breathing slowly, which in dark mode came out nearly black on a dark sidebar. It’s now three small dots in a soft wave, the way a chat app shows someone typing: clearly busy, without asking for anything. The coloured dots still mean something needs you.
Pinned and Sessions fold. Click the Pinned or Sessions header to fold it away, as you can a folder, and Wortel remembers it. A folded section shows a dot when a session inside needs you, and unfolds by itself when a new session lands in it.
Headers you can point at. Folder, Pinned and Sessions headers light up under the pointer like session rows do, so it’s clear they’re there to click.
Also in this release: every status dot in the sidebar now follows light and dark mode when you switch between them.
Tidier menus, and a Clean Up that shows what it cleans
Clean Up Worktrees, readable. In 2026.41.2 the list in Session ▸ Worktree ▸ Clean Up Worktrees… could collapse to nothing, leaving only the button. It now shows every worktree Wortel made, grouped by repository, one line each: tick what should go, see at a glance what’s clean and what’s kept, with “17 changes” or “In use” on the ones that stay. Rest the pointer on a row for the details, or right-click it to show it in Finder. One switch decides whether the branches Wortel made go too, and only ever the ones with nothing to lose.
Menus that read like a Mac app’s.
- A new Tab menu holds everything about tabs: new terminal and browser tabs, moving between and moving tabs, reopening, and Close Tab.
- The Session menu is down to what it’s about: starting sessions and folders, moving between sessions, the selected session’s own commands, and closing it. ⌘1 to ⌘9 still switch sessions, without nine rows for them.
- The worktree commands sit together under Session ▸ Worktree.
- Move To is greyed out when there’s nowhere to move the session.
- View is in the order of the window: the sidebar and panels, the source control panes, the browser, then text size.
- Show Sidebar and Hide Sidebar say which one they’ll do, Find has its own submenu, and the Wortel menu has Services and Show All, as every Mac app does.
Every keyboard shortcut works as before.
Also in this release: the usage-data note under the ⓘ in the sidebar could stay on screen and not go away when it first appeared while Wortel wasn’t the app you were in. It now closes when you switch to another app, and only appears once you’re back in Wortel.
Lighter in the background, and nothing left behind
Much less work in the background. The source control panel used to re-read every repository it had ever shown each time a file changed, and to count the changes in every worktree on almost every switch. On a big repository with agents busy in a few worktrees, that could keep several cores busy and the fan spinning. Now only the repository you’re looking at is read. The others note that something changed and catch up when you come back to them, with a small spinner while they do. The Files pane does no work while it’s hidden.
Switching sessions is lighter. Moving between two sessions whose side columns differ no longer resizes every terminal in the app, which made every agent redraw its whole screen. A terminal takes its size when you show it.
Worktrees are cleaned up, safely. Closing a session in a worktree now says what’s in it and what will happen to it, and Session ▸ Clean Up Worktrees… lists every worktree Wortel made. One with nothing unsaved is removed, folder and branch. One with commits that exist nowhere else keeps its branch unless you tick it. One with uncommitted changes, or something running in it, is kept, and Wortel says why. Folders go to the Trash, so nothing is gone for good.
Nothing left running.
- When your git settings turn on its file watcher, Wortel no longer starts one for every repository it looks at. They never exited, and piled up.
- Closing a session you hadn’t opened since launch now ends its shell, instead of leaving it, and any agent in it, running out of sight.
- A shell Wortel lost track of comes back at launch as a Recovered session if something is running in it, and is closed if it’s idle.
- A fetch, pull or push that hangs is stopped after five minutes, and anything git started stops with it when you quit.
ssh sets up once. Connecting to a host installs its terminfo the first time only, instead of printing “Setting up xterm-ghostty terminfo” and leaving a folder in /tmp on every connection.
Also in this release:
- Pasted images are cleared from the temp folder after a day.
- If the list of sessions can’t be read, it’s set aside instead of being overwritten.
Window tiling is back, and the browser keeps its size
Window tiling is back. Since the new titlebar, Fill, Center and everything under Window ▸ Move & Resize were greyed out, and their shortcuts (fn-⌃C to center, fn-⌃F to fill, fn-⌃ and an arrow for a half) did nothing. They work again. Dragging a tab in the titlebar still moves the tab, not the window.
The browser keeps its size. A browser in the side column could come back at its narrowest after you switched to another session and back. And once you had hidden and shown the sidebar, switching the column between the browser and Files or Changes could make it jump in width. Both are fixed: the column stays the width you gave it. If a session’s browser already got stuck narrow, drag it wide once and it stays.
A browser that behaves, and files open where you drop them
A browser that behaves like one. Signing in with Google, and sites like Figma, work now: the browser introduces itself the way Safari does, and a page’s sign-in window opens as a real window that can report back and close itself. A page’s own cursors show, so Figma’s hand appears when you pan. Holding a key a page doesn’t use, like space to pan a canvas, no longer beeps. ⌥⌘I opens Web Inspector, and ⌥⌘I again puts it away. A page still gets your shortcuts first, as in Safari and Chrome, except quitting, closing, a new session and moving between sessions, which no page can take from you.
The browser takes the resize. With a browser in front of the side column, making the window bigger or smaller changes only the browser, and your terminal holds still. With Files, Changes or History in front, the terminal takes it, as before.
Drag a file where you want it. Drag a file out of Changes, History or the file tree onto any tab row, or onto a pane that isn’t a terminal, and it opens there as a tab. Dropped on a terminal it types the file’s path, as it always has, which is how you hand an agent a file.
One ”+” everywhere. The bottom strip’s ”+” sits right after its tabs and offers the same menu as the side column’s: a terminal, a browser, or one of the git and file panes, opening in that row.
Worktrees, said plainly. When the repository has more than one worktree, a chip beside the branch says which one you’re looking at, and its list shows what’s in each. Looking at another one, an agent’s for instance, changes nothing on disk: the header says so, the branch can’t be switched from there, and Back takes you home. The branch menu only switches branches now.
A calmer sidebar. A session waiting on you is its coloured dot again, without a second line making the list jump each time an agent finishes; rest the pointer on the row to read what it said. The dot for a session that is working is easier to find.
Also in this release:
- History keeps room for the commit subject in a narrow column, letting the author, the hash and then the age go first.
- macOS no longer offers to fill a verification code from Messages or Mail over the terminal. A sign-in page in a browser tab still gets it.
- Agents stay in the right light or dark palette after a restart. A second copy of Wortel, such as a test build, could undo what the running one knew about your sessions; now a second copy brings the running one forward instead.
- Usage reporting now also counts which kinds of tabs are opened and where, whether ⌘P ends in a session, a command or nothing, whether a commit’s message was typed or drafted on your Mac, and whether a file preview opened as a tab or a window. Never what is in them. The full list is at wortel.sh/privacy, and the switch is the ⓘ at the bottom of the sidebar.
Everything is a tab, and a calmer window
Everything is a tab. A session used to be one terminal with a panel beside it. Now it has three rows of tabs: the main area with the session’s own terminal, a column beside it, and a strip under the terminal (⌘J). A tab can be a terminal (⌘T opens one where you are, ⌘D in the column, ⇧⌘D in the strip), a browser, a file, or one of the git and file panes, and any of them can be dragged to any row. ⌘W closes the tab in front of the area you’re in, ⇧⌘T brings back the last one you closed, and resting the pointer on a tab shows what’s in it: a terminal’s last lines, the page, the top of the file.
A browser beside your work. ⇧⌘L opens a browser tab. Its address field lists what your sessions are serving and completes as you type, and a port on its own is enough. ⌘L goes to the address, ⌘R reloads from anywhere, the terminal included (change something, ⌘R, look), and the button beside the address opens the page in your own browser.
Tabs open where you put them. Files and browsers open in the column until you move one somewhere else; from then on, that kind opens where you last moved one, per session. ⌥-click a file or a server to open it in the main area just this once.
A calmer window. Wortel draws its own titlebar now: one flat band with the tabs in it, the desktop showing softly through the sidebar, plain white pages for the terminal and the column, and fewer buttons, each beside what it controls. Panes open and close in one smooth motion, with the terminals resizing once when they land instead of on every frame. The sidebar runs up to the traffic lights as one surface.
The sidebar, rethought. Pin the sessions you live in (⌥⌘P, or the ”…” that now appears on every row) and they stay in a Pinned section at the top. Sessions in no folder get a section of their own. Rows are roomier, a session that is waiting on you says what for on a second line and for how long, a long name slides into view when you rest the pointer on it, and renaming happens right on the row. Mark as Unread (⇧⌘U) flags a session to come back to. Folder headers lose their path and gain a ”+” for a new session in that folder, and a ”…” for the rest.
⌘P finds anything. Type a few letters of a session’s name, folder, branch or directory and Return takes you there. With nothing typed, Return goes back to the session you were in before this one. The same box runs any command in the menus, and ⇧⌘P shows commands only.
One menu for a session. The ”…” in the titlebar, the ”…” on its sidebar row and its right-click menu are the same menu now, with icons: rename, move to a folder, pin, mark as unread, fork onto a branch of its own, show in Finder, copy the path, close. Fork is in the Session menu too.
Git follows the session, and the work. The git panes always show the session you’re in. When an agent works in a worktree while your terminal stays in the main checkout, the header says so (“sidebar has 16 changes”) and one click shows that checkout, for that session, until you go back. The branch list starts with every checkout of the repository, and the commit box is a single line until you start writing.
You can see where the keyboard went. Moving between areas with ⌘] and ⌘[ briefly lights the edge of the area you land in, and a list’s selection is blue only while that list has the keyboard, grey otherwise, as in Finder.
Shortcuts you already know. The layout follows the editors and Codex: ⇧⌘E for files, ⌃⇧G for source control, ⌥⌘R to rename a session, ⌘G for the next match. ⌥⌘E and ⌥⌘G keep working. ⌘/ opens the full list, and the Help menu’s search field finds any command by name. ⌘A selects all in a text field or a page.
Also in this release:
wortel renameandwortel notifywork from any terminal in the session, not only its own.- The running jobs list is smaller and reads like a menu.
- A click anywhere on a row in the file tree selects it, not only on its name.
- The terminal’s padding is closer to the edges, as in iTerm.
An agent follows light and dark again
An agent follows light and dark again. An agent asks the terminal once, when it starts, to be told whenever the Mac changes appearance, and from then on it trusts the terminal to say so. Your sessions survive a Wortel restart while their terminal does not, and the new one was never asked, so nothing was ever said. The agent went on painting the palette it chose hours earlier, which is how a dark diff block ends up on a white screen, or a white prompt box on a dark one. Nothing recovered on its own, because the agent had no reason to ask twice. A resumed session now carries that request across and is told what the appearance is as soon as it comes back, so an agent left running overnight is in the right colours in the morning.
This is the same fix as the pasted paragraph in 2026.38.5, one setting further on: a session outlives the app, its terminal does not, and everything the program still believes has to be said again.
A pasted paragraph is one message again
A pasted paragraph is one message again. Paste a few lines into an agent’s prompt and each line could arrive as a separate submitted message, filling its queue. A terminal only wraps a paste as one block when the program has asked it to, and your sessions survive a Wortel restart while their terminal does not: the new one started with none of the settings the agent still believed were in place. Wortel now remembers what each session’s terminal has been told and says it again on reattach, so a paste stays a paste. The same fix covers shift+enter in an agent’s prompt, which could turn back into a submit for the same reason.
A server the agent keeps to itself is still your server. Some agents run commands in their own process group rather than giving each one its own: goose, Kimi, Factory droid, and Pi through an extension. A dev server started that way was counted as part of the agent, which meant it was missing from the toolbar pill, missing from the list, and not stopped when the session closed. It is now listed on its own, with its address, and stopping it can never reach the agent it was started from.
A server handed to the system is found again. nohup npm run dev &, the shape agents reach for most, hands the server to macOS the moment the command returns, leaving nothing pointing back at the terminal it came from. Wortel now recognises those by the session they were started in, so they appear in the pill within a scan instead of turning into a leftover nobody owns. This works for anything serving a port, including a plain python3 -m http.server in a subshell.
A project named after your agent is not your agent. A server in a folder called claude-demo, or a vite inside pi-site, was read as the agent itself and disappeared from the list along with it. Only the program’s own name counts now. Wortel also recognises Kimi, Qwen, droid and Copilot, which previously appeared as ordinary rows with a Stop button on the conversation.
A row shows a command, not your environment. An agent that renames its own process left parts of its environment in the row’s name, including things like an API token. Rows now drop environment values and show the command.
A server belongs to its session
Closing a session stops what it started. Closing used to hang up the shell and leave the rest to chance. Anything started with nohup or disown, and any dev server that detaches itself, ignored that and kept running with no session attached, still holding :3000 with nothing on screen to say so. The close dialog was already telling you “Closing stops” those servers; now it does.
Wortel remembers where a server came from. Once a server has been seen running in a session, it stays that session’s, even after it leaves the shell. It shows up in that session’s list marked as detached, and it stops when the session closes. The record is kept on disk, so quitting and reopening Wortel does not lose track of it either.
Closing asks when it matters. A shell sitting at its prompt with a server running behind it used to close without a word. It now asks first, and names what will stop.
The toolbar says what is running. The icon is now a status pill in the middle of the toolbar, showing the server by name and its address, bun dev :3000, or a count when there are several. It is about the session you are looking at: switch to a session running nothing and the pill goes away.
The list has room to breathe. Servers come first, lowest port first, with everything else below. Each row shows its name with the address and memory underneath, and Copy and Stop sit beside it, quiet until you point at them. VoiceOver reads a row as one sentence, with its port spoken as a port.
An agent keeps its spinner for the whole turn. Two ways of losing it are fixed. Wortel recognises most agents by their command line, and reading a command line fails now and then on a perfectly healthy process. That failure was being read as “the agent has exited”, so Pi, Gemini, Amp and aider could lose their spinner mid-turn and not get it back until they quit. A failed read no longer counts, and it takes two misses in a row, a minute apart, before Wortel believes an agent is gone.
The other was a build. An agent that runs cargo build or anything else that reports its own progress looked like an agent that reports its own status, and Wortel stopped watching its screen for good. When that progress ended, the spinner went with it, for the rest of the session. Wortel now keeps watching and picks the spinner back up whenever nothing else is claiming it, without announcing a finished turn for a pause in the middle of one.
One row is one thing
A command that starts two servers is two rows. bun dev fanning out to dev:web and dev:images puts both of them in one process group, and Wortel was treating a process group as one job. That is true when a shell starts it, and it is how an agent’s jobs arrive, which is why it held up for so long. It is false here: the pair came out as a single row named after whichever started first, carrying their combined memory and showing only the lower of the two ports, with nothing to say the second one existed.
The hidden port was the smaller half of it. That row’s Quit would have stopped both servers, from a row naming one. A process group is now split into the separate trees it contains, so each server is its own row, with its own port and its own Quit. A job that is the whole of its group is still stopped as a group; one sharing a group stops only its own processes.
Pointing at one row no longer highlights several. The highlight was keyed on the process group, which stopped being unique the moment a group could hold more than one job. The same mistake had reached one other place: quitting a row would have taken its neighbour’s row away while that server kept running.
The cursor stays an arrow. It was turning into a pointing hand over a row, which is a web habit. macOS keeps the arrow over clickable rows and says “this does something” with the highlight.
The scan is twice as fast. It was slower than reading everything about every process on the machine, which is a good sign that something is being done twice, and three things were. Abandoned processes were fully inspected before being filtered on the directory that discarded nearly all of them, so the cheap question is asked first now. Whether a process belonged to a session was recomputed once per session rather than once. And each process had its command line read twice, once to recognise an agent and once to name a job.
The list reads properly with VoiceOver. A row was four separate fragments; it is one sentence now, with the port announced as a port, and each Quit says what it stops rather than being one of several identical buttons. The green dot is marked as decoration, because what it means is already in the sentence, and it uses the system green, which follows Increase Contrast.
The running list, read properly
A port is no longer squeezed out of shape. :13337 rendered stacked one digit per line down the row, because the job’s name claimed the row’s width and left the port nothing to lay out in. An address cannot be split, so it takes its width first now, and the name, which is the only thing on the row that can usefully shrink, is what gives way.
Long commands truncate where you can still read them. They were shortened from the middle, which turned quick.js serve dist --dir ... into quick.js serve di...-chat-prototype. A command reads from the left, so it now keeps its beginning. The same goes for a session heading, which is sometimes a whole sentence, because a session can be named from the first thing you typed into it.
Abandoned processes have to be worth mentioning. A chrome_crashpad_handler sitting in a project directory at 2.8 MB is not a server anybody forgot to stop, and it was being listed as one. Something with no session left now has to be holding a port you could reach, or be big enough that stopping it is the point. Your own sessions’ jobs are still listed whatever they cost, because you started them and they are still yours.
One icon in the toolbar, and it stays the same. It used to swap between two different symbols depending on whether anything was serving a port, which made the item harder to find and encoded a distinction the list already draws far better, with a dot and a port on every row. The icon only appears when something is running, so it has nothing left to say beyond that.
What your sessions left running
Wortel shows what each session is still running. A new item appears in the toolbar when there is something to show, and opens a list grouped by session: one row per job, the port it is serving on, what it costs in memory, and a Quit that appears when you point at it. Click a row to open it in your browser, or right-click for Copy Address, Reveal in Finder and Quit. The item is absent, not greyed out, when nothing is running, so a terminal that has started nothing carries no extra chrome.
It reports memory the way Activity Monitor does, which turns out to matter more than it sounds. ps reported a live vite process at 30 MB while it was really holding 572 MB: on a machine under pressure, compressed and swapped pages leave the resident set, and the number every other tool shows you is the one that hides the problem. One session on the machine this was built against was holding 1.39 GB across two dev servers and an agent.
It finds the ones nothing else can. A dev server that outlives its session reparents itself to launchd and keeps nothing pointing back at the terminal that started it, so no tool on your Mac can tell you it is yours. Wortel can, because the working directory still answers days later. Two were sitting on the development machine while this was written: a wrangler four days old holding 399 MB, and a bun script five days old. Neither was serving anything reachable. They appear under “Not attached to a session”, with how long they have been there and which project they came out of.
Closing a session says what it will stop. The warning used to read “A process is still running in this session”, which is equally true of a session holding one sleep and one holding 1.4 GB across two dev servers. Now it names them: “Still running: bun dev:web (:3000), claude, bun dev:images. Closing stops 8 processes and frees 1.05 GB.” The agent is named too, because closing the session does stop it, and that is the part worth reading.
Your agent is never offered a Quit button, and neither is the session’s own shell. What counts as one job is the process group, which is how shells actually work rather than a guess about which processes belong together.
Notifications carry the session’s current name. A notification was posted with the session’s name and the session was often renamed moments later, when the on-device namer or the agent’s own title came back a few seconds after the turn ended. The banner then said “Session 3” while the sidebar said what the work actually was, which reads as a notification about some other session. A renamed session now rewrites its own banner in place, without a second ding.
Two ways a terminal could come back blank. A session restored from a previous launch could fail to take the keyboard, leaving a window that draws but will not accept a keystroke, with nothing on screen saying why. And a session whose program sat idle while the app was closed had nothing to replay and nothing to prompt a repaint, so it came back empty until you touched it. Both are fixed.
The git panel can pull. Fetch told you that you were behind and then left you to go and type the obvious command. Pull sits between fetch and push, and is fast-forward only: a panel with no conflict UI has no business starting a merge it cannot finish, so a diverged branch gets git’s own refusal and the terminal is right there to resolve it in.
Image diffs say what the change costs. An image commit is reviewed on two things, what changed and what it weighs, and the caption only ever had the first. A PNG that gained 400 KB without visibly changing looked like no change at all. Both sides now show their size alongside their dimensions.
Worktree sessions stop inventing a folder. A session’s folder is the part of its name before the last slash, so naming a worktree session after its branch filed it under a folder named for the branch’s namespace: a second sidebar group holding exactly the sessions that belonged in the first one. New sessions are named for the branch’s leaf, and any session already filed in a phantom folder moves back on this launch.
Two new anonymous events come with this release, both counts only: that the running list was opened, with rough numbers of jobs and of processes that had outlived their session, and that something was quit from it. Never what they are, what they are serving, or where they are running. The full list is on the privacy page, which remains the whole list.
Pi stays watched
Pi is recognised as running for as long as it runs. The previous release taught Wortel to read Pi’s screen for the busy spinner, and it worked for about a minute. Once a minute Wortel checks that each agent it is tracking is still alive, by looking under the session’s shell for a process with the agent’s name. Pi is a Node script, so its process is called node and no process is ever called pi. The check failed, Wortel decided Pi had quit, and it stopped watching the session: no spinner, no agent badge in the sidebar, and no resume after a crash. The same was true of Gemini CLI and Amp, which also run under Node, and of aider, which runs under Python. The check now also looks at what a process was started with, so a Node process running Pi counts as Pi. Agents that are their own binary, Claude Code, Codex, crush, goose and opencode, were never affected.
Pi shows it is working, and a path in a name is not a folder
Pi finally shows it is working. Pi ships with its progress reporting switched off, so Wortel had to read its screen to tell working from waiting, and that reading failed in two ways. It never watched the session you had selected, on the theory that you could see for yourself, so the one place you actually watched Pi work showed nothing. And every message Pi draws is wrapped in terminal marks that made the core believe a command had just finished, which switched the spinner off mid-turn and, with it, the “finished, your move” dot that follows a turn. Both are fixed. The selected session is watched like any other, with your own typing, pasting, clicking and scrolling discounted so a long prompt never reads as the agent at work, and a finished-command signal that arrives while an agent is running is ignored, since the agent, not your shell, still has the terminal. Expect the spinner a few seconds after Enter: this is Wortel guessing from the screen, and it waits for two changed frames before it commits.
- A slash in a generated name no longer makes a folder. Session names come from your first prompt or the agent’s own title, and both are full of paths. “Debug web/src build” was being read as a session called “src build” inside a new folder called “Debug web”. Generated names now use a look-alike slash that the sidebar does not treat as a folder separator, so the path still reads as a path. A slash you type into a name yourself still moves the session into that folder, as before.
- Quitting an agent no longer raises a “Command finished” dot. The finished-command signal at an agent’s exit was being reported like any long shell command. It counts as the agent leaving, not as a command worth flagging.
- This applies to every agent that reports nothing, so opencode, goose and aider gain the spinner in the selected session too. Agents that announce themselves, Claude Code, Codex, Gemini, crush and Amp, are unchanged.
Sessions name themselves, and a folder is a directory
A session is named after what you asked for, seconds after you ask. Until now a row was called after its directory until an agent’s turn ended and the on-device model got a look at the screen, and that look tended to produce two or three words about whatever happened to be scrolling past. Now the name comes from the conversation. Claude Code already titles its own conversation from your first prompt and puts that title in the terminal, so Wortel reads it back: the row says “Debug git panel display issues with worktrees” a few seconds after you press Enter, matches what Claude’s own session picker shows, and follows /rename. Every other agent gets the same thing a different way. Wortel owns the terminal, so while an agent has just launched it watches for the first real line you type, hands it to the on-device model, and names the row from that. No hooks, no config files, nothing leaves your Mac, and the name is set once and held: it changes only when a new conversation starts in that session. A name you type yourself is final and nothing automatic ever touches it again.
- Worktree sessions are named for the task, with the branch underneath. A session opened on a branch used to be called after the branch and stay that way. It is now named like any other session, and the branch moves to a second line under the name, with the same glyph as the toolbar’s branch chip.
- A cut-off name shows itself on hover. Agent names are longer than branch names, so more of them truncate. Hover one and the full name appears as a tooltip, only when it is actually cut off.
- A folder is a directory. A sidebar folder used to be a label: “New Session in Wortel” filed the session under Wortel and started it wherever the selected session had last wandered, which looked exactly like it had worked. Folders now carry a directory, new sessions start in it, and the path shows on the folder header. Set it from the header’s menu, or press ⌘O to open a folder from disk and get a session in it, filed under the folder that already covers it or a new one named for it. ⌘N beside a worktree session opens in the project, not inside the worktree.
- The Session menu moves where a Mac app keeps its main menu, before Edit, and is grouped: starting a shell, folder commands, acting on the selected session, moving between sessions, jumping to one. “New Section” is now “New Folder…”, which is what it always was. ⌥⌘N opens a session at home when you want out of the current folder.
- The git panel takes a selection. ⌘-click toggles a row, ⇧-click takes a range, ⇧↑ and ⇧↓ do it from the keyboard, and ⌘A takes everything. Stage, unstage and discard act on the whole selection with one confirmation, and dragging a selected file into the terminal carries every selected path.
- ⌃⌥⌘. brings Wortel to the front from any app, whether it was hidden, buried or minimised. It is a registered hot key, so it needs no Accessibility permission, and the same chord cmux uses, so if you run both, whichever registered first wins rather than a coin flip.
- ⌘W lands on the row above. ⌘N files a new session right after the selected one, so ⌘N, do the thing, ⌘W now lands back where you started instead of one row further down.
Two crashes, and ⌘Z belongs to the terminal again
Wortel could quit on ⌘Z, and the longer the window had been open the likelier it was. This one came in from a window that had been up for five days. Typing in the commit box was registering its undo steps against the window rather than against the box, and those steps outlived the box every time the panel closed or you moved to another session. Pressing ⌘Z afterwards, with the terminal focused and the commit box nowhere on screen, reached for a step whose editor was long gone, and the app went down on the spot. The commit box keeps its own undo now, so nothing accumulates on the window and there is nothing stale left to reach for.
- ⌘Z goes to your shell again. The same bug had quietly taken the key: once you had typed a commit message, the Edit menu’s Undo claimed ⌘Z for itself, and the terminal’s own undo (clear the line you are typing) stopped happening. Undo inside the commit box works exactly as it did.
- Closing the last session no longer crashes on the way out. The window was being freed the instant it closed, while the app was still holding on to it, so anything that ran in the gap could land in memory that had already gone. Updating the title to say no session is selected was enough to do it. It only ever surfaced once the window was gone, which is the least useful moment to hear about it.
The spinner tells the truth, and a branch you can actually pick
The sidebar’s busy spinner had drifted away from the truth in two directions at once, and if you keep several agents open you will have seen both. A working session showed nothing, while a session that finished an hour ago kept spinning. The first was a marker list that had gone stale: Wortel recognised the braille spinner agents used to animate in their window title, and Claude Code now animates a different one, so it read every frame as “not working” and fell back to guessing from the screen. The second was worse in a quieter way. When the guessing tier lost sight of a session, which a window resize was enough to cause, it forgot that it owed that session a “stopped” and the spinner never came down. Looking at the session to see what it meant was itself one of the ways it got stuck, so it could never recover.
- An agent that outlives the app is still an agent. Sessions survive quitting Wortel, but the record of which agent was running in each one was cleared at launch, on the assumption that anything still alive would re-announce itself. A long-running agent never does, because it never returns to a shell prompt. So a session you left running for days came back with no agent name in the sidebar and no activity detection at all, and the longer it ran the less Wortel knew about it. The record now survives when the shell it belongs to does.
- New Session on Branch is a proper dialog now. It was an alert with a pop-up button whose menu carried a “Filter…” item that opened a list on top of it: a menu, to get to a filter, to get to the branches. It is one panel with one searchable list, and the list is the same one the toolbar’s branch switcher uses, so the two can no longer disagree about what a branch list is.
- Typing a colleague’s branch name checks out their branch. It used to create a new branch forked from trunk wearing their name, with none of their work and nothing on screen to say so. A branch that exists on a remote is now recognised as a branch that exists, checked out with its history and set to track, and the dialog says which remote it came from before you commit to it.
- A new branch starts from trunk as it is now, not as of the last time you happened to pull. Wortel fetches while the dialog is open, so the fork point is current by the time you press Create, and it gives up on a slow fetch rather than making you wait on it.
- The first push from a new worktree session works. A branch forked from
origin/mainwas inheritingorigin/mainas its upstream, which git then refuses to push to under its own default settings. New branches start with no upstream, and the first push sets the right one. - Remote branches no longer hold up the list. On a large repository they are the slow half by a wide margin, so the picker opens on your local branches and fills the rest in underneath, saying so while it does.
Anonymous usage data, and one switch to turn it off
This is the release where the app starts reporting anonymous usage data. It counts which features get used, so that questions like “does anyone open the Files pane” have an answer at all. That is the whole of it: no session names, no directories, no commands, nothing from your screen. It is on by default, and the first time you open this version the ⓘ at the bottom of the sidebar says so and offers the switch that stops it. DO_NOT_TRACK is honoured, and wortel.sh/privacy lists every event that exists, in full.
- A new branch now forks from trunk, not from wherever you happened to be. Opening a session on a new branch forked the current one, which in a worktree session meant quietly inheriting that worktree’s branch. The dialog asks now, with a From row that defaults to the repository’s own default branch.
wortel new --branchdoes the same. If a script relied on the old behaviour, it wants--from HEAD, which is now how you ask to stack on the current branch on purpose. - A worktree session is marked in the sidebar. A session opened on a branch is renamed to that branch, so it read as an ordinary shell in a directory. It carries the branch glyph now, the same one the toolbar chip uses, because which kind it is decides where your last commit went.
- The branch chip fits its name instead of breaking it in half at a hyphen and standing taller than everything beside it. Long branch names truncate from the tail, and short ones no longer sit in a chip half full of nothing.
The git panel keeps up with a worktree
Two fixes to what the panels tell you, both in the case the app is most useful in: an agent working on its own worktree, unattended. If you run sessions that way, this is the release that stops them reporting stale work.
- A worktree session’s git panel was blind to its own commits. A linked worktree keeps its HEAD and index under the primary checkout, so committing there moved nothing the panel was watching: the Changes list went on offering files that had been committed minutes ago. It watches that directory now. The primary checkout had the mirror of the same problem.
- The file tree lost its colours. A changed file is supposed to colour every folder above it, so you can see where the work is without opening anything, and ignored entries like
node_modulesshould stay grey. Neither happened when a session started at a repository root, because the root resolved a beat after the listing that needed it. - Release notes now appear in the update dialog, and the whole changelog is at wortel.sh/updates.
- The new-session button sits on the corner’s diagonal instead of leaning into it.
Sessions that outlive the app
The largest change since sessions themselves. Your shells now run under a keeper process outside the app, which means the app is no longer the thing keeping them alive. Quit Wortel, or have it crash, and the agent in session three keeps working. It is on by default.
- Process survival. The ptys live outside the app. Closing the window is no longer a decision about the work.
- A
wortelcommand. Open and drive sessions from the terminal.wortel --versionreports the app it is talking to, which is the one mismatch worth knowing about. - A worktree per session. Point several agents at one repository without them standing on each other, with a branch picker for choosing where each one lands.
- A preview window. Open a file in its own window: Source mode with syntax highlighting, ⌘F, images sized against the window, and markdown on GitHub’s type scale.
- Hold the pointer over a commit in History to read the whole message.
- A collapsed sidebar folder says what it is hiding, and the Dock badge asks for the permission it needs.
- Nested command-line tools are signed on their own terms. Without that, notarization rejects the app, and an unnotarized app is one nobody can open.
The file tree earns its keep
A week of using the file tree, then fixing what using it exposed.
- Move to Trash, the one file operation the shell does worse than the Finder.
- Hold option to take the whole subtree.
- The chevron is a target you can hit, and it acts on press.
- A directory watch follows an inode, so a directory replaced wholesale (a checkout, a rebuild) no longer goes silent.
- A clean work tree in Changes is an empty state, not a one-line list.
- Each inspector pane keeps its own width, and that width wins the race at launch instead of being overwritten by the column’s.
- The branch chip shrinks when the toolbar runs short of room, instead of taking the whole section with it.
- Attention stopped announcing turns that nobody took.
- wortel.sh rebuilt around a single window: a scroll tour through the app, copy that sounds like a person, and a mobile layout that gives each section its own frame.
Files
- Files, the project as a tree, beside Changes and History. Drag a row into the terminal and the escaped path lands at your prompt.
- A toolbar menu fix: menu items built from a closure survive being copied, which is what the toolbar does to them.
One slot for the dot and the close button
- The status dot and the close button share one slot, so a row no longer moves under the pointer when a session goes busy.
- Release versions are derived from the live update feed instead of a local file, which is what made 2026.31.2 ship twice.
- Publishing a release redeploys wortel.sh, so the version the site advertises is the version you can actually download.
A version everyone could take
Nothing in the app changed in this release.
2026.31.2 had been published twice, as two different binaries, because the version counter was derived from a local record rather than the live feed. Sparkle only ever offers a strictly newer version, so anyone holding the first of the two had nowhere to go. This release gave them somewhere. The cause is fixed in 2026.31.4.
Attention, for agents that say nothing
The point of this release: most agents emit no progress signal at all, and the ones that do are inconsistent about it. Attention now works from what the session draws.
- Agents that announce nothing are noticed anyway.
- Agents launched through a wrapper are recognised as agents.
- Paused progress and blank braille frames no longer read as work in flight.
- A softer, distinct chime when a turn ends.
- The unread ring stays visible while a session is busy.
- ⌘⇧[ and ⌘⇧] switch sessions, alongside ⌘⌥↑ and ⌘⌥↓.
- A close button on session rows, on hover.
- The in-app browser pane is gone. It was one pane more than the window wanted.
Copy code out of a diff
- Diff lines are selectable, and copy as code: no line numbers, no gutter, nothing you have to strip out before pasting it back into the terminal.
- A one-command throughput benchmark that finds the terminals you have installed and compares against them.
- The git toolbar stops fighting itself for space.
- The running-agent subtitle is gone from session rows; the status dot already said it.
Agent resume that survives ⌘Q
- Resume covers eleven agent CLIs across zsh, bash and fish, rather than just claude.
- Quitting cleanly used to erase the record of what had been running, which is precisely when you want it. It does not any more.
- Liveness is read from the process table, failing open: an agent it cannot see is assumed to be there.
- An in-app browser arrived as a third inspector pane. It was removed again in 2026.31.2.
Markdown, rendered
- A native markdown renderer in the inspector column. Click a path in the terminal and the file opens there, rendered, with its code blocks highlighted by the same stack the diff view uses.
- ⌘T works as a hidden alias for New Session, for the muscle memory every other terminal built.
- The landing page shows the current version under the download button.
Fetch and push without leaving the window
- Fetch and push from the git toolbar.
- Shell integration installs the ghostty terminfo on the far side of an SSH connection, so a remote session renders like a local one.
- wortel.sh gained the embedded demo, a grid the content snaps to, and a round of accessibility fixes.
Images in History, and an accordion that holds up
- Images render inline in the accordion, sized against the pane rather than against themselves.
- One scroll for the whole commit, with file headers that stick as you pass them.
- A correctness and performance pass over the accordion.
Every commit opens
- Click a commit in History and its changed files unfold underneath it, with the diff for each one loaded when you ask for it.
- Native text-editing shortcuts work in the rename field.
- New layered app icon.
Syntax highlighting in diffs
- Diffs are syntax highlighted with tree-sitter, per hunk, off the main thread.
- A native branch chip in the toolbar, and right-click menus that open instantly instead of after a beat.
- History is branch-aware, and draws its log the way Fork does.
- The git panel toggle folded into the Changes and History buttons: one control fewer, in the place you were already aiming.
Walking the sidebar
- ⌘⌥↑ and ⌘⌥↓ move to the previous and next session, skipping folders you have collapsed.
- Shell integration reports the working directory as
localhostrather than$HOST, which is what makes the path resolve.
The git panel belongs to the session
- Git panel visibility is per session. A shell in a repository wants it; the one in your home directory never did.
- Renaming selects the leaf of a name, not the folder prefix in front of it.
- wortel.sh rebuilt around the root theme.
History grows a graph
- History draws the branch graph beside the commits, and pages them in as you scroll.
- Large repositories stay responsive: the cost tracks what is on screen, not what is in the repository.
- Sensible default widths for the side panes.
An AppKit shell, and History arrives
The shell around the terminal was rewritten in AppKit: sidebar, terminal and git panel as one three-pane layout rather than a SwiftUI split view doing an impression of one.
- History, a read-only commit list, behind a pane picker in the toolbar.
- Sessions moved to a native outline view. Names are derived from the directory, and a slash in a name makes a folder.
- Session rows are a single line again.
- The git panel divider is draggable and remembers where you put it.
- Agents that were running when you quit (claude, to start with) are picked back up on relaunch.
- New sessions open in your home directory instead of inheriting the launcher’s
/.
Commit messages, drafted on your Mac
A commit box worth typing into, and a first pass at not writing the message yourself.
- A native commit-message editor in the Changes pane, with drafts generated on device by Apple Intelligence. The prompt is budgeted, so a large diff cannot run away with it.
- Right-click any file in Changes for the actions you expect.
- Richer, faster signals in the sidebar for what an agent is doing.
- New app icon artwork.