7.8.0
The editor you actually use is one click away, the composer stops moving under the
cursor, and a terminal pane you can no longer type into has two ways back.
Open the workspace in VS Code
-
One button, local or remote. A project row and the file viewer now hand the
workspace to your desktop editor. A remote SSH project opens through VS Code
Remote-SSH, already at the right path — no reconnecting by hand, no hunting for
the folder. -
It opens on the machine you are sitting at. The studio launches the editor
itself when it can find acodebinary on the host; when it cannot — inside
Docker, on a headless server, on Windows — it hands your browser avscode://
link instead, and the desktop handler takes it from there. One rule, no
platform-sniffing, and it lands correctly whether the studio runs on your laptop
or three time zones away. -
Not only VS Code. Insiders, VSCodium, Cursor and Windsurf are selectable in
Settings → UI. All four are VS Code forks, so the remote-SSH link means the same
thing in each; only the scheme and the binary change. -
A remote workspace on a non-standard port carries it. Omitting the port would
not be the cautious choice — the connection would simply be attempted against 22
and fail. -
Refusals say what is wrong. A remote project recorded with a
~/project
workdir cannot be expressed as a URI (Remote-SSH would look for a directory
literally named~), so it is refused by name rather than opening the wrong
folder. Per-file opening stays local-only on purpose: VS Code's own URL handler
opens a remote file link as a folder, so the button comes off rather than doing
the wrong thing — the project row still opens the remote workspace.
The composer stopped moving under the cursor
Four defects reported against the shipped build, none of them a regression: each was
work that never reached a commit. Two of them are the composer, two the terminal pane.
-
The interrupt pill no longer shoves the placeholder. It sat upstream of the
textarea in a flex row, so every earlier sibling owned the text's left edge: the
moment a turn started, the hint jumped ~70px to the right and the narrower box
re-wrapped it. The pill now lives downstream of the textarea, where it appears and
disappears without moving a glyph. -
One place computes the composer's height. The formula was already right; it
simply ran from one function. Boot (the markup shipsrows="1"), a language switch
(a longer translation wraps differently), a sidebar toggle, a window resize and the
pill entering the row all changed the wrap without re-measuring, which is what left
the second line of the hint clipped.autosizeInput()now owns the cap and is
called from all seven paths.
An adversarial review of the diff (an independent non-Claude reviewer, run before the
merge) turned up four more, all fixed here: the composer was measured at the start of
the 250ms sidebar animation, a superseded socket's close event could mark a working
terminal "disconnected", a bare Return — the one key you most need at a [Y/n] prompt —
was the one key the send line refused to send, and a draft left in that line followed the
user to whichever terminal they opened next.
Terminal sessions
-
A pane no longer goes deaf until you switch tabs and back. xterm routes
keystrokes through a hidden textarea; a reconnect swapped the socket but left focus
wherever it had drifted, so the pane looked live and swallowed every key. The tab
switch "fixed" it only becauseshowTerminalView()ends onterm.focus(). A
reconnect and a click on the pane now do the same -- and a click is ignored while a
selection is being dragged out. -
A reconnect button in the terminal header. Every automatic path is conditional:
the visibility handler and the tab switch only act on a socket that already reports
closing, andoncloseonly fires if a close event ever arrives. A socket whose TCP
path died without a FIN reports OPEN on both ends -- the server heartbeat kills those
within ~60s, but that is a timeout, not an answer to "it is stuck now". -
A send line under the pane. The composer is
display: nonein terminal mode, so
the only way to send a line to a terminal session was to type into the pane -- exactly
what a stale socket takes away. The new input writes the same{type:'input'}frame
the pane writes, so it works on an agent tab and on the subscription engine's pane,
where it is how a blocking permission prompt gets answered. It refuses to send on a
socket that is not OPEN rather than dropping the line silently.