Commit Graph
14535 Commits
Author SHA1 Message Date
Neil 294fd2ac06 fix(agent-hooks): bound retained agent exits (#29600)
* fix(agent-hooks): bound retained agent exits

Proven exits were only forgotten by a successor claim, so closed tabs and
retired panes kept theirs forever and every save rewrote them. Drop an exit
when its tab closes, its pane retires or its PTY is really torn down (not a
reconnectable disconnect), and prune exits older than the hydrate window
at save.

* fix(agent-hooks): closing a moved pane's former tab keeps its exit

* fix(agent-hooks): keep an aged exit while its retained resume row remains

* fix(agent-hooks): launch-authority retirement keeps a proven exit
2026-10-16 03:01:41 -07:00
OrcaWinandOrcaWin b56cc369f0 test(runtime): verify mobile geometry through desktop restores (#29323)
* test: batch lint fixtures and remove repeated runtime scan

* test(cli): consolidate owner coverage and remove false decoding proof

* test(renderer): retain IPC lifecycle behavior without copied inventories

* test: share floating panel behavior suite startup

* test: retire synthetic runtime constructor probes

* test: share saved terminal title runtime setup

* test: share native chat render cost setup

* test: share terminal close continuity runtime setup

* test(runtime): prove mobile geometry through desktop restores

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 02:58:20 -07:00
Neil e687b183b6 fix(ssh): bind relay-era legacy coordinators to their host, cap inbox reads, and name orchestration in the reset notice (STA-10765) (#29596) 2026-10-16 02:57:18 -07:00
OrcaWinandOrcaWin c0251f95b0 test: reset directory creation failures for every history case (#29590)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 02:55:10 -07:00
OrcaWinandOrcaWin 10145cb318 perf: import onboarding notification function directly (#29570)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 02:54:58 -07:00
OrcaWinandOrcaWin feea786c93 test: prove diff reveal cancels a paging rail jump (#29585)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 02:54:08 -07:00
Neil b16a71c7fb ci: reuse Windows hook builds and shorten test setup and shutdown (#29439)
* ci: remove Windows build and persistence test overhead

* ci: collect unit phase diagnostics during PR checks

* test(ci): seed hook reuse fixture from the canonical prebuild

The hook reuse regression first built into a missing private --output, so it
always reached Cargo (74s warm on Windows). Build through the default output
instead, which reuses a warm canonical prebuild, then copy its executable and
fingerprint into the private fixture root.

* fix(lint): clear inherited max-lines and broad object tab parameter after main merge

Combine the duplicate shared/execution-host imports in runtime-host-services
(301 -> 300 lines) and type the overlap test's tab mapper with the
RuntimeMobileSessionClientTab owner type instead of object.

* fix(ci): align inherited runtime and workflow contracts

* test: establish changed runtime probe signatures deterministically

* test: await asynchronous daemon profile cleanup

* test: shut down owned daemons before deleting profiles

* test: clean up oracle daemons during final app close

* test: recognize verified Linux zombie exit during daemon teardown

* fix: preserve folder SSH ownership when project groups conflict
2026-10-16 02:52:22 -07:00
Neil f387c5d19b fix(ssh): relay-era terminals' orca orchestration commands work again, behind the per-host switch (STA-10765) (#29571)
* fix(ssh): relay-era terminals' orca orchestration commands work again, behind the per-host switch (STA-10765)

* fix(ssh): attest bridge-verified relay terminals for legacy records, replay settled receipts, cancel on disconnect

* fix(ssh): admit retained legacy coordinators, their delivery targets, and legacy receipt replays

* fix(ssh): reject emptied retry ids, match moved panes by leaf, replay completed retries after reassignment

* fix(ssh): answer --help in a relay-era terminal without running the command

* fix(ssh): exempt only matching mutation replays from relay CLI scope; keep legacy retries replayable after reassignment

* fix(ssh): relay CLI security review: pane-bound legacy coordinators only, revoke and cap calls, exact-hash replays, target-aware identity, consent copy

* fix(ssh): admit settled legacy workers only with a committed receipt; honor exact reply replays
2026-10-16 02:50:24 -07:00
Neil 2346970e97 fix(runtime): keep one worktree spelling for an early alias session-tabs stream (#29592) 2026-10-16 02:49:52 -07:00
Neil b95ea32797 fix(orcad): skip the moved shell-history pass on starts with nothing to install (#29556)
Every orcad start ran installPendingOrcadMigrationShellHistory, which paid a
process inventory with an empty worktree list. That inventory could leave a
surviving daemon session unfiled and drop its restored orchestration receipt
before any client connected. Return early unless a committed migration still
holds a received shell history, and refresh against the host's real worktrees
when one does.

Follow-up to #28902.
2026-10-16 02:47:02 -07:00
Neil da14046614 fix(orcad): free a lock whose PID another user now owns, and explain a possibly reused PID (#29548)
* fix(orcad): reclaim a pre-#28125 lock whose PID another user now owns, and explain a possibly reused PID

Records written before #28125 carry no start ticks or boot id, so on Linux a
wall-clock mismatch is unproven and a reused PID kept the lock held forever.
A PID owned by another non-root uid cannot be the holder (orcad never changes
uid), so that now proves reuse in both lock reclaim and managed stop. When the
verdict stays unproven, the error names the live process and the orcad.lock
path that is safe to remove once no orcad is running.

* fix(orcad): treat the overflow uid as unproven and word the reused-PID error for any boot-less record

* test(orcad): keep the Linux-platform lock cases off Windows, where the platform hook also drives data-root privacy
2026-10-16 02:45:29 -07:00
Jinwoo HongandClaude 115c26e1b8 Open and close browser tabs and pages through main behind the layout-owner build switch (off by default) (#29353)
* feat(layout): add the dark layout.apply channel and route pane splits through main behind ORCA_LAYOUT_OWNER

A build made with ORCA_LAYOUT_OWNER=main registers layout.apply: main applies the
window's layout command to the stored partition through the shared applyLayoutCommand,
minting new ids. A user split then waits for main's answer and mounts the pane id main
minted. Every other build substitutes 'window', so neither branch is compiled in.

* fix(layout): write only the records a layout.apply command touched

A load-then-save rewrite also normalizes records the command never touched. The command's
effect is now the diff between the save before and after it, written onto the stored
partition record by record. A split whose main reply says a paired server holds the tab
splits as today.

* fix(layout): write a load-supplied record whole and check that patched partitions reload to the command's result

* feat(layout): close, rename and equalize panes through main behind ORCA_LAYOUT_OWNER

In a layout-owner build the window's pane close, title change and equalize go through
layout.apply and the window shows main's answer. A window pane close keeps the legacy
close's rules: the tab's last pane is refused, a pane restarted since main read the close is
left alone, every partition holding the tab closes it, and the tab's remote session id follows
the remaining pane. The rules sit behind a command field only layout.apply sets.

* fix(layout): close the tab when a racing pane close leaves the window one pane

* fix(layout): leave an unmounted tab alone when main refuses its last pane

* feat(layout): move panes and save divider ratios through main behind ORCA_LAYOUT_OWNER

Claude-Session: 10569c9a-a0a1-4fc9-8469-0edfb7aed125

* test(layout): a taken pane drop whose pane closed does nothing

Claude-Session: 10569c9a-a0a1-4fc9-8469-0edfb7aed125

* test(layout): pin the window's pane move to main's saved tree, and the drops main cannot take

Claude-Session: 10569c9a-a0a1-4fc9-8469-0edfb7aed125

* fix(layout): close a user's pane even if its terminal restarted, as today

Claude-Session: 10569c9a-a0a1-4fc9-8469-0edfb7aed125

* test(layout): pin the restarted-pane close directly, not through a made-up profile state

Claude-Session: 10569c9a-a0a1-4fc9-8469-0edfb7aed125

* fix(layout): leave a split to today's path only when the workspace's row names a paired server

The split switch point asked which host to route to with a helper that falls back to the focused
server, so a focused server could claim a workspace whose row names no owner. Use the same owner
test the tab mirror uses.

* test(layout): type the split owner mock without a cast

* test(layout): type the layout-owner command mocks with the real signature

* test(layout): type the gesture command mock with the real signature

* fix(layout): close the dark path's gaps: unmounted split panes, refused or failed splits and moves, ratios during a move, release guard

- A pane main saved but the window could not mount (source pane or manager gone during the await)
  is closed again in main, so it does not come back on restart.
- A split main refuses because its copy lacks the workspace, tab or pane, or a failed call, splits
  as today; a refused or failed move moves as today.
- Divider ratios committed while a move is in flight wait for the window's move, then go to main.
- The orcad bundle gets the ORCA_LAYOUT_OWNER define when the switch is on.
- Packaging and the orcad template refuse ORCA_LAYOUT_OWNER=main and any output a dark build marked.
- workspace-layout-record-patch.ts: no non-null assertions; plain comment for the map depth.

* test(layout): count a split pane as mounted from the split mock's own results

* fix(layout): act as today whenever main lacks the target or the call throws, not just for splits

- sendPaneCommandToLayoutOwner runs asToday for workspace/tab/pane_not_found and a thrown call, so
  close, rename and equalize fall back like split and move; a handler that throws no longer runs the
  fallback too.
- A close main refuses as its last pane, while this window still has others, closes as today.
- A move whose local step throws still releases held divider ratios.
- Drop the orcad output marker: nothing read it; the template build refuses the switch itself.

* test(layout): plain names for the last-pane fallback test and the marker comment

* docs(layout): say plainly what an indeterminate write can leave behind

* fix(layout): finish the main merge with this branch's versions of the layout-owner files

* test(build): copy the layout-owner build guard into the compiler-cache checkout fixture

* feat(layout): send tab rename, color and pin through main behind the layout-owner build switch

In an ORCA_LAYOUT_OWNER=main build, the tab bar's rename, color and pin ask main's layout.apply
first; the window then runs today's action. When main lacks the tab or the call fails the
window acts as today; a paired server's workspace keeps today's path. Pinning a tab now also
ends its preview in main's copy, as the tab bar's pin does. Other builds compile the switch out.

* fix(layout): leave a pinned tab's preview mark to the window until main opens files

Changing the shared pin command would change what a paired client's pin does in every build.

* fix(layout): write a folded legacy row in its loaded form when a layout.apply command touches its claim

A legacy terminal row the load folds into a tab-bar tab stays stored as is. Closing the tab it
repeats, or giving it a tab-bar entry by moving it, let the next load resolve the claim the other
way: the row came back or took the other tab's terminal. Such a command now writes the row as
the load had it; every other record still stays as stored.

* feat(layout): accept tab moves, group splits and group sizes on layout.apply

Group sizes have no tab, so they go to the workspace's routed partition.

* refactor(layout): move the window's layout.apply sender out of the terminal pane folder

Tab groups send through it too; it now also acts as today when main lacks the group.

* feat(layout): reorder, move and split tab groups, and save group sizes, through main behind ORCA_LAYOUT_OWNER

A tab drop and Move Tab to Split wait for main's answer and then show main's placement, with main's
new group id; group divider sizes are drawn while dragging and saved by main when the drag ends.
Closing an empty group needs no command: main never holds an empty group.

* docs(layout): wrap the layout-owner sender's doc comment

* fix(layout): review fixes for tab moves through main

- Read a folded row's terminals with the loader's own claim rule, so rows sharing only an SSH
  session are covered too, and drop the row's remote session entry with it.
- The record-patch test allows a folded row only in its loaded form.
- A tab drag ends at once; main's answer shows the move after.
- A lone group main moved whole is placed so only when this window's group is lone too.

* refactor(layout): adopt only a folded row's pane layout beside its row

A row's remote session entry is carried through load and save unchanged, so adopting it from the
load changed nothing (the earlier commit's message overstated it).

* feat(layout): record a window's terminal tab close through layout.apply

closeTabs can now record each terminal tab it closes, or does not find, as closed for the given
reason (pruned as a partition's records are), so a start that commits later is refused, as today's
close records it. layout.apply takes one tab's close with the window's reason: main forces it in
every holder partition, marks a user close's launches, stops no terminal (the window already did,
sparing any another tab shares), and leaves a workspace it lacks to today's close. A sibling the
load supplied that the close only renumbered is no longer written.

* feat(layout): send the window's terminal tab close to main behind ORCA_LAYOUT_OWNER

The window still closes the tab and stops its terminals itself; main records the close through
layout.apply instead of the close intent, which stays for paired servers and when main lacks the
workspace.

* fix(layout): review fixes for the tab close through main

- The window's close sends through a store-free sender, so the store no longer imports itself.
- Main marks a user close's launches by the terminal's own id.
- A recorded close prunes the whole partition's close records, as today, not one workspace's.

* feat(layout): open and close browser tabs and pages through main behind the layout-owner build switch

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(layout): name the browser sender's no-op so the window bundle keeps its names

* feat(layout): move a window's dragged-out pane into a new tab through layout.apply behind ORCA_LAYOUT_OWNER

* refactor(layout): keep the topology commit under its line limit

* fix(layout): keep a served browser tab's open, address and close in order while main writes it

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(layout): review fixes for the window's pane drag-out through main

* docs(layout): note what a refused served-tab close leaves

* refactor(layout): re-key a moved pane from the move alone

* refactor(layout): share one record-only layout.apply sender and inline the id schema

Co-Authored-By: Claude <noreply@anthropic.com>

* Restore the browser layout-apply hook dropped by the main merge

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-16 02:44:14 -07:00
OrcaWinandOrcaWin 1b79a3af7f test: verify history GC coalescing through live snapshot ownership (#29577)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 02:41:05 -07:00
NeilandClaude b0178a5dbc fix(orcad): prove the held-6768 fallback in e2e and keep the managed marker out of terminals (#29569)
* test(e2e): prove the held-6768 case really held the port and orcad bound another

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(pty): keep orcad's managed-launch marker out of user terminals

A terminal on a managed host inherited ORCA_ORCAD_MANAGED_ACTIVATION_ROOT, so an
orcad a user started there looked client-managed: --port stopped being strict
and idle exit applied. Scrub it like the other per-launch identity variables.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-16 02:40:53 -07:00
Neil 17a14a9d7f fix(remote): reopening a slept tab resumes when the other holder's agent has proven exited (#29588)
A pane whose shell outlived its agent kept counting as the session's live
holder because its PTY was alive, so a paired client got a plain shell.
Ask the hook store: a holder it proves exited no longer blocks the resume;
unverifiable still does.
2026-10-16 02:40:20 -07:00
Neil 67c36f3588 fix(ssh): link a stopped server's kept projects instead of re-importing them (#29560) (#29586) 2026-10-16 02:38:34 -07:00
Neil a77cf64121 fix(accounts): open the browser for a WSL account sign-in (#29566)
* fix(accounts): open the browser for a WSL account sign-in

A WSL Add account / Sign in again ran the provider CLI inside the distro,
where stock distros have no opener, so no browser opened. Claude's link is
now caught by the same BROWSER stand-in Copy link uses, Codex's by the link
it already prints, and the desktop opens it after validation.

* fix(accounts): never open a cancelled WSL sign-in's link; wait the full login window

Addresses review: watch the login's cancel signal before opening, give auto-open
the whole login window to receive Claude's link, log the refused host, and cover
cancel-before-delivery and service wiring in tests.
2026-10-16 02:35:04 -07:00
Neil 020630822d fix(terminal): clear the paused-output gap exemption once a snapshot covers it (#29582) 2026-10-16 02:34:51 -07:00
OrcaWinandOrcaWin bb58978d37 test: share terminal close continuity runtime setup (#29318)
* test: batch lint fixtures and remove repeated runtime scan

* test(cli): consolidate owner coverage and remove false decoding proof

* test(renderer): retain IPC lifecycle behavior without copied inventories

* test: share floating panel behavior suite startup

* test: retire synthetic runtime constructor probes

* test: share saved terminal title runtime setup

* test: share native chat render cost setup

* test: share terminal close continuity runtime setup

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 02:34:31 -07:00
Neil 0ef2ea4321 fix(notifications): notify for a task that finished during an SSH disconnect (#29580)
A reconnect replay seeded every cached row, so a done the renderer never saw
(its row was still working) was silently dropped. Observe a replayed done
normally when it differs from the renderer's current row.
2026-10-16 02:33:17 -07:00
Neil 6edf9e7a81 fix(ssh): clear the launch-session-ended verdict after this client relaunches the server (#29579) 2026-10-16 02:31:25 -07:00
Neil d9521f9991 fix(codex): a transcript lookup miss creates no Codex directories (#29557)
The per-account tier of the session-file resolver listed homes through
getHostCodexHomePathsForSessionDiscovery, which reached the mkdir-ing
getOrcaManagedCodexHomePath. The transcript poll runs every 5 s on a miss, so
users who never used Codex got userData/codex-runtime-home/home created. Use
the path-only resolver for discovery, and skip the per-account ownership
checks while the managed accounts root does not exist.

Follow-up to #28469.
2026-10-16 02:27:27 -07:00
Neil 088fefbb5a fix(wsl): bound the line-ending sample's index scan, not just its matches (#29552)
* fix(wsl): bound the line-ending sample's index scan, not just its matches

The WSL-on-Windows-drive line-ending sample piped ls-files --eol through grep
then head, so when no entry was eligible (* text=auto) head never closed the
pipe and every file was read over drvfs until the 15 s timeout, which stage,
discard and commit waited on after each backoff. Cap the raw ls-files output
before the grep.

Follow-up to #27778.

* docs(wsl): describe the line-ending sample as the first index entries
2026-10-16 02:27:24 -07:00
OrcaWinandOrcaWin e3f42d76a0 test: restore worktree Git spies after each case (#29558)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 02:23:50 -07:00
OrcaWinandOrcaWin ba9f70a9ee test: share diff comment lifecycle setup (#29555)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 02:23:46 -07:00
Neil baf534d5f9 fix(space): make chart zoom and Finder reveal usable (#29567)
* fix(space): make treemap zoom and workspace reveal discoverable

* fix(space): reveal folders from breakdown list
2026-10-16 02:21:54 -07:00
OrcaWinandOrcaWin 9ee7ee79bf test: share native chat render cost setup (#29316)
* test: batch lint fixtures and remove repeated runtime scan

* test(cli): consolidate owner coverage and remove false decoding proof

* test(renderer): retain IPC lifecycle behavior without copied inventories

* test: share floating panel behavior suite startup

* test: retire synthetic runtime constructor probes

* test: share saved terminal title runtime setup

* test: share native chat render cost setup

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 02:21:29 -07:00
OrcaWinandOrcaWin 2e97d9aa84 fix: resolve terminal authority from workspace owner evidence (#29565)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 02:10:23 -07:00
Neil 172a5d2015 fix(orcad): Windows orcad stops cleanly when its Electron browser sidecar's profile is still locked (#29562)
* fix(orcad): a locked Electron browser sidecar profile no longer fails orcad's stop on Windows

* test(orcad): give the stop-request teardown room for slow Windows ARM deletes
2026-10-16 01:59:52 -07:00
Jinwoo Hong 127704b5f5 Drag a pane out to a new tab through main (dark, build switch off by default) (#29351)
* feat(layout): add the dark layout.apply channel and route pane splits through main behind ORCA_LAYOUT_OWNER

A build made with ORCA_LAYOUT_OWNER=main registers layout.apply: main applies the
window's layout command to the stored partition through the shared applyLayoutCommand,
minting new ids. A user split then waits for main's answer and mounts the pane id main
minted. Every other build substitutes 'window', so neither branch is compiled in.

* fix(layout): write only the records a layout.apply command touched

A load-then-save rewrite also normalizes records the command never touched. The command's
effect is now the diff between the save before and after it, written onto the stored
partition record by record. A split whose main reply says a paired server holds the tab
splits as today.

* fix(layout): write a load-supplied record whole and check that patched partitions reload to the command's result

* feat(layout): close, rename and equalize panes through main behind ORCA_LAYOUT_OWNER

In a layout-owner build the window's pane close, title change and equalize go through
layout.apply and the window shows main's answer. A window pane close keeps the legacy
close's rules: the tab's last pane is refused, a pane restarted since main read the close is
left alone, every partition holding the tab closes it, and the tab's remote session id follows
the remaining pane. The rules sit behind a command field only layout.apply sets.

* fix(layout): close the tab when a racing pane close leaves the window one pane

* fix(layout): leave an unmounted tab alone when main refuses its last pane

* feat(layout): move panes and save divider ratios through main behind ORCA_LAYOUT_OWNER

Claude-Session: 10569c9a-a0a1-4fc9-8469-0edfb7aed125

* test(layout): a taken pane drop whose pane closed does nothing

Claude-Session: 10569c9a-a0a1-4fc9-8469-0edfb7aed125

* test(layout): pin the window's pane move to main's saved tree, and the drops main cannot take

Claude-Session: 10569c9a-a0a1-4fc9-8469-0edfb7aed125

* fix(layout): close a user's pane even if its terminal restarted, as today

Claude-Session: 10569c9a-a0a1-4fc9-8469-0edfb7aed125

* test(layout): pin the restarted-pane close directly, not through a made-up profile state

Claude-Session: 10569c9a-a0a1-4fc9-8469-0edfb7aed125

* fix(layout): leave a split to today's path only when the workspace's row names a paired server

The split switch point asked which host to route to with a helper that falls back to the focused
server, so a focused server could claim a workspace whose row names no owner. Use the same owner
test the tab mirror uses.

* test(layout): type the split owner mock without a cast

* test(layout): type the layout-owner command mocks with the real signature

* test(layout): type the gesture command mock with the real signature

* fix(layout): close the dark path's gaps: unmounted split panes, refused or failed splits and moves, ratios during a move, release guard

- A pane main saved but the window could not mount (source pane or manager gone during the await)
  is closed again in main, so it does not come back on restart.
- A split main refuses because its copy lacks the workspace, tab or pane, or a failed call, splits
  as today; a refused or failed move moves as today.
- Divider ratios committed while a move is in flight wait for the window's move, then go to main.
- The orcad bundle gets the ORCA_LAYOUT_OWNER define when the switch is on.
- Packaging and the orcad template refuse ORCA_LAYOUT_OWNER=main and any output a dark build marked.
- workspace-layout-record-patch.ts: no non-null assertions; plain comment for the map depth.

* test(layout): count a split pane as mounted from the split mock's own results

* fix(layout): act as today whenever main lacks the target or the call throws, not just for splits

- sendPaneCommandToLayoutOwner runs asToday for workspace/tab/pane_not_found and a thrown call, so
  close, rename and equalize fall back like split and move; a handler that throws no longer runs the
  fallback too.
- A close main refuses as its last pane, while this window still has others, closes as today.
- A move whose local step throws still releases held divider ratios.
- Drop the orcad output marker: nothing read it; the template build refuses the switch itself.

* test(layout): plain names for the last-pane fallback test and the marker comment

* docs(layout): say plainly what an indeterminate write can leave behind

* fix(layout): finish the main merge with this branch's versions of the layout-owner files

* test(build): copy the layout-owner build guard into the compiler-cache checkout fixture

* feat(layout): send tab rename, color and pin through main behind the layout-owner build switch

In an ORCA_LAYOUT_OWNER=main build, the tab bar's rename, color and pin ask main's layout.apply
first; the window then runs today's action. When main lacks the tab or the call fails the
window acts as today; a paired server's workspace keeps today's path. Pinning a tab now also
ends its preview in main's copy, as the tab bar's pin does. Other builds compile the switch out.

* fix(layout): leave a pinned tab's preview mark to the window until main opens files

Changing the shared pin command would change what a paired client's pin does in every build.

* fix(layout): write a folded legacy row in its loaded form when a layout.apply command touches its claim

A legacy terminal row the load folds into a tab-bar tab stays stored as is. Closing the tab it
repeats, or giving it a tab-bar entry by moving it, let the next load resolve the claim the other
way: the row came back or took the other tab's terminal. Such a command now writes the row as
the load had it; every other record still stays as stored.

* feat(layout): accept tab moves, group splits and group sizes on layout.apply

Group sizes have no tab, so they go to the workspace's routed partition.

* refactor(layout): move the window's layout.apply sender out of the terminal pane folder

Tab groups send through it too; it now also acts as today when main lacks the group.

* feat(layout): reorder, move and split tab groups, and save group sizes, through main behind ORCA_LAYOUT_OWNER

A tab drop and Move Tab to Split wait for main's answer and then show main's placement, with main's
new group id; group divider sizes are drawn while dragging and saved by main when the drag ends.
Closing an empty group needs no command: main never holds an empty group.

* docs(layout): wrap the layout-owner sender's doc comment

* fix(layout): review fixes for tab moves through main

- Read a folded row's terminals with the loader's own claim rule, so rows sharing only an SSH
  session are covered too, and drop the row's remote session entry with it.
- The record-patch test allows a folded row only in its loaded form.
- A tab drag ends at once; main's answer shows the move after.
- A lone group main moved whole is placed so only when this window's group is lone too.

* refactor(layout): adopt only a folded row's pane layout beside its row

A row's remote session entry is carried through load and save unchanged, so adopting it from the
load changed nothing (the earlier commit's message overstated it).

* feat(layout): record a window's terminal tab close through layout.apply

closeTabs can now record each terminal tab it closes, or does not find, as closed for the given
reason (pruned as a partition's records are), so a start that commits later is refused, as today's
close records it. layout.apply takes one tab's close with the window's reason: main forces it in
every holder partition, marks a user close's launches, stops no terminal (the window already did,
sparing any another tab shares), and leaves a workspace it lacks to today's close. A sibling the
load supplied that the close only renumbered is no longer written.

* feat(layout): send the window's terminal tab close to main behind ORCA_LAYOUT_OWNER

The window still closes the tab and stops its terminals itself; main records the close through
layout.apply instead of the close intent, which stays for paired servers and when main lacks the
workspace.

* fix(layout): review fixes for the tab close through main

- The window's close sends through a store-free sender, so the store no longer imports itself.
- Main marks a user close's launches by the terminal's own id.
- A recorded close prunes the whole partition's close records, as today, not one workspace's.

* feat(layout): move a window's dragged-out pane into a new tab through layout.apply behind ORCA_LAYOUT_OWNER

* refactor(layout): keep the topology commit under its line limit

* fix(layout): review fixes for the window's pane drag-out through main

* refactor(layout): re-key a moved pane from the move alone
2026-10-16 01:52:11 -07:00
OrcaWinandOrcaWin 2cf8d9bde8 test: reuse captured Codex readiness replay frames (#29542)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 01:42:16 -07:00
Neil b89373c757 test(e2e): a paired phone lists and opens a managed SSH host's projects through the desktop (#29549)
Pins #29456 end to end: relay-era SSH projects convert to a managed server, a phone paired with the desktop lists them via mobileRelay.hosts.* under the SSH host's name and opens one through the relay, while the desktop's own list keeps the retained copies hidden.
2026-10-16 01:38:40 -07:00
OrcaWinandOrcaWin 026efc3a51 test: share saved terminal title runtime setup (#29314)
* test: batch lint fixtures and remove repeated runtime scan

* test(cli): consolidate owner coverage and remove false decoding proof

* test(renderer): retain IPC lifecycle behavior without copied inventories

* test: share floating panel behavior suite startup

* test: retire synthetic runtime constructor probes

* test: share saved terminal title runtime setup

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 01:38:06 -07:00
Neil cd10ab7bfc fix(terminal): restores a host kept asleep resume in the background once it has room (#29547) 2026-10-16 01:35:27 -07:00
Neil a51e9308e5 fix(terminal): honour a paired-client close for every sleeping record shape (#29546)
* fix(terminal): honour a paired-client close for every sleeping record shape

Refs #21235. Fixes #29421.

* fix(terminal): keep foreign-host records out of the claim election
2026-10-16 01:34:31 -07:00
Neil 2529df8d5d fix(ssh): a disconnect during the legacy relay bridge wait no longer republishes connected (#29544)
Refs STA-10395
2026-10-16 01:31:58 -07:00
9216636677 fix(runtime): resolve session tab workspace path aliases (#29543)
* fix(runtime): resolve session tab workspace path aliases

An explicit worktree ID that differs from the host's stored spelling only
by Windows path separators (or another worktreeIdsEqual-equivalent form)
returned an empty session tab snapshot, hiding a workspace's existing
tabs from paired clients.

Resolve explicit session selectors against the IDs the host already
knows (published snapshots, saved session tabs, surviving renderer-owned
PTYs) with the shared worktreeIdsEqual comparison, keep the host's
stored spelling, reject ambiguous aliases, and refuse alias adoption
across execution hosts. Session-tab subscriptions match and clean up by
the normalized key.

Fixes #27260

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(runtime): keep exact live PTY spellings and reject foreign PTYs under local owners

Addresses Codex review of the #27264 alias resolver.

---------

Co-authored-by: Simon Cho <40405860+SimonSQLML@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 01:31:25 -07:00
Sungsoo KwonandClaude Fable 5.1 574cb6e348 fix(ssh): start a managed server whose active slot has no launch artifacts (#29532)
* fix(ssh): start a managed server whose slot has no launch artifacts

A recorded-active orcad slot with neither a PID file nor a readiness file
answers NEVER_LAUNCHED from the liveness probe. The parser folded that into
UNKNOWN, so every reader treated it as unprovable: the wake never started the
slot, the deploy path reported "process state is unverifiable", and the host
stayed unreachable until someone moved orcad-active.json aside by hand.

A launch creates the readiness file before anything else, so a slot with
neither file provably has nothing running from it; GC already relies on that
to remove such directories. Keep NEVER_LAUNCHED as its own liveness value and
read it as proven exit wherever DEAD is: the wake, ensureOrcadSlotServing,
probeActiveOrcadReadiness, interrupted-candidate resume, decommission
recovery and GC. UNKNOWN stays untouched and still never starts anything.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs(ssh): one-line docstrings for the liveness readers this change touches

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* test(ssh): the shell-probe integration test expects NEVER_LAUNCHED for a slot with no launch artifacts

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-16 01:29:58 -07:00
Neil 50de2bc966 fix(ssh): offer the held-back challenge when a strict MaxAuthTries host drops the key retry (#29541)
When the agent-first attempt skips the host's keyboard-interactive challenge
so the deferred ~/.ssh key can go first, a host with MaxAuthTries=1
disconnects after rejecting that key, so the key retry never reaches the
challenge. Record when an attempt held the challenge back and when an
attempt actually offered it; if the key retry fails with an auth error
without offering it, run one attempt with no agent and no key that offers
only the challenge.

Fixes #29443
2026-10-16 01:25:22 -07:00
Neil 7f8faae800 feat(space): open disk usage in a separate window (#29513)
* feat(space): open disk usage in a separate window

* perf(space): move local disk scan off Electron main thread

* fix(space): satisfy full PR quality gates
2026-10-16 01:25:19 -07:00
Neil c4f1dedad4 fix(orcad): a managed SSH/WSL server falls back when port 6768 is taken; WSL lane skips the MSI on 3.0.1 images (#29522)
* ci(wsl-orcad): skip the WSL MSI when the image already has 3.0.1

windows-2025 image 20261007.264.1 ships WSL 3.0.1.0, and reinstalling the
pinned 3.0.1 MSI over it exits 1603, failing every run. Install only when the
image is older, print the msiexec log on failure, and gate on >= 3.0.1 after.

* fix(orcad): let a managed launch fall back when its default port is taken

#29432 made any --port mandatory, but managed SSH/WSL launches pass the
default 6768 as a preference and read the bound port from readiness. WSL2
distros share one VM loopback, so a second distro's orcad now failed with
pinned_port_unavailable. Only an operator --port is required now.
2026-10-16 01:23:57 -07:00
OrcaWinandOrcaWin 941ad1e2e0 test: retire synthetic runtime constructor probes (#29309)
* test: batch lint fixtures and remove repeated runtime scan

* test(cli): consolidate owner coverage and remove false decoding proof

* test(renderer): retain IPC lifecycle behavior without copied inventories

* test: share floating panel behavior suite startup

* test: retire synthetic runtime constructor probes

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 01:22:08 -07:00
Jinwoo Hong 4d3e3c8b0e feat(layout): send tab rename, color and pin through main behind the layout-owner build switch (#29301)
* feat(layout): add the dark layout.apply channel and route pane splits through main behind ORCA_LAYOUT_OWNER

A build made with ORCA_LAYOUT_OWNER=main registers layout.apply: main applies the
window's layout command to the stored partition through the shared applyLayoutCommand,
minting new ids. A user split then waits for main's answer and mounts the pane id main
minted. Every other build substitutes 'window', so neither branch is compiled in.

* fix(layout): write only the records a layout.apply command touched

A load-then-save rewrite also normalizes records the command never touched. The command's
effect is now the diff between the save before and after it, written onto the stored
partition record by record. A split whose main reply says a paired server holds the tab
splits as today.

* fix(layout): write a load-supplied record whole and check that patched partitions reload to the command's result

* feat(layout): close, rename and equalize panes through main behind ORCA_LAYOUT_OWNER

In a layout-owner build the window's pane close, title change and equalize go through
layout.apply and the window shows main's answer. A window pane close keeps the legacy
close's rules: the tab's last pane is refused, a pane restarted since main read the close is
left alone, every partition holding the tab closes it, and the tab's remote session id follows
the remaining pane. The rules sit behind a command field only layout.apply sets.

* fix(layout): close the tab when a racing pane close leaves the window one pane

* fix(layout): leave an unmounted tab alone when main refuses its last pane

* feat(layout): move panes and save divider ratios through main behind ORCA_LAYOUT_OWNER

Claude-Session: 10569c9a-a0a1-4fc9-8469-0edfb7aed125

* test(layout): a taken pane drop whose pane closed does nothing

Claude-Session: 10569c9a-a0a1-4fc9-8469-0edfb7aed125

* test(layout): pin the window's pane move to main's saved tree, and the drops main cannot take

Claude-Session: 10569c9a-a0a1-4fc9-8469-0edfb7aed125

* fix(layout): close a user's pane even if its terminal restarted, as today

Claude-Session: 10569c9a-a0a1-4fc9-8469-0edfb7aed125

* test(layout): pin the restarted-pane close directly, not through a made-up profile state

Claude-Session: 10569c9a-a0a1-4fc9-8469-0edfb7aed125

* fix(layout): leave a split to today's path only when the workspace's row names a paired server

The split switch point asked which host to route to with a helper that falls back to the focused
server, so a focused server could claim a workspace whose row names no owner. Use the same owner
test the tab mirror uses.

* test(layout): type the split owner mock without a cast

* test(layout): type the layout-owner command mocks with the real signature

* test(layout): type the gesture command mock with the real signature

* fix(layout): close the dark path's gaps: unmounted split panes, refused or failed splits and moves, ratios during a move, release guard

- A pane main saved but the window could not mount (source pane or manager gone during the await)
  is closed again in main, so it does not come back on restart.
- A split main refuses because its copy lacks the workspace, tab or pane, or a failed call, splits
  as today; a refused or failed move moves as today.
- Divider ratios committed while a move is in flight wait for the window's move, then go to main.
- The orcad bundle gets the ORCA_LAYOUT_OWNER define when the switch is on.
- Packaging and the orcad template refuse ORCA_LAYOUT_OWNER=main and any output a dark build marked.
- workspace-layout-record-patch.ts: no non-null assertions; plain comment for the map depth.

* test(layout): count a split pane as mounted from the split mock's own results

* fix(layout): act as today whenever main lacks the target or the call throws, not just for splits

- sendPaneCommandToLayoutOwner runs asToday for workspace/tab/pane_not_found and a thrown call, so
  close, rename and equalize fall back like split and move; a handler that throws no longer runs the
  fallback too.
- A close main refuses as its last pane, while this window still has others, closes as today.
- A move whose local step throws still releases held divider ratios.
- Drop the orcad output marker: nothing read it; the template build refuses the switch itself.

* test(layout): plain names for the last-pane fallback test and the marker comment

* docs(layout): say plainly what an indeterminate write can leave behind

* fix(layout): finish the main merge with this branch's versions of the layout-owner files

* test(build): copy the layout-owner build guard into the compiler-cache checkout fixture

* feat(layout): send tab rename, color and pin through main behind the layout-owner build switch

In an ORCA_LAYOUT_OWNER=main build, the tab bar's rename, color and pin ask main's layout.apply
first; the window then runs today's action. When main lacks the tab or the call fails the
window acts as today; a paired server's workspace keeps today's path. Pinning a tab now also
ends its preview in main's copy, as the tab bar's pin does. Other builds compile the switch out.

* fix(layout): leave a pinned tab's preview mark to the window until main opens files

Changing the shared pin command would change what a paired client's pin does in every build.

* docs(layout): wrap the layout-owner sender's doc comment
2026-10-16 01:21:15 -07:00
Neil 0942535c28 fix(runtime): keep the published agent-status stamp monotonic when a turn's trailing spinner ends (#29538)
The host projected a title-only working row stamped with the spinner frame,
then republished the older Stop-time done once the title went plain, so a
paired client kept the newer working row forever (#28102).
2026-10-16 01:20:22 -07:00
Neil d9823843bc fix(ssh): hidden relay-era SSH panes stop sending every output chunk to the window (#29537)
* fix(ssh): hidden relay-era panes stop sending every output chunk to the window; a reveal re-reads the relay's screen

* fix(ssh): reveal replays at the relay's snapshot boundary and hidden panes still answer terminal queries

* fix(ssh): hidden bridged panes still deliver split queries, OSC marks and bells

* fix(ssh): hidden bridged panes answer cursor queries from a current screen and keep sequences split at visibility changes

* fix(ssh): hidden bridged panes keep kitty, window-size and DCS queries, and reopen an OSC cut at reveal
2026-10-16 01:18:50 -07:00
OrcaWinandOrcaWin 39636115b5 test: remove duplicate Codex denylist executions (#29473)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 01:13:33 -07:00
OrcaWinandOrcaWin 46779ca7c3 test: share floating panel behavior suite startup (#29304)
* test: batch lint fixtures and remove repeated runtime scan

* test(cli): consolidate owner coverage and remove false decoding proof

* test(renderer): retain IPC lifecycle behavior without copied inventories

* test: share floating panel behavior suite startup

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 01:09:01 -07:00
OrcaWinandOrcaWin 3314659c10 refactor(checks): compose review header without loading controller (#29529)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 01:06:13 -07:00
OrcaWinandOrcaWin 20fca451c5 test(serve): wait for supervisor signal readiness (#29527)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 01:01:50 -07:00
OrcaWinandOrcaWin b3dfd54827 perf(build): skip unnecessary work and reclaim Vite caches (#29479)
* perf(build): remove unnecessary development and config work

* feat(dev): reclaim inactive worktree Vite caches

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 00:56:30 -07:00