Commit Graph
14600 Commits
Author SHA1 Message Date
OrcaWinandOrcaWin 40f56eb7bb test: consolidate duplicate terminal redraw scenarios (#29709)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 07:44:40 -07:00
OrcaWinandOrcaWin eada95e960 test: consolidate duplicate terminal theme subscription cleanup (#29708)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 07:40:38 -07:00
Neil 86aa232876 test: advance mocked terminal clocks and share status setup (#29704)
* test: advance mocked terminal restore observation windows

* test: share setup across agent status entry contracts
2026-10-16 07:38:00 -07:00
Jinwoo Hong 44a86bb188 test(orcad): make the retiring-daemon teardown test independent of exit timing (#29702)
The test let a child exit on a 1 s timer and then required kill(pid, 0) to
report ESRCH. On Linux the teardown wait rightly accepts an unreaped zombie,
which kill(pid, 0) still reports as present, so the assertion raced Node's reap.
The child now exits only when told, and the test asserts teardown is still
pending while it lives and resolves once it exits.
2026-10-16 07:24:18 -07:00
Jinwoo Hong 90addf474e Number layout stream updates so a layout command's answer names the update holding it (dark, build switch off by default) (#29696)
* Number layout frames so a layout command's reply names the frame holding its effect (dark, build switch off by default)

* Report every frame's position, test the reply's frame end to end

* Rewrap sendLayoutApply's doc comment
2026-10-16 07:22:01 -07:00
OrcaWinandOrcaWin 5851ecd96d test: exercise plugin startup completing after cancellation (#29699)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 07:17:22 -07:00
Neil 54dc2d609d test: share repository store setup and advance mocked mail clocks (#29698) 2026-10-16 07:16:30 -07:00
OrcaWinandOrcaWin adf26f9ec5 test: share browser catalog startup across allowlist and CDP checks (#29693)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 07:13:34 -07:00
OrcaWinandOrcaWin a3dfb05258 test: share mobile presence and subscription runtime startup (#29694)
* test: share mobile presence and subscription runtime startup

* test: route mobile reliability gate through retained suite

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 07:10:40 -07:00
OrcaWinandOrcaWin e141e13384 test: keep disconnected plugin fixture alive until supervised stop (#29695)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 07:08:22 -07:00
Jinwoo Hong dbc1e18b07 Route the remaining window pane-layout changes through main (dark, build switch off by default) (#29689)
* Route the remaining window pane-tree writers through main (dark, build switch off by default)

* E1b review fixes: valid pane ids, keep a mounted split, automatic closes skip the user mark, sole-pane exit guard
2026-10-16 07:04:34 -07:00
Neil e40f8ec115 test: remove real waits and repeated catalog setup (#29690) 2026-10-16 06:53:02 -07:00
OrcaWinandOrcaWin 7cbbc9585e test: share Linear access suite runtime startup (#29688)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 06:46:04 -07:00
OrcaWinandOrcaWin 1b3d4086e4 test: trim redundant mailbox backlog and check delayed input (#29686)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 06:35:20 -07:00
OrcaWinandOrcaWin bd32573780 test: establish surviving child before checking mutation lock (#29683)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 06:28:52 -07:00
Neil 52a8b87a03 test(accounts): hand over the Claude sign-in link the way the BROWSER stand-in does (#29682)
The fake Claude wrote .orca-sign-in-browser.link directly, so the link
poller could read it between create and write, see an empty link, and end
the sign-in. Write a temp file and rename it into place, as the real
stand-in script does. Flake introduced with the tests in #29566.
2026-10-16 06:26:21 -07:00
Neil 9a47caeaac test: dispose managed SSH profiles as their final app closes (#29671) 2026-10-16 06:22:52 -07:00
OrcaWinandOrcaWin 1459473bdb test: observe all remote input resends after recovery (#29674)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 06:19:46 -07:00
Jinwoo Hong 4a123f300c test(orcad): wait for an idle-retiring daemon before deleting the serve-parity profile (#29669)
* test(orcad): wait for an idle-retiring daemon before deleting the serve-parity profile

A terminal daemon that loses its last client deletes its pid record before it
exits, so teardown that found daemons only through pid records skipped it and
raced its open files (EBUSY on Windows ARM). Record the pid before stopping
orcad and require that process's exit.

* test(orcad): record profile daemons before stopping orcad in launcher and stop-request tests

* test(orcad): wait for the daemon's child processes before deleting its profile on Windows

The terminal daemon runs with the profile as its cwd and its children inherit it,
so a child that outlives the daemon keeps the profile directory busy (EBUSY on
rmdir). Record the daemon's process tree before shutdown and require each
recorded child's exit, naming any survivor at the deadline.

* test(orcad): keep the real Windows process table out of the teardown unit tests
2026-10-16 06:16:27 -07:00
Neil 068cdda282 fix(terminal): a paired pane is created at its real box and fits the same grid from any grid (#29668)
The web client positions a retained pane host from a measured tab-group body,
but the pane mounted (and fit xterm) a render before that measurement, at the
32px placeholder box, then refit when the measurement landed. Mount the pane
only after the first read.

FitAddon also divides by xterm's css cell, which is the rounded canvas width
over the current cols, so the same box proposed 51 cols from a 75-col replay
and 52 from a 52-col pane: a revealed pane resized twice. Fit with the
grid-independent device cell instead.
2026-10-16 06:13:11 -07:00
OrcaWinandOrcaWin 5bad9cbb0e test(terminal): consolidate reattach reset proof and advance its clock (#29673)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 06:09:51 -07:00
Jinwoo HongandClaude 7b7148d0a9 Open into a new split in one layout command (dark, build switch off by default) (#29655)
* Open into a new split in one layout command (dark, build switch off by default)

Main makes the window's new split group and its first tab (terminal, editor
or browser) in one apply, so main never refuses the open for a group it lacks
and never stores an empty group. The window derives the split from its own
group tree in the three existing switch-point recorders.

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

* Open beside an emptied root split, and into a group main already holds

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

* Describe both openInNewGroup fallbacks in its doc comment

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

* Test: no split is read back beside a sibling that is itself split

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-16 06:09:24 -07:00
Neil 222ede7f5b fix(ssh): reopening a workspace-slept agent tab on a managed host resumes it, without widening its permissions (#29672)
* fix(ssh): reopening a tab slept from a paired desktop resumes its agent on the managed host

A paired client's worktree sleep stops the host's PTYs, but the resume
record its renderer writes never reaches the host, and the host is what
answers the tab open. Capture the record on the host from its own hook
store before the stop, applying the shared holder rule (an agent the
hook store proved exited leaves no record).

* fix(ssh): keep the launch recipe and record acknowledged stops when inventory fails

* fix(ssh): only a proven agent exit retires a pane's earlier sleep record

* fix(ssh): stamp the captured record's SSH host and keep a saved launch recipe

* fix(ssh): read the session id after the presence probe that may outlast it

* fix(agents): a resume reuses only its launch's recorded args, never permission-widening defaults

Resuming a session started as a hand-typed `claude` filled the missing
launch recipe from settings defaults, which carry the permission bypass.
Host tab-open resume, window cold restore and worktree wake now share
one rule: the recorded recipe, or none.

* fix(ssh): a WSL relay tag on a captured record is local, not another host

* fix(ssh): a capture retires when the hook store names another agent in the pane
2026-10-16 06:05:08 -07:00
OrcaWinandOrcaWin 3798302197 test(terminal): consolidate visibility proof and repair focus refusals (#29670)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 05:59:18 -07:00
Neil 19cf2e5578 ci: remove duplicate server builds and reuse checked Windows addons (#29614)
* ci: build the WSL server template once

* ci: reuse validated Windows native addons in E2E preparation

* ci: avoid the unused standalone server build in SSH E2E shards
2026-10-16 05:50:43 -07:00
OrcaWinandOrcaWin 183d1426fa test: advance hidden replay settling with a virtual clock (#29667)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 05:45:00 -07:00
OrcaWinandOrcaWin 49721b0595 test: avoid repeated RPC catalog loads for layout schemas (#29663)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 05:42:51 -07:00
Jinwoo Hong 18df97a7bc Refuse a chat create whose close came first (dark, build switch off by default) (#29659)
* Refuse a chat create whose close came first, behind the layout-owner switch

With ORCA_LAYOUT_OWNER=main, main remembers a close that reaches it before
the chat's create and refuses that create, or closes the chat as it lands.
The window then tells this machine's host about a cancel instead of
keeping a cancel tombstone; a host it cannot tell still gets the
tombstone. Paired hosts keep the tombstones, whose fence module moves to
lib/launch-cancel-tombstones-compat/.

* Close a chat whose create a cancel beat, on any create outcome

The local cancel now retires the chat on main (close and host-tab close),
so a create that landed first leaves no tab behind; a tab_not_found answer
means the create had not landed. Main closes the chat for any create
answer once a close was noted, including a refusal or a throw past commit,
and publishes no tab for it. The tombstone fallback notifies listeners.

* Keep the switched-off create path byte-identical

* Log, not throw, a failed close of a chat closed before create

* Run the close-before-create test in the Node SQLite project
2026-10-16 05:41:33 -07:00
Neil 469ae09c97 fix(agents): a resumed agent's chat is readable on the phone before its first new turn (#29664)
* fix(agents): a resumed agent's chat is readable on the phone before its first new turn (#10923)

* fix(agents): skip a dropped Codex resume and keep the seeded identity across restart

* fix(agents): seed resume identity before the spawn's first await and keep it through terminal evidence

* fix(agents): seed after the spawn commits, and name the session on host-built resumes
2026-10-16 05:39:25 -07:00
Neil 6622b8298c fix(terminal): tell panes their daemon died at once and say when typed input was lost (#29660)
* fix(terminal): tell panes their daemon died at once and say when typed input was lost

* fix(terminal): use the info toast the terminal suites already stub
2026-10-16 05:39:07 -07:00
Neil 78f2e9b174 test(terminal): load the host runtime in setup so the alt-screen chain fits its test limit (#29661) 2026-10-16 05:33:31 -07:00
OrcaWinandOrcaWin a93fe5e955 test: advance tour visibility delays with a controlled clock (#29657)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 05:23:28 -07:00
Neil 2252240d42 fix(terminal): preserve paste order across remote recovery (#29635) 2026-10-16 05:22:32 -07:00
NeilandGideon c8ad8ea313 fix(projects): list symlinked folders as folders in the remote Add Project browser (#29658)
A symlink to a directory was listed as a file on SSH and managed hosts, so
projects behind a linked path could not be reached. Follow links when
classifying entries; broken links and loops stay files.

Co-authored-by: Gideon <jjin6573@naver.com>
2026-10-16 05:21:44 -07:00
Neil d3cafe234d test(e2e): stage the WSL inline-image payload in a file (#29633)
* test(e2e): stage the WSL inline-image payload in a file instead of a 25 KB typed line

* ci: run the real WSL lane when its inline-image spec changes
2026-10-16 05:20:59 -07:00
OrcaWinandOrcaWin bf22760392 test: exercise real gate authorization refusals (#29332)
* 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

* test(runtime): skip unused RPC catalog in bind-host coverage

* test: share transcript scroll suite startup

* test: share SSH lease candidacy suite startup

* test: exercise real gate authorization refusals

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 05:19:54 -07:00
Jinwoo Hong ebb9e3243a Record a restored editor tab's move to its owning workspace through main (dark, build switch off by default) (#29653)
* Record a restored editor tab's move to its owning workspace through main (dark, build switch off by default)

* Refuse non-editor and duplicate moves; route the move by workspace

* Type the move routing test's command
2026-10-16 05:17:45 -07:00
Neil 93ca977ca9 fix(runtime): republish session tabs when an adopted terminal's restored title lands (#29654) 2026-10-16 05:16:43 -07:00
Neil 199027d40b fix(notifications): notify for a managed-server task that finished during an SSH disconnect (#29636)
* fix(notifications): notify for a managed-server task that finished during an SSH disconnect

* test: type the reconnect completion dispatch mock
2026-10-16 05:15:58 -07:00
Neil 62bf1d68c3 fix(projects): adding a project through a symlink alias reuses the existing project (#29651)
* fix(projects): adding a project through a symlink alias reuses the existing project

On a managed host, adding repo-link (-> repo) created a second project for the
same checkout while re-adding repo was deduped. Compare the real path, resolved
on the host that owns the files, so an alias finds the tracked project; distinct
checkouts keep distinct real paths and stay separate. Local folder workspaces
get the same check.

* test: run fixture git through process-host
2026-10-16 05:15:32 -07:00
Kelvin Amoaba 942ffe2f9e fix(terminal): right-click pastes once into Codex (#29647) 2026-10-16 12:11:06 +00:00
OrcaWinandOrcaWin 36d449ba67 test: consolidate repeated application rebuild checks (#29628)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 05:10:22 -07:00
OrcaWinandOrcaWin 5db05e8ed4 test: share SSH lease candidacy suite startup (#29329)
* 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

* test(runtime): skip unused RPC catalog in bind-host coverage

* test: share transcript scroll suite startup

* test: share SSH lease candidacy suite startup

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 05:03:12 -07:00
OrcaWinandOrcaWin 9c03c68957 test: reduce RPC authorization suite startup (#29645)
* fix: classify integration credential moves on their owner host

* test: install renderer API fixtures for terminal close paths

* test: restore IPC harness API and listener ownership contracts

* test: avoid unused RPC catalog setup in authorization suite

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 05:01:21 -07:00
Neil e79671b51f test(e2e): skip the WebGL replay-presentation case where WebGL is unavailable (#29649)
Headless Linux CI (xvfb, no GPU) falls back to the DOM renderer, so the
WebGL scenario added in #29331 waited for a canvas that never attaches.
Other WebGL specs already skip the same way.
2026-10-16 04:59:39 -07:00
NeilandClaude e522986211 fix(ssh): load the bridge panes module lazily so importing the SSH state effects has no side effect (#29646)
#29625 statically imported legacy-relay-bridge-panes, which subscribes to the
bridge (and calls listPanes) at load, so every useIpcEvents test whose
window.api mock lacks it threw at import.

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-16 04:53:10 -07:00
OrcaWinandOrcaWin 7b90f57b1a test: repair renderer API fixtures and listener ownership (#29634)
* fix: classify integration credential moves on their owner host

* test: install renderer API fixtures for terminal close paths

* test: restore IPC harness API and listener ownership contracts

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 04:48:41 -07:00
Jinwoo HongandClaude dddad7d66a Record sleep and wake through main (dark, build switch off by default) (#29350)
* 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>

* feat(layout): open editor tabs under the window's id, per split, and promote previews through layout.apply

openEditorTab takes the window's tab id (the same open again is a no-op, a held id is refused),
dedupes per group so a file open in another split gets its own tab, pins an existing preview on a
non-preview open, and places the new tab before closing the replaced preview so a group whose only
tab is its preview keeps its id. layout.apply accepts openEditorTab, promotePreviewTab and a
closeTabs with no terminal close record.

* feat(layout): record the window's editor tab opens, closes and preview promotions in main behind ORCA_LAYOUT_OWNER

The window still draws first (openFile returns at once and its callers act on the tab by id).
Main then records the tab under the window's ids and decides the group fallback and preview
replacement by the same shared rule. Switch points: the one editor tab create, the unified tab
close, preview promotion on activation, edit and make-permanent, and the reopened tab's position.

* 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

* Record sleep and wake through main (dark, build switch off by default)

In a layout-owner build, main records each sleep the window decided and each
wake of the one pane it showed: a workspace sleep or a pane hibernation sends a
'sleep' per tab once the terminals stopped, and a resumed pane sends a 'wake'
naming only itself. The window keeps deciding, stopping terminals and saving
its own records.

* 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): record sleep and wake in every partition holding the tab

Review fix: a tab a legacy relay reattach left in two partitions gets its
sleeping record in both, as a pane close does. The pane hibernation comment
no longer claims a stop on the branch that stops nothing.

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

* fix(layout): review fixes for editor tabs through main

openEditorTab refuses a group main lacks instead of placing the tab in another group, and gives
a workspace with no group (the window keeps its emptied root group; main closes it) the sender's
group id. Tests pin close-all, the emptied root group, the refused open into a fresh split, and
that the window sends an edit-mode file's record exactly as its session save keeps it.

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

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

* test(layout): assert the window drew the tab main refused

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

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-16 04:35:28 -07:00
NeilandClaude Opus 5.5 25d83af9a7 fix(main): classify integrationCredentials RPC ownership (#29638)
#29608 added integrationCredentials.moveKeyToFile without an ownership entry, failing host-operation-ownership.test.ts on main.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 04:35:25 -07:00
Neil 2d2bccf6c4 fix(agents): new-agent shortcut, Explain and direct launches ask the workspace's own host for its agents (#29622)
* fix(agents): new-agent shortcut and direct launches ask the workspace's own host for its agents (#29599)

* fix(agents): probe a paired server's new workspace, not the server's default context

* fix(agents): drop a pending shortcut launch when the workspace's host changed

* refactor(agents): compare the shortcut's detection target through the shared inventory

* fix(agents): keep the disabled-agent preflight and recheck the host before explain launches

* fix(agents): a delayed shortcut launch opens in the pane it was pressed in

* fix(agents): pick the delayed default agent with the settings current when the host answers
2026-10-16 04:24:26 -07:00