← Back to Plexus
Release notes

Changelog

Everything that shipped in Plexus, newest first. The app updates itself and shows these same notes once per version in its What's new window — see Installation for how updates arrive.

v0.20.2 Latest

Windows sessions start, and consoles close

Two Windows fixes that turn out to be the same bug seen from opposite ends. A session could refuse to start — a blinking cursor, then "Claude didn't start — it launched but produced no output, and an automatic retry didn't help either." And every terminal Plexus opened left its Windows console process behind when it closed, some of them spinning a CPU core for as long as the app stayed open. One report had 23 of those alive after a day of use, burning 85 CPU-hours between them while Plexus itself sat idle. There are fixes in here that are not Windows ones either: the review-and-fix cycle no longer marks findings as done when its agent never ran, and pull request comments you send to the agent can always be sent again.

Sessions that never started

A new Windows console asks the terminal it is attached to where the cursor is, and it will not start the program inside it until something answers. Plexus answered from its terminal view, which meant the answer could be missed entirely — and when it was missed, that session was stuck for good. Resuming again started a fresh console with the same problem, which is why Retry did not help.

Plexus now answers immediately, in the same place it reads the console's output, before any of the app's own machinery is involved. It was never a problem with your Claude installation, and nothing about that installation needed fixing.

The review-and-fix cycle's background agent could never answer at all — its terminal is deliberately read-only — so its rounds are covered by the same change.

A review round that didn't run keeps its comments

The review-and-fix cycle marked the comments it handed to a round as resolved the moment it launched the fix agent — about a minute before it could tell whether that agent had started at all. So when one didn't start, the round's findings were struck through anyway: the Review tab read as though there was nothing left to do, Send N comments to agent greyed out, and the per-file counts showed a tally of work that never happened.

A round now resolves its comments only once it has actually run. If the fix agent never started, the comments stay open and the next round hands them over again — so a cycle that stopped early leaves you exactly where you were, with every finding still there to act on.

The fix agent says when there is too much to send it

There is a limit to how much text can be handed to a program when it starts, and a cycle with a lot of open comments could exceed it. What came back was the operating system's own wording — "The filename or extension is too long." — attached to a failed cycle, which explained nothing.

Plexus now checks first and says what is wrong: how much there is, what the limit is, and that resolving or deleting some comments will let the cycle run. It never sends a shortened version of your comments, because an agent working from half a list is worse than one that didn't start.

Consoles are closed when a terminal closes

Stopping a session, switching away from one, closing a scratch terminal or finishing a review round now releases the Windows console that terminal was using, instead of leaving it running until you quit the app.

Switching between sessions was the quietest source of this. Plexus keeps a limited number of sessions warm and stops the least recently used one beyond that, so simply moving around a project with more sessions than the warm limit leaked a console each time — with nothing on screen to suggest it.

If you have been hitting this, you do not need to do anything after updating: the leftovers from earlier runs are gone the next time you quit and reopen Plexus.

A terminal that fails to open is retried

If building a terminal failed once, Plexus remembered the failure and reused it for every terminal afterwards, for as long as the app stayed open. Every session opened from that point on got no terminal — and on Windows, a session with no terminal was a session that could not start. Plexus now retries instead of caching the failure.

Sessions that fail to start no longer leave an agent behind

If the last step of starting or resuming a session failed, Plexus could return an error while the agent it had just launched kept running — with no way for you to see or stop it. That agent is now stopped as part of the failure.

Diagnostic logs stay a sensible size, and stay readable

Three fixes to the log behind Settings → Diagnostics:

  • It could grow without limit inside a single run — one report arrived at 179 MB — because the clean-up on start-up skipped any file whose oldest line was still inside the retention window, which is always true of a file something is actively filling. Oversized logs are now trimmed to their most recent portion regardless of age.
  • A session that failed to start wrote a warning about it every two seconds for as long as the app stayed open, which is what filled those logs. That warning is now capped, so the log keeps the part that explains the problem instead of burying it.
  • Lines written at the same moment from different parts of the app could interleave, splicing two entries into one unreadable line. Each entry is now written in one piece.

Setting Delete diagnostic logs after (days) to 0 still keeps everything, and a log you pointed Plexus at yourself with PLEXUS_DIAG is still never touched.

Pull request comments you can always send again

Handing a PR review comment to the agent marks it Sent so you don't send it twice. That mark now lasts only as long as the agent that received it. Stop the session, resume it, or lose the agent to a crash, and every comment it was given goes back to being sendable — because a prompt written to a terminal that is no longer there was never read by anybody.

Before, the mark lasted for as long as Plexus was open. A send into a session whose agent was not actually running still counted, so the comments were left chipped Sent, the button that sends them all disappeared, and restarting Plexus was the only way back.

That button also stays on screen now instead of vanishing once everything has been sent. It goes quiet and says what it is waiting for, rather than leaving you looking for a control that isn't there.

If you have Resolve PR comments after the agent fixes them turned on, it is held to the same rule: a comment is only resolved on GitHub or Bitbucket if the agent that was actually given it finishes the turn. A resume no longer resolves comments that agent never saw.

v0.20.0

Send feedback, and open your dev server from the session

Plexus can now hear back from you. There is a Feedback button in the app bar, the diagnostic log finally stops growing forever, a session's dev server is one click away from its tab strip, a session whose pull request has merged cleans itself up without stopping to ask, and a session that has handed its work to subagents says so rather than asking for you. And on Windows, two things that never worked on an npm install of Claude Code now do: every AI feature, and starting a session at all when your user name has a space in it.

Send feedback

Next to the search field there is now a Feedback button. Write whatever you want — a bug, a missing feature, something that annoys you — and it reaches us directly. No account, no issue tracker, no signing up.

Because Plexus is local-first, this is the one place where something you made can leave your machine, so the dialog is built around showing you exactly what that is. Nothing is sent until you press Send, and nothing is sent that the dialog did not put in front of you first.

What you can attach

A screenshot, only if you press Attach screenshot. It is a picture of the Plexus window drawn by Plexus itself, not a capture of your screen — it cannot contain another application, a second monitor, or anything behind the window, and Plexus never asks macOS for screen-recording permission. You see it before you send, and you can remove it again.

Diagnostic logs, on by default, with a Preview what's included panel that prints the exact text that will be uploaded. Anything shaped like a token, key or password is blanked out before it leaves your machine, and your home folder and username are rewritten. What it keeps — deliberately, because it is what makes the log useful — is repository paths, branch names, worktree folders, session ids and timings.

If Diagnostic logging is switched off, Plexus says so, still attaches the activity trail it keeps in memory, and offers to turn logging on — while being honest that it starts recording from that moment and will not help the report you are writing.

Your email address is optional and blank unless you type it. Without it we simply cannot reply.

Deleting a report

Every report comes back with a reference code, which Plexus keeps in a list on your device. Mail that code to timo@codedwords.com and we delete the report and everything attached to it. Screenshots and logs are deleted automatically after 90 days in any case, and the message itself after a year.

Full details of what is and is not sent are at https://runplexus.com/docs/feedback and in the Privacy Policy.

Diagnostic logs stop growing forever

plexus-diag.log used to be appended to and never trimmed. Now every launch drops lines older than seven days.

You can change that with Delete diagnostic logs after (days) under Settings → Advanced — set it to 0 to keep everything, which is what you want when you are capturing a problem that only reappears every few weeks. A log file you pinned yourself with the PLEXUS_DIAG environment variable is never touched.

Diagnostic logging itself is still off by default, and still writes nothing until you turn it on.

Open the session's dev server

Every session gets its own block of ten localhost ports, and the first of them — the one your dev server should be listening on — used to be a small grey number on the session's sidebar row and in the header bar. A number you could read, in two places you could not do anything with it.

It has moved to where it is useful. Open a session and its tab strip now carries an Open localhost:20030 button, beside Hook output. Click it and your browser opens at that port. The caret next to it holds Copy port and Reassign ports, so nothing about a session's ports asks you to leave the session any more. In Compact the label shortens to localhost:20030, and on a narrow pane it drops to the icon, so the tabs beside it stay reachable however far you drag the sidebar over. Hover it and the tooltip names the whole block, ports 20030 through 20039.

The button is there when the session holds a block and Assign dev server ports is on for that project — and it goes the moment you switch that setting off, with no restart. It is never shown greyed out: a session that has never started holds no ports, and there is nothing you could press to give it some.

The dashboard keeps its port chip. That screen has no session tab strip to put a button in, and it is the one place you compare one session's ports against another's. The menu on every session row, in the sidebar and on the dashboard alike, still carries the same three port actions it always did.

One thing worth knowing now that reassigning is a click away: it does not move a dev server that is already running. The port variables are handed to what Plexus starts, at the moment it starts it, so a server your run hook launched keeps listening where it was told to while the button already names the new block. Reassign while the session is stopped, or restart it afterwards.

Full details are at https://runplexus.com/docs/worktrees#dev-server-ports.

Cleanup after a merge no longer asks

Clean up a session when its pull request is merged has always described something Plexus did not quite do. It said it would remove the session automatically; what it actually did was wait until a background check noticed the merge — sometimes a minute after somebody else pressed the button — and then open a confirmation dialog in front of whatever you were doing.

That dialog is gone. If you switched the setting on, that was the answer. Plexus now cleans the session up on its own, with no interruption, and tells you afterwards what it did.

It still follows your When you remove a session setting, so Archive (keep a restorable copy) files the session away and leaves everything on disk. The one change is Ask each time: there is nobody to ask when the trigger is a background check, so it deletes there, the same as Delete immediately. The setting's description in Settings → Git & PRs now says all of this outright.

Whether the session's branch goes with it is inherited from the Also delete the local branch switch in the ordinary removal dialog — the one you last used when removing a session by hand. That switch starts off, so branches are kept until you have ticked it at least once. A branch that existed before the session, one you started work on rather than one Plexus cut, is always kept: deleting somebody else's branch is not a decision Plexus will make while you are not looking.

Only a merge Plexus watched

The cleanup runs for a pull request Plexus saw while it was open. One that was opened and merged entirely between two checks — or that Plexus is meeting for the first time already merged — is left alone. Removing a worktree cannot be undone, so it is not something to do on the strength of a status just seen for the first time.

Several at once

If more than one session's pull request has merged, all of them are cleaned up now, one after another. Previously only the last one got its dialog and the rest were quietly skipped, which is why a merged session sometimes stayed in the sidebar for no visible reason.

Sessions say "Delegating" instead of "Needs you"

A session with background subagents running now says Delegating — in the same blue as the ring around its dot — whenever its main agent is not mid-turn. It reads that way on the second line of its sidebar row and in the header bar at Normal density, and in ⌘K search, where it comes with the count: Delegating · 2.

A session whose agent is still working is untouched. That one keeps saying Working, and Working · 2 delegating in search, because the main agent being busy is the more useful half of that answer.

Before this, the same session said Needs you in amber, or Idle — and amber reads as a call to action for a session where the agent has handed work off and the delegated work is what is still running. The rest of the app had already decided that isn't a moment worth pulling you in for: a turn that ends with subagents still going gets no chime and no notification. The word was the last surface still calling you over.

One thing worth knowing, because the word alone won't tell you: a session paused on a permission prompt, a plan waiting for approval or a question also reads Delegating while the ring is lit. The tell is the dot, which is deliberately unchanged — it stays amber, and hovering it still says Waiting for input — 2 subagents running.

Nothing else moves. The dot, the ring, the tooltip and every "N delegating" count are exactly as they were.

AI features on a Windows npm install

Run AI review, the AI pull request title and description, session summaries and every round of the review-and-fix cycle now work on an npm or Volta install of Claude Code, on Windows, with nothing for you to change. No setting, no reinstall.

They had never worked there. Plexus handed Claude its instructions on the command line, and on Windows an npm install of Claude Code is a small claude.cmd script that Windows runs through the command prompt — which cannot carry a line break inside a command-line argument at all. Every one of those instructions is more than one line long, so each of those features failed every single time, before Claude was even started. AI commit messages were the one exception, and only because their instruction happens to fit on a single line.

Plexus now sends the instruction to Claude the same way it has always sent the diff or the transcript that goes with it: through the program's input rather than its command line. That is the case on macOS and Linux too, not only on Windows — one route everywhere, so this is not a special case that only breaks again somewhere nobody looks. What the agent is asked for is unchanged, word for word.

The review-and-fix agent runs in a terminal of its own and has no such input to write to, so on those installs Plexus hands it a file holding the instructions instead. That one is the only part of this that is Windows-specific: for the fix agent, native installs of Claude Code and every install on macOS and Linux take exactly the route they always did.

If Plexus does still refuse an argument on Windows — a session name containing a character the command prompt would treat as punctuation, for instance — the message now tells you what to do about it. It leads with claude install, the Claude Code command that replaces an npm install with the native build without opening a browser, and offers the PowerShell one-liner irm https://claude.ai/install.ps1 | iex beside it. The old message pointed at a page that answers with an error.

Sessions start when your Windows user name has a space in it

A second Windows bug, found while fixing the first, and unrelated to AI features: if the path to your claude.cmd contained a space, starting a session did not work at all. That is not an exotic case — a Windows profile named First Last puts a space in the npm install path, and so does any install under C:\Program Files.

Plexus runs a claude.cmd through the Windows command prompt, and a quoted path at the very start of that command was being taken apart by the command prompt's own quote handling before it ever ran. The command is now written so that cannot happen. Nothing about your setup needs to change.

v0.19.0

Appearance settings, two interface modes, and one header per window

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.

Appearance settings

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.

Theme

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.

Compact and Normal

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.

One active workspace

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.

Search your sessions

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.

Choose the project when you create a 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.

Session summaries introduce themselves

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.

One header per window

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.

Dev server ports

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.

What your scripts get

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:

bash
pnpm dev --port $PLEXUS_PORT

Commit that to your repository's .plexus/hooks.json and everyone on the team gets it from a clone.

Your dev server still has to be told

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.

One thing that may change under you

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.

The range, and the settings behind it

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.

If a port gets taken anyway

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.

Watch the review-and-fix cycle work

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.

Rounds that don't idle, and settings for the rest

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.

A more reliable subagent ring

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.

v0.18.0

An activity dot that works on Windows, published review notes, and comments that delete

The notes you leave on a diff line have always been private — written for the agent, kept on your machine. Sometimes the right reader is a person instead. A note can now be posted to the session's pull request as an inline comment on the same line, one at a time or the whole review at once. And notes finally keep their line breaks, so a paragraph stays a paragraph wherever it ends up.

Deleting one of those notes could also do nothing at all, and then insist the note no longer existed. Both halves of that are fixed.

Connected accounts got a fix of their own: a Bitbucket connection that was short of a permission could ask you to reconnect for ever, and now it stops once it has been asked and answered.

On some Windows machines the green dot next to a session simply never lit up. The agent was working perfectly — it just never looked like it, so a wall of sessions gave you nothing to read and the dashboard was worth no more than a glance at each terminal.

The cause was a link in the chain nobody could see. Plexus asked Claude Code to report what your agent was doing by running a small command, and Claude Code hands that command to a shell — which on Windows is PowerShell unless you happen to have Git Bash installed. There the report was quietly lost on the way. That is why it broke for some Windows users and not others, and why nothing anywhere said so.

Plexus no longer asks a shell. It also no longer depends on those reports arriving at all, and if something is still wrong there is now a button that tells you which link is broken.

Publish a note to the pull request

Every inline note carries a fourth button next to Edit, Resolve and Delete: publish it. It posts the note to the session's pull request as an inline comment on the same file and line, under your own GitHub or Bitbucket account.

Plexus asks first. A confirmation shows the note about to go out and names the repository it is going to, as owner/repo#number — publishing is public and there is no undo from Plexus, so the last step is always yours.

Publishing consumes the note. Once the comment lands, the local copy is deleted and the pull request's own thread renders on that line in its place, so there is nothing left in Plexus to accidentally send twice. To change or remove it afterwards, edit or delete the comment on GitHub or Bitbucket, the same as any other comment you left there.

The Review header carries the bulk version — the same confirmation, a button with a count. It sends the session's unresolved notes, up to forty at a time; with more than that the dialog says so ("the first 40 of 57") rather than quietly leaving the rest behind. Notes whose file has left the diff are skipped, since there is no line left to anchor them to — which is why the count can be lower than the one on Send N comments to agent.

Resolved notes can be published too. Send N comments to agent resolves everything it sends, and so does each round of the review-and-fix cycle, so the notes worth showing a reviewer are often exactly the resolved ones.

Notes the AI review agent wrote say so

A published note that the AI review agent drafted opens with an italic line, Drafted by the Plexus review agent. — someone reading the thread should know which findings came from a model rather than from you. Notes you wrote yourself go out exactly as written, with no marker, the same as the line composer's Comment on the PR always has.

When it's offered, and what can still refuse it

Both buttons appear only once the pull request's conversation has actually loaded, only while the pull request's comments are shown, and only while the pull request is open — a merged or closed one takes no new comments.

A line that isn't part of the pull request's diff yet is refused by the provider. Plexus keeps that note and tells you which ones didn't land, so committing and pushing and trying again is all it takes. A large batch goes out one comment at a time, paced so the provider doesn't rate-limit it halfway through; if it does run into a rate limit or an authentication problem it stops there and reports the rest as untried, rather than hammering an endpoint that has already said no.

And you can stop a batch yourself: while one is running, the header button becomes a Stop. It stops at the next note — the comment already on its way still lands — and leaves the rest untouched, so publishing again picks up where it left off.

Notes keep their line breaks

An inline note used to be flattened into a single line the moment it was saved, which turned a two-paragraph thought — or an AI review finding with a code block in it — into one long run of text. It doesn't any more: paragraphs, nested lists, indented code fences and the alignment inside them survive being saved, so the Review tab shows you the note you wrote, and so does the pull request when you publish it. That matters most for a suggestion block, which the person reading your comment can apply into the file with one click.

Two things a saved note still bounds, so no note can pad the rest of itself out of view: a run of spaces is kept up to 16 columns, and a run of blank lines up to two. A very long note now scrolls inside its own thread rather than pushing the diff off screen.

The prompt the agent receives is unchanged: it still gets one line per note, so a long comment can't split the instruction it belongs to.

Reconnect notices that stop coming back

If your Bitbucket connection was short of a permission — the access to your repositories, or to pull requests — Plexus asked you to reconnect, then announced Bitbucket access restored a moment later, then showed the very same notice the next time you searched for a repository or refreshed a pull request. Not now didn't end it either: the notice was back with the next round. Reconnecting never stopped the app asking you to reconnect.

Behind it was a check being read as an all-clear it was never able to give. Plexus checks your Bitbucket connection every few hours, but that check can only confirm one thing — that your workspaces are still visible — because Bitbucket offers no way to ask what else a connection covers. Passing it was treated as proof that everything was fine, which wiped a warning about a completely different permission, and wiped the fact that you had put that warning away.

A check now clears a warning only when it actually tested the permission the warning is about. So a notice raised by a real refusal stays up until the refusal stops, Not now puts it away for good, and the "access restored" message only appears when something really was restored.

Three things follow from that:

  • When signing in again genuinely can't help, Plexus says so and stops asking. Some Bitbucket permissions have to be enabled on the Plexus side, where no amount of re-signing-in will widen them. Once a reconnect has been tried and the access is still short, Plexus tells you that plainly instead of offering the same button again — and it now remembers it after a restart, so you don't walk into the same loop every time you open the app.
  • The notice names the permission the way Bitbucket does. Bitbucket's newer permission names are recognised now, so a notice reads Account: Read — the checkbox as it is labelled — rather than an internal identifier you'd have to guess at.
  • A refusal while loading a pull request counts. If a provider turned down a pull-request request because of a missing permission, that could pass without ever reaching a notice. It now raises the same notice as everything else, against the account it came from.

The access each connection carries, in Settings → About

Settings → About now lists every connected account under Connected accounts, together with the access the provider recorded for it. When Plexus tells you a permission has to be enabled on our side and asks you to report it, that list is the thing to copy into the report — until now there was no way to see it from the app at all. A provider that recorded nothing says so, rather than showing a blank you would read as "no access".

Deleting an inline comment

Clicking the trash icon on an inline comment in the Review tab could leave the comment sitting exactly where it was, with no error and no sign anything had happened. Clicking it a second time then said not found: review comment 3 — and the comment still stayed on screen. The frustrating part was invisible: the first click had already deleted it. The list you were looking at had simply put it back.

It deletes on the first click now, and stays deleted — through a tab switch, and through quitting and reopening Plexus.

Two things caused a comment to come back. Plexus matched a comment by its number alone, and those numbers get reused after you delete a session, so a comment could be matched against a long-gone comment from a session you had already thrown away. And re-reading the comment list in the background could overwrite a comment you had just deleted with an older copy of the list. Neither can happen now: a comment is only ever matched inside the session it belongs to, and a list that was read before your change is discarded rather than applied on top of it.

Resolve and Edit were affected by the same matching fault and are fixed with it — they could silently apply to the wrong copy of a comment, so the strikethrough or the new text only showed up after you left the Review tab and came back.

Deleting a comment that is already gone is no longer reported as an error. It is what you asked for, so the comment simply disappears.

While a change to a comment is still being saved — a delete, a resolve or an edit — that comment's buttons are greyed out. A second click can't land on a comment that is already on its way out, and two quick clicks on Resolve can no longer race each other into leaving the row showing the opposite of what was saved.

Comments from a deleted session no longer show up under a new one

Deleting a session left its inline comments in memory. Because Plexus reuses the internal numbering of deleted sessions, a session created afterwards could show the deleted session's comments in its Review tab until you switched tabs. They are now cleared along with the rest of the session's state when it is deleted.

A change you made just before deleting a session can no longer land in the session that inherits its number either, which could otherwise leave a comment in a brand-new session's Review tab that had never been written there.

The first comment on a file appears immediately

Adding the very first comment to a session — before Plexus had finished reading that session's existing comments — could leave it invisible until something else redrew the diff. It shows up as soon as you add it.

Commenting during that same moment could also hide the comments that were already there: Plexus discards a comment list it read before your change, and it now reads a fresh one instead of waiting for the next time you open the Review tab.

Sessions on Windows show what the agent is doing

Plexus now has Claude Code report activity directly, with no command and no shell in between — so there is nothing left to lose the message. Working, waiting for you, plan-mode pauses and the background-subagent ring all behave on Windows the way they always have on macOS and Linux.

If you are running an older Claude Code, Plexus keeps using the previous method, which is unchanged. Updating Claude Code is worth it on Windows.

The dot keeps working even when the reports don't

The activity dot used to be entirely dependent on those reports. If none arrived — an old Claude Code, a policy that blocks them, a broken PATH — the dot was simply dead, and a session that ran a tool could get stuck showing green forever, with Reset status the only way out.

Now, when a session has gone a while without a single report, Plexus falls back to reading the agent's own conversation record instead. It turns green while the agent is writing and goes back to amber when the turn ends — including for turns that use no tools at all, which the old behaviour could never show. A session that was interrupted mid-tool now returns to amber on its own instead of pulsing green until you notice.

This only ever engages for a session that has had no reports at all, so nothing changes for a session where they are arriving normally.

Check activity hooks

There is a new Check activity hooks… item in a session's ⋯ menu, right above Reset status. It runs the whole chain end to end and tells you in one line what it found — whether Claude Code is running Plexus's hooks, whether they are reaching Plexus, and whether this session is pointing at an older run of the app and needs restarting.

It also reports what happened on the session's last real turn, not just a test, so a problem that has already happened can be diagnosed without reproducing it. Copy report puts the whole thing on your clipboard for a bug report. Plexus's own secret is never in it. Claude Code reports hook errors for the whole turn rather than per hook, so if any of your other hooks failed their errors appear too — that is where your own API keys can end up, so those errors stay on screen and are kept out of the copied report unless you turn on Include these in Copy report underneath them. The report still says how many there were, so nobody reads it as "no errors".

Anonymous usage data is now always on

Plexus has always sent one small message a day: your operating system, your processor type, the app version, and a random install id that our server scrambles with a key that changes every day, so today's message can't be matched against yesterday's. It is what tells us how many people actually use Plexus — the number every decision about what to build next rests on.

That message is now part of the app, it carries more, and the Share anonymous usage data setting is gone, along with the Privacy page in Settings that held nothing else. If you had switched that setting off, it is now on again. We are telling you plainly rather than letting you find out: the reason the switch went is that there is nothing in what we send that identifies you, your machine, or your work, and a switch labelled "share anonymous usage data" suggests otherwise.

The message now also carries how much the app was used since the previous one — how many sessions you ran, how many turns you exchanged with an agent, how often each feature and Git operation was used, and how often things failed and in what broad way. Alongside that it carries a few coarse facts about your setup: your colour theme, which model you have selected, whether a Git provider is connected, how many workspaces and projects you have as a range like "6-20" rather than an exact figure, your operating-system version, how Plexus was installed, your shell, and the version of the Claude CLI it is driving.

What is never sent has not changed, and this is the part that matters: no code, no file contents, no prompts, no file paths, no repository, project or branch names, no commit or pull-request text, no error messages, no IP address. Nothing you type is ever part of it, and every value we do send is either a number or one of a fixed set of options — never free text.

Three things keep it anonymous rather than merely promised. The usage counts are added into shared daily totals the moment they arrive and are never stored against your install, so no record of "what this install did" exists on our side at any point. The daily id used to count how many installs were active is deleted every night once it has been counted. And the random install id stored on your own machine now expires after a year — Plexus replaces it with a new one, so nothing identifying the install persists indefinitely, and there is no version of it we could go back and join anything to. What survives is aggregate: "1,240 active installs on macOS running 0.18.0". It is all stored in the EU.

If you need Plexus to send nothing at all — a locked-down machine, an offline-by-policy network — it still honours the DO_NOT_TRACK and PLEXUS_NO_TELEMETRY environment variables. Set either one before launching and no message is sent. Development builds never send anything either.

The full detail, including the legal basis, is in the Privacy Policy at https://runplexus.com/legal/privacy.

Fixes

  • A session whose folder is spelled differently from how Plexus recorded it — a different drive-letter case, a trailing slash, one of Windows' long-path prefixes — no longer loses its activity updates.
  • When the check finds that a session's hooks point at an earlier run of Plexus, or that it has none at all, it can now repair them in place — no restart, so the agent keeps its conversation and whatever it is in the middle of. If you have just updated Claude Code, the repair picks that up as well and switches the session to the newer, shell-free method — without restarting Plexus either.
  • Turning on Diagnostic logging in Settings → Advanced now records the whole activity chain: whether the hooks were installed, whether Claude Code ran them, whether they reached Plexus, and which session they were matched to.
v0.17.1

A commit graph that stays on screen, and links that open

The project Git tab's commit graph could go blank and stay blank until you switched to another tab and back. It no longer can — and while you are down in a repository's history, refreshing now keeps your place instead of throwing it away.

Clicking a link in Plexus mostly did nothing, either. The Open in browser button on a pull-request comment, a link inside a comment someone wrote on your PR, a link in a markdown file you were previewing, a dependency's homepage on the About screen, a link in this very changelog window — all of them were dead. Not slow, not an error: nothing at all. They open now.

The commit graph no longer goes blank

Scrolling a fair way down a project's commit history and then doing anything that reloaded it could leave the graph pane empty. Deleting a branch was the easiest way to hit it, but it did not need a git operation at all: leaving Plexus and coming back, or an agent committing in a session worktree of the same repository, would do it just as well. Nothing brought the graph back except switching to another tab and returning — and typing into Search commits while scrolled down could empty the pane the same way, taking the search results with it.

The pane now stays on the deepest position that still exists whenever the history under it gets shorter, so there is nothing left to strand it.

Refreshing keeps your place in the history

Loading more commits and then refreshing used to snap you back to the most recent 200, which happened on every commit, checkout, branch switch and background refresh. A refresh now reloads as much history as you had actually loaded, so the graph stays where you were reading.

The graph says when it is loading, and when it could not load

If reading a repository's history failed, the graph pane simply sat empty with no explanation and no way to try again. It now tells you it is loading while it works, and shows what went wrong with a Try again button if it could not.

The button that started it was the small Open in browser icon on a pull-request comment thread in the Review tab, and the read them on the provider link next to a thread Plexus had only fetched part of. Both went nowhere. The same fault was underneath every other link in the app that was written as markdown rather than as a button — links inside PR comment bodies, in the Explorer's markdown preview, in an AI session summary, and in the What's new window you are probably reading this in.

mailto: links now open your mail client, too. They used to be styled as links, sit there looking clickable, and do nothing.

Where Plexus genuinely cannot open something — an address in a form no browser handles — it no longer shows you a button for it. A dependency on Settings → About whose homepage Plexus can't open is now printed as plain text instead of a link that fails silently, and a pull-request comment whose permalink is unusable simply has no button. If your system refuses to open a link, you get a message saying so rather than nothing happening.

Session summaries can't lose the window

A link in an AI session summary was worse than dead. Summaries are written by the agent, and if one contained a link to a file in the repository — the kind of thing an agent writes without thinking about it — clicking it replaced Plexus's own window with a blank page, with no way back except quitting and reopening the app.

Links in a summary now behave like links everywhere else: the ones that point at a real web page open in your browser, and the ones that point at a file in your repository do nothing at all.

v0.17.0

Remotes without a terminal, discarding where you are looking, and a file list that remembers

The project Git tab can now add, edit and remove the repository's remotes: right-click a remote's heading in the refs panel to rename it, point it somewhere else, or drop it — and hover it to see where it actually points.

Throwing away uncommitted work has stopped meaning a hunt through the panel header, too. Changed files answer to a right-click like everything else in the git client, the whole working tree can go in one action, and a single hunk can go without the rest of the file. And in the Review tab, resolving a comment no longer drops the file from the file list — each row now says both how many comments are still open and how many have been dealt with.

Add, edit and remove remotes

Until now the Git tab showed you the remotes your repository had and left changing them to a terminal. Each remote's heading in the refs panel is now a menu: Edit remote…, Add remote…, Remove remote…, and copies of its URL and its name. Hovering that heading tells you the URL it points at, and the separate push URL underneath when it has one — so a repository whose origin quietly points at the wrong fork is something you can now see rather than something you find out about on the next push.

Add remote… takes a name and a URL — HTTPS, SSH, or a path to a repository on your own machine. Edit remote… renames it, repoints it, and can give it a separate push URL so fetches and pushes go to different places. Renaming is the safe kind of rewrite: the remote's branches move to the new name and every local branch that was tracking one is repointed for you.

If the repository has no remotes at all, the refs panel offers Add remote… on the spot, and so does the Pull button's menu — with nothing to pull from, there is no heading to right-click.

Adding a remote doesn't reach out to it

The Add dialog has a Fetch after adding switch, on by default, that runs an ordinary fetch right after. The two stay separate steps on purpose: a typo in the URL or a credential the remote won't accept is then reported as a fetch that failed against a remote that was still added properly, rather than as an add that half-worked and left you guessing which half.

Credentials stored in a URL are left alone

Some remote URLs carry a password or a token in them. Plexus shows those URLs without it, and the Edit dialog leaves that field empty with the stripped URL as a hint. Leave it empty and the stored URL is kept exactly as it is, credential included; type a new one and it replaces the whole thing, so put the credential back in if you still need it there.

What removing costs, and what it doesn't

Removing a remote deletes your local copies of its branches and clears the upstream of every local branch that tracked one. The confirmation spells that out first, down to which branch copies go and how many locals lose their upstream. Your own branches and their commits stay put, and nothing at all changes on the server.

Two things are worth knowing before you rename or remove one. Remotes belong to the repository, not to a session: every session of a project works in a linked copy of the same checkout, so the change reaches all of them at once. And Plexus finds a project's pull requests through the remote called origin — so renaming or removing that one clears its record of which pull request belongs to which session, and the badges showing it. Nothing is lost on GitHub or Bitbucket: those links come back on the next refresh, worked out from wherever origin points now.

Right-click a changed file

Every other row in the git client has a right-click menu — branches, tags, stashes, worktrees, commits. Changed files did not, which made Discard hard to find: it only appeared in the panel header once you had already selected something, and the header is nowhere near the file you are looking at.

Changed files now have their own menu, in both the project Git client and a session's Git tab. It stages or unstages the file, copies its path or its name, and discards it. On a conflicted file it offers Take ours and Take theirs instead, with discard greyed out until the conflict is resolved.

The menu follows the same rule your file manager does. Right-click a file that is already part of a selection and the whole selection is what gets discarded — the entry says which, reading Discard 3 files… rather than Discard changes…. Right-click anywhere else and that one file becomes the selection first. Staging is the exception, and the labels make it obvious: it always acts on just the file you clicked.

Discard all changes

Stage all and Unstage all have always been one click. Discarding everything meant selecting every row by hand. With nothing selected, the header now offers Discard all.

Every tracked file goes back to its state at the last commit, and every new file is deleted from disk — including new files you have already staged, which have never been committed either. A switch in the confirmation turns that second part off if you would rather keep them, and the dialog says how many of each it found before you commit to anything. Empty folders left behind by deleted files go too, which the per-file discard never handled.

Files ignored by .gitignore are never touched, and there is no switch that changes that. Your node_modules, your build output and your local .env are not part of "your changes" — they never appear in the file list, so a confirmation could not honestly show you what it was about to delete. If you genuinely want that, git clean -xfd in the built-in terminal is one line and carries its own warning.

Discard all also refuses while a merge, rebase, cherry-pick or revert is in progress. Reverting the working tree underneath one of those does not cancel it — it strands it, leaving git convinced an operation is still running over files that no longer contain the resolution. Finish or abort it from the conflict banner first, and the button explains itself in the meantime.

Discard a single hunk

Diffs in the project Git client already let you stage one hunk at a time. Each hunk on the unstaged side now carries a Discard hunk button next to Stage hunk, for the case where one experiment in a file did not work out and the rest of it did.

It reverts only those lines, and only in the working tree. Anything you have already staged in the same file is left exactly as it was, so a file you were carefully splitting across two commits stays split.

To discard a hunk you have already staged, unstage it first and then discard it. That is one extra click and it is deliberate: once a file is both staged and further edited, "remove just the staged half of these lines" has no single correct answer, and guessing at one would quietly destroy the other half. Unstaging first merges the two into the hunk you can actually see, so you are confirming against the real result.

Discarding still cannot be undone and still never stashes anything on your behalf. Stash sits next to it for when you might want the work back.

Resolved comments stay on the file list

A file with comments used to carry one badge — a speech bubble and a count of its open comments. Resolve them all and the badge went away, which left a file you had just read and worked through looking exactly like one nobody had ever opened.

Each row now shows two badges: a speech bubble with the open comments, and a check with the resolved ones. Either appears only when it has something to count, so a file whose comments are all resolved still says so, and a file with no comments still shows nothing at all.

This was most confusing where Plexus resolves comments for you. Send N comments to agent resolves everything it sends, and so does each round of the review-and-fix cycle — so handing a whole review over used to blank the entire sidebar in one click. It now reads as a count of resolved comments per file: a record of what was addressed, on the files it was addressed on.

While the pull request conversation is shown, both badges count its threads too — open threads in the speech bubble, resolved ones in the check. Hide the conversation and they go back to counting only your own notes, so a badge never points at a comment the tab isn't showing you. (A pull request thread that no longer lines up with the diff still counts on its file — you'll find that one in the conversation rather than on a diff line.)

v0.16.1

Git that authenticates itself, and a What's new window that shows up

Fetch and push can now use the GitHub or Bitbucket account you connected in Plexus when your machine has no credentials of its own. The What's new window no longer sits out the update that introduced it, and a release now runs down the side of it rather than across the top.

Your connected provider now authenticates git too

Fetch, Pull and Push run the real git on your machine, so they have always used your own credentials — a credential helper, an SSH key, whatever git fetch would use in a terminal. On a machine that has none of those for an https remote, that was the end of it: the operation simply failed, even for people who had signed into GitHub or Bitbucket in Plexus.

That connection now counts. If your machine's own credentials can't authenticate an https remote on GitHub or Bitbucket, Plexus retries the operation once with the account you connected in Settings → Git providers — including background fetches, which cannot ask you for anything. Most people will simply notice that Fetch works now.

Your own credentials still go first, always. The connection is only ever tried after git's own attempt has failed, so a credential helper with wider access than your Plexus connection keeps being the one that authenticates, and nothing about a setup that already works changes. The token is offered only to the provider's own host, only for that one command — never written into your repository's config or its remote URL. ssh remotes are untouched.

And if the provider turns that connection down — the account can't reach the repository, the grant was revoked, your organization hasn't authorized it — Plexus rests it for a few minutes instead of doubling every fetch with an attempt it already knows will fail. Reconnecting the provider clears that immediately, so following the error's own advice never means waiting.

Git errors that say what to do

A git operation that couldn't authenticate used to report git's own words:

git command failed: fatal: could not read Password for 'https://you@bitbucket.org': terminal prompts disabled

Which reads like a Plexus fault, and isn't — "terminal prompts disabled" is Plexus deciding never to hang on a password box you can't see. That message now names the host that refused and what will fix it: connect the provider, sort out your credential helper, or switch the remote to ssh. If the credentials that were tried got refused — an expired app password, a revoked token — it says that instead, which is a different problem with a different fix.

The What's new window

Plexus shows a What's new window the first time you run a new version. Until now it stayed quiet unless it already had a record of what you had last been shown — which nobody had before the window itself existed, so the release that introduced it was the one release it could not announce. It now opens after an update, with the notes for the version you have just moved to.

A brand-new install still opens straight into Plexus. A first launch is not an update, and nobody's first minute with an app should be a wall of release notes.

The window is also wider, and the changes in a release are listed down the left-hand side rather than across the top, so you can see everything a release contains at a glance instead of scrolling a strip of tabs. A long entry scrolls on its own, while the title, the release you are reading and the buttons stay where they are.

v0.16.0

Sessions on branches you already have, hooks that add up, and a What's new window

Sessions can now start on a branch that already exists, repository hooks run alongside the ones you set up rather than replacing them, and every release explains itself — in the app and on the web.

Release notes you can actually read

Plexus now keeps a changelog. Every release is published at runplexus.com/changelog, and the app shows you what changed in a What's new window the first time you run a new version — one tab per feature, so each one gets room to explain itself rather than a single line in a toast.

You will only ever see it once per version. If you skipped a few releases, they are all there, selectable from the top of the window. You can reopen it any time from Settings → About → What's new.

Repository hooks run alongside your own

A repository that commits a .plexus/hooks.json used to replace the hooks you had set up in Plexus for that project — every event, even the ones the file says nothing about. Both sets run now. Cloning a repo still gets you the team's setup, and it no longer costs you the hooks you added for yourself.

How repository hooks combine with yours (Settings → Worktrees & Hooks) decides which set goes first: the repository's hooks first (the default), yours first, or repository hooks only. That last value is the old behaviour, if you want it back. Like the other hook settings it layers global → workspace → project, so one choice can cover everything and a single project can still differ.

If you used repository hooks before this version

Hooks you set up in Plexus for such a project start running again the next time a session starts, resumes, or is torn down — including the teardown that runs when you delete a session or a project. Open Settings → Worktrees & Hooks on the project to see exactly what will run; the editor points this out once, on projects that have both.

Plexus tells you when a connection needs renewing

GitHub and Bitbucket grant a token the permissions the app had at the moment you signed in. If that set later changes, your existing connection quietly keeps the narrower access — and refreshing it in the background never widens it. Until now you found out when something failed: a repository search that couldn't list anything, or a pull-request status that stopped updating.

Plexus now checks for itself, shortly after starting and occasionally while you work. When the access no longer covers what it needs, a notice names the missing permission — in the wording the provider itself uses, like Bitbucket's Workspace membership: Read — and offers Reconnect right there, so you sign in without leaving what you were doing.

It then re-checks before telling you it worked. Signing in again is not what clears the warning; the check is. So if a reconnect happens to land on the same narrow access, Plexus says so plainly and stops asking, rather than sending you round the same loop. Settings → Git providers keeps showing the warning until a check finds the access restored, and a later permissions change raises a fresh notice — dismissing one never silences the next.

Two settings under Settings → Git & PRs → Connection checks control it: Check that provider connections still work turns it off entirely, and How often to check provider connections (hours) spaces the checks out on a metered connection or a rate-limited account.

Settings grouped into sections

Settings pages are no longer one long list. Related settings now sit together under a heading with a line describing what the group covers — Pull requests, Code review, Fetching and remotes, and so on. Nothing moved between pages, so anything you knew where to find is still on the same page.

Override one group at a time

On a workspace's or project's settings, Override parent settings now belongs to each section rather than to the whole page. You can override Copied files for one project and leave Session folders and Lifecycle hooks inheriting, and turning a section back off clears only that section's overrides.

One consequence worth knowing: if you had previously overridden a whole page to change a single value, only the sections you actually edited will show as overridden. Nothing you set has been lost — the rest of that page was inheriting all along, and now says so.

Start a session on a branch that already exists

Starting a session always cut a new branch for it. Now the New session dialog has a mode switch: keep New branch for that, or pick Existing branch to check out a branch that is already there. Point a session at a colleague's pushed branch to carry it forward, or at one you have been asked to look at, and review it with the agent in a worktree of its own.

Branch is what gets checked out; Compare with is what the Review tab diffs against, what Rebase onto… targets, and the base of any pull request you open. It defaults to your repository's trunk — usually main — rather than whatever your main working copy happens to be on, so a branch you did not cut is compared against something meaningful.

A branch that only exists on the remote works the same way: Plexus creates a local branch tracking it, so it starts at the remote's tip and ahead/behind counts are right from the start.

Git allows a branch in exactly one working copy at a time, so a branch that is already checked out is shown greyed out with the reason — the session holding it, your project's own working copy, or a leftover worktree record you can clear from the Git tab.

Pull base branch first becomes Pull the branch first in this mode: it fetches, then fast-forwards the branch you picked, so you do not quietly start on a copy from last week.

Plexus will not delete a branch it did not create

Cancelling a start, a setup script that stops the launch, or an agent that fails to start all clean up the session's working copy — but a branch that was already there is left alone. Only a branch Plexus cut for the session is removed, exactly as before.

Deleting one on purpose is still possible: Also delete the local branch asks a second time and names the branch, and it is never pre-ticked from your last answer the way it is for a branch Plexus created. Git then keeps any branch still carrying commits that are not merged anywhere else, and Plexus tells you it did. Deleting a project or workspace works the same way, listing the branches it did not create before it touches them.

One thing to keep in mind

Rebase and Squash rewrite the branch's history. On a branch you share with other people, that is history they may already have — so Plexus warns rather than stopping you. Nothing leaves your machine until you push, and Plexus never force-pushes.

The pull request conversation stays out of the way

The Pull request conversation section at the top of the Review tab now starts collapsed, so opening the tab shows you the diff rather than a wall of remote comments. Opening it is for the visit you're on — come back to the tab later and it's closed again.

Collapsed, its header still tells you what it's holding: a count of what's actually inside the section, an Approved or Changes requested chip when a reviewer left a verdict, and a warning triangle when only part of a very busy conversation could be fetched. Comment on the PR and Send N PR comments to agent stay where they were, so neither needs the section open.

Opened, the section takes at most about 40% of the tab and scrolls inside that, with its header staying put. A long conversation can no longer squeeze the diff off the screen.

The count now describes what's behind it

It used to count every thread on the pull request, including the ones that render against their diff lines further down. It now counts what opening the section actually gives you — the comments that have no home on a line, plus the review verdicts.

Approving without writing anything counts

A reviewer who clicks Approve and leaves the comment box empty — GitHub's default — used to be dropped entirely on the way in. If they had asked for changes earlier, Plexus went on reporting Changes requested long after they had approved. Empty-bodied decisions now come through and appear as a one-line entry with the reviewer's name and the verdict.

The chip also reads the review history correctly: each reviewer's most recent decision counts, so an approval replaces that same reviewer's earlier Changes requested, while one reviewer still asking for changes outweighs everyone else's approval.

Writing a comment has room of its own

Comment on the PR opens its box below the section rather than inside it, so the conversation's size limit never squeezes what you're typing, and collapsing the section while you write is a way to make room — your text stays put when you do.

v0.15.0

Side-by-side diffs, PR conversations, and steadier Windows sessions

A big review release: diffs can now be read side by side, pull-request conversations live inside the Review tab, and several long-standing Windows rough edges are gone.

Side-by-side diffs

Every diff pane — session Review, the Git tab, and the project Git client — now has a Unified / Split switcher. Split lays the old and new sides next to each other and marks the words that actually changed within a line, so a rename or a reordered argument reads at a glance instead of as two near-identical rows.

Your choice is remembered globally and applies to all three panes at once. Review comments work the same in both layouts: an anchor still belongs to a line, not to a column.

Pull-request conversations

Once a session has a pull request, the provider's own review conversation is rendered in the Review tab beside your local notes — never merged into them. Works with both GitHub and Bitbucket.

For each thread you can Reply, Resolve, or hand the whole thread to the agent to act on. Comments that no longer point at any line in the current diff collect in a collapsible Pull request conversation strip rather than silently disappearing.

Search your repositories when adding a project

The repository picker's search box now actually filters. Type to search the repositories you can see on a connected provider, with a refresh control beside the box for a repository you have just created. When the list is capped, the footnote says so plainly instead of pretending it searched everything.

Worktrees that clean up after themselves

Deleting a session — or a whole project or workspace — now reliably removes the git worktree that went with it. Previously the .git/worktrees entry could outlive its directory, which left git holding the branch and refusing to reuse it.

The Git tab's refs panel gained a cleanup action for metadata stranded by older versions, and Plexus reclaims what it can at startup. When it deliberately keeps something — a branch you may still want, a worktree an agent is still using — it now says so rather than acting silently.

Windows: sessions that start, and stay started

Three separate wedges are fixed. Starting a session no longer hangs on a "Starting…" spinner that only a restart could clear. Resuming a session resumes the actual conversation instead of opening a fresh one. And the review-and-fix cycle no longer freezes the window after its first round.

If Windows has been asking "Are you sure you want to uninstall this product?" every time Plexus updates, it can now find the older installation responsible and offer to remove it — see Settings → About.

Plexus keeps itself up to date — see Installation for the update flow, or browse every release asset on GitHub.