Plexus has always had exactly one look, and it was the tightest one — built for the moment
you have five to ten sessions live and every pixel is signal. That is still there, and it is
still what Compact means. But it is no longer the only answer, and it is no longer something
you have to accept silently.
Settings has a new Appearance page. Theme moves there from the title-bar button — including
"match my operating system", which the button could take you out of but never back into.
Beside it are two new choices about the shape of the app itself.
Settings → Appearance. Three preferences, each shown as a pair of cards with a small diagram
of the layout it produces, so you can see the difference before you commit to it.
These are per-machine preferences. Unlike everything else in Settings they are never
inherited by a workspace or project, and they will not appear on a project's own settings
page — how Plexus looks on this laptop is not a property of your repository.
Light, Dark, and Match system, which is what a new install uses. The title-bar toggle stays
as a shortcut between light and dark; the page is where you get back to following the OS.
Density is a layout mode, not a spacing slider. Each one changes what a session row is.
Compact is one 28px line per session: the name, a coloured dot for the agent's state, and
the pull-request icon. It is the layout Plexus shipped with, unchanged.
Normal — the new default — gives a session two lines. The second one names the branch it
is on and says what the agent is doing in words: Working, Needs you, Idle.
The glyph beside that branch name does two jobs at once. Its shape tells you where the branch
came from: a branch Plexus cut for the session, or a link for one it attached to — which is
what you want to spot before a rebase rewrites history someone else may already have. Its
colour is the pull request: grey when there is none, green when one is open, purple once it
is merged. Click it to open the PR.
The row's ⋯ menu no longer holds a place for itself while it is hidden, so the session name
and the state word run to the edge of the sidebar instead of stopping short of it. The menu
appears over that edge when you hover the row.
Switch between them from the app bar, or from Settings → Appearance.
The session and project tabs changed with them: the active tab is now marked by
a brand underline along the bottom of the strip rather than a filled chip, and
each tab carries its own glyph.
The sidebar used to nest three levels: workspace, then project, then session. It now shows
one workspace at a time, chosen from a switcher in the app bar — so a project is the first
thing in the sidebar and a session is one step in, with no chain of chevrons to open before
you reach the thing you wanted.
The switcher's menu lists every workspace with its session count and, in amber, how many are
waiting on you. That is the question you switch workspaces to answer, so it is visible before
you switch rather than after.
Under that list are the active workspace's own actions — Edit, Settings, Set as default and
Delete workspace. With one workspace shown at a time there is no workspace row in the sidebar
to hang them on, so this menu is where they live.
Prefer the old tree? Settings → Appearance → Workspace navigation → All workspaces in the
sidebar brings all three levels back — and it is easier to read than it was. Each workspace
is now drawn as a group: a header that stays put while its projects scroll past, over a well
with a rail down its left edge, so you can see where one workspace ends and the next begins
instead of counting indentation. The workspace holding whatever you have open is tinted, and
nothing is tinted when nothing is open.
Project rows also gained a standing button for the project view — the dashboard, git client
and terminal — which previously you could only reach by knowing that clicking the row did
something.
Press ⌘K — Ctrl+K on Windows and Linux — or click the search field in the app bar, and
type. Every session and every project in the tree is there: match on a session's name, the
branch it is on, the project it belongs to, or the workspace. Two words narrow instead of
widen, so plexus settings finds the one session you meant.
Enter opens it. If it lives in a workspace you are not currently looking at, or in a project
that is collapsed, Plexus points the sidebar at it and scrolls the row into view rather than
selecting something you cannot see. With nothing typed you get your whole tree as a flat list,
50 rows at a time — when there are more than that, the bar along the bottom tells you how many. The same is now true of the Open button on a
notification — it used to be able to take you to a row that was nowhere on screen.
The shortcut works while the agent terminal has focus, which is where it is most useful and
where a shortcut normally stands down. That does mean Ctrl+K no longer reaches the terminal on
Windows and Linux, where it clears to the end of the line; if you want it back, Settings →
Keybindings → Search sessions and projects rebinds or unbinds it. It does stand down for
one thing: another dialog. Opening a search on top of a half-filled New session dialog would
navigate away and leave that dialog stranded over an unrelated session.
The New session dialog inherited its project from wherever you opened it, and the + in the
app bar had to guess — the project you had selected, or the first one in the workspace. When
the guess was wrong the only way out was to close the dialog and start again.
It now asks. Project is a field in the dialog, prefilled with that same guess and
changeable in one click. It offers what the sidebar offers: the current workspace's projects,
or every workspace's grouped by name if you use the "All workspaces in the sidebar" setting.
Open it on a project from another workspace — from a dashboard row — and both are listed under
their names, so the way back is a click rather than a reopen.
Switching re-reads that repository's branches and clears the base and branch you had picked —
main in one repository is not main in another — while keeping the name you typed. A name
Plexus filled in for you from a branch goes with that branch.
The New branch / Existing branch switch is now a segmented control, with the explanation
for whichever mode is selected below it.
Plexus can keep an AI-written digest of a session — what you asked for, and what the agent has
done about it — refreshed as the agent stops, while you have the panel open on it. It has been
there for a while, switched off by default. The trouble was that the same setting also hid its
button, so the only way to find the feature was to already know it existed.
Summary is now always in the session header. Open it with summaries switched off and the
panel says what it does and what it costs — each refresh sends that session's transcript to
the agent and uses one of your plan's turns — and offers two ways to switch it on: for the
project you are working in, or everywhere. Either way Plexus writes the first summary straight
away rather than leaving you with an empty panel until the agent next stops.
Nothing is sent anywhere until you press one of those buttons.
The session view and the project view each used to draw their own header inside the right
pane, starting at the sidebar's edge and repeating what the sidebar already showed. There is
now a single bar across the full width of the window that says where you are — project, then
session, then the agent's state — and carries the tools that act on it. The pane below it is
just the work.
Running two sessions of one repository has always had the same sharp edge: both want to start
the dev server, and the second one finds port 3000 taken. Plexus now hands every session its
own block of ten localhost ports and puts them in the environment of everything it starts for
that session — the agent, the session's terminal tab, and every lifecycle hook.
The block is reserved when a session starts, checked to be genuinely free before Plexus commits
to it, and kept for as long as the session's working copy exists. Resuming gives a session the
same ports it had, so a dev server that is already listening is never moved out from under
itself. Tearing the worktree down releases them.
Each session's first port shows as a small chip in three places — its sidebar row, its dashboard
row, and the header bar while it is open. Hover it and the tooltip names the whole range.
Its ⋯ menu, in the sidebar and on the dashboard both, gains three matching actions: Open
localhost:20030 launches your browser at that port, Copy port puts the number on the
clipboard, and Reassign ports is covered below. They are absent rather than greyed out for a
session that holds no block, since nothing you could do from that menu would give it one.
PLEXUS_PORT is the session's first port — the one to use. PLEXUS_PORT_BASE is the same
number for scripts that do arithmetic, PLEXUS_PORT_COUNT is how many the block holds, and
PLEXUS_PORT_1 through PLEXUS_PORT_9 are the rest of it, for a second server, a test
database or a debugger. PORT is set too, because that is the name Next.js, Nuxt, Rails and
Express already read.
The intended home for all of this is a run hook, which fires on every start and resume:
pnpm dev --port $PLEXUS_PORT
Commit that to your repository's .plexus/hooks.json and everyone on the team gets it from a
clone.
Plexus sets the variables. It does not inspect your project, does not know which framework you
use, and never adds a flag to a command you wrote. If your server reads PORT on its own,
there is nothing else to do. Vite, Astro and Angular do not — they need
--port $PLEXUS_PORT on the command, or the value threaded into their config. And if nothing
in your project reads any of these variables, nothing about your setup changes.
Most .env loaders leave a variable alone when the process already has one. So for a project
whose .env is copied into each session and carries a PORT=3000 line, that line no longer
wins: Plexus sets PORT in the environment first, and the loader will not overwrite it. If you
were fixing a port that way — which is exactly what the old documentation suggested — your
server now starts somewhere in the twenty-thousands instead.
That is usually the outcome you wanted. If it isn't, open Settings → Worktrees & Hooks and
clear Extra port variables: with the list empty, Plexus sets only its own PLEXUS_PORT*
names and PORT is yours again.
Blocks come out of 20000–32000 — around 1200 of them. That window sits above every common
dev-server port, above 10080 (the highest port Chrome and Firefox refuse to open, which would
give you a server that starts fine and a browser that will not load it), and below 32768, where
Linux starts handing the same numbers out to outgoing connections. Move it with First port
and Last port if it clashes with something on your machine.
All five settings live in Settings → Worktrees & Hooks, globally or per project: Assign dev
server ports (on), First port, Last port, Extra port variables, and Write ports
to file.
That last one is off by default and covers what environment variables cannot reach — a
docker compose file reading .env for substitution, or a server you launch yourself from a
terminal Plexus did not open. Name a file and Plexus keeps a marked block of the same variables
inside it, refreshed every time the session comes back up, with everything outside the markers
left exactly as you wrote it. It is for compose services, database ports and app config. It is not a second way
to move a dev server: Vite, for one, loads .env.local and still takes its listen port only
from its config or its command line.
A reservation is remembered, not re-checked — re-checking it on every resume could move a
running server's ports out from under it — so something else on your machine can claim one of a
stopped session's ports while it is down. Reassign ports in that session's ⋯ menu drops
the block and searches again. If nothing has taken the old one after all, you get it back: what
you asked for is a block that works, not a different number.
Full details, including what the reservation does and does not promise, are at
https://runplexus.com/docs/worktrees#dev-server-ports.
A review-and-fix cycle can run for the better part of an hour, and until now the only thing it
told you was "Cycle round 2 — agent applying fixes…". That sentence is the same on a round that
is editing files and a round that is stuck, which made a long round and a broken one impossible
to tell apart.
Watch agent now sits next to Stop, both in the Review tab's status strip and in the
session header, and only while a cycle is actually running. It opens a panel across the bottom
of the session with two halves. The top is a running account: which round it is on, how many
files the review is reading, when it asked the model, how many comments came back, and how long
each phase took. The bottom is a live terminal on the fix agent itself, so you can watch what it
is editing as it happens.
The terminal is read-only. You can select and copy from it, but nothing you type reaches the
agent — which also means a stray keystroke can't interrupt a round that has been going for
twenty minutes. The output never touches disk, and it only reaches the app while the panel is
open; closing it stops the stream at the source rather than just hiding it. Open the panel
part-way through a round and it back-fills the most recent stretch so you aren't starting from
blank.
Only the fix half runs in a terminal. During a reviewing phase the panel says so, and the
account above it carries the story instead — with a live clock on the current step, so you can
always see something is moving.
Every headless call Plexus makes — the AI review, session summaries, pull request descriptions,
commit messages — was starting up your configured MCP servers first, waiting for all of them to
connect, and shutting them down again when it finished. None of those features can use an MCP
tool. On a machine with a handful of servers configured that was tens of seconds of waiting per
call, twice per review-and-fix round, for nothing. They are no longer started.
Three other things on the review path were quietly wrong. It ran in whatever directory Plexus
itself had been launched from rather than the session's worktree. It had no time limit at all,
so a review that wedged looked exactly like a review that was merely slow, forever — it now
gives up after fifteen minutes and says so, and inside a cycle that just skips the round. And
the fix agent was handed the review comments with nothing telling it to stay on them, so in a
repository whose agent instructions describe a lot of routine upkeep, a round applying six
comments could go and do all of that too.
The parts that are genuinely a matter of taste are now settings rather than assumptions
(Settings → Git & PRs, overridable per workspace or project). Model and Effort pickers
for the review and, for the first time, for the fix agent — the expensive half, which previously
had no controls whatsoever and silently inherited whatever your Claude Code configuration
resolved to. Review-and-fix agent instructions for what the fix agent is told before the
comments. And Allow MCP servers in the review-and-fix agent, off by default, for the rare
project whose fixes genuinely need one.
All four model and effort settings default to Automatic, so nothing changes until you choose —
but the new panel reports what each round actually used, which is the part that was invisible
before.
The blue ring around a session's dot means the agent handed work to subagents and carried
on without waiting for them. When it appeared it was right — it just did not appear
anywhere near often enough, and once lit it did not always go out again.
Work started by a workflow counts now. A workflow that fans out to several agents at
once records the fan-out but nothing about the agents themselves, so the ring stayed dark
for exactly the case where the most work is running in parallel. Plexus now follows the
run itself, and those agents light the ring and drop off it as each one finishes.
A launch is reported the moment it happens, rather than when the session's conversation
record catches up. Those are usually the same instant, with one exception that made the
ring look unreliable: if the same turn also stopped to ask you a question or to show you a
plan, the record could land after the work had already been reported finished — and the
ring then never appeared at all. Nothing about that was visible from the outside, so the
same action seemed to work sometimes and not others.
What lights the ring is unchanged. An agent the main agent is sitting and waiting on is the
main agent working, so it stays a plain green dot with no ring; the ring is for work running
beside your session, not work it is blocked on.
Stopping a session clears it. A session stopped in the middle of a delegation kept
pulsing blue until you restarted Plexus. Stopping it — or the agent exiting on its own —
now clears the ring immediately, which is what the documentation has always said happens.
And it shows up where sessions are only summarised. A collapsed project used to hide
delegated work completely; its row now carries a small ring and the number of sessions
delegating underneath it. The workspace switcher in the app bar does the same for the
workspace you are in, and its menu shows that count per workspace beside the "need you"
one. In ⌘K search, a session's second line spells it out in words — Working · 2
delegating.
A dark ring can now explain itself. Turn on Diagnostic logging (Settings →
Advanced) and Plexus records what the session actually delegated to — including the kinds
of agent that deliberately do not light the ring, counted alongside the ones that do. If
your subagents did not show up, that tells you whether Plexus missed them or whether they
were the sort that never lights it, without you having to reproduce anything.