Commit Graph
1343 Commits
Author SHA1 Message Date
Jinwoo Hong aff4ee7ac7 feat(sidebar): main produces this host's workspace rows, checked against the window (dark) (#30184)
* feat(sidebar): main produces the local workspace rows, checked against the window (dark)

* fix(sidebar): workspace rows invalidate the listing only on metadata saves; prove it on the real cache

* fix(sidebar): workspace rows merge the listing fresh instead of invalidating the shared cache

* chore(sidebar): workspace rows comments say what the fresh merge reads
2026-10-17 22:10:09 -07:00
Jinwoo Hong bb0f229aa5 test(e2e): wait for git status to show the seeded file before the discard confirmation test acts (#30165) 2026-10-17 20:59:19 -07:00
Jinwoo Hong 2b49a48334 test(e2e): hidden split-pane exit tests end the shell with exit 0 (#30162)
A bare exit returns the shell's last status. Under the e2e profile on macOS,
/etc/zshrc leaves $? at 1, so the pane is kept behind the exited card on
purpose and the layout check never settles.
2026-10-17 20:46:57 -07:00
Jinwoo Hong 3aad2b17b0 feat(sidebar): dark phone feed of the sidebar inputs (sidebarInputs.read) (#30161)
* feat(sidebar): dark phone feed of the sidebar inputs (sidebarInputs.read)

* fix(sidebar): feed review: fresh read on ready, notices kept per revision, one flush owner, closed connections never subscribe

* fix(sidebar): feed skips values JSON cannot hold; a failed read forgets its notice

* fix(sidebar): name the feed batch key by where the batch starts from
2026-10-17 20:46:10 -07:00
Neil 1b3113de8e fix(ssh): a tab closed while a managed host is disconnected stays closed; deflake the shared-home spec (#30146)
* fix(ssh): a tab closed while a managed host is disconnected stays closed after Connect

#30130 made a user's Disconnect mark the host's managed server manually
disconnected, so the desktop now answers its calls itself with
runtime_manually_disconnected. The tab close path read that as the host's
answer and dropped the close instead of holding it for replay, so the tab
came back on reconnect. Treat it as an undelivered close, and route the
Disconnect sources to the managed-orcad Docker lane.

* test(e2e): close the disconnected host's tab the way a user does

The journey called the store's bare closeTab, which sends only terminal.close
and holds nothing; it passed only because the disconnected host used to be
redialed in the background, which #30130 stopped. Click the tab's X instead,
the path that holds and replays an undelivered close.

* test(e2e): the shared-home spec tells a host's own server from a PID that only collides

Each Docker host has its own PID namespace, so the PID host A records in the
login-home slot can belong to an unrelated live process on host B; kill -0
alone then read it as B running from A's slot. Count a recorded PID only when
its process runs from that slot.
2026-10-17 20:23:19 -07:00
Jinwoo Hong d9a61432c8 Main's layout Loader keeps one pane per terminal on restore (dark, layout-owner build only) (#30110)
* fix(layout): main's Loader repairs a terminal bound in two panes of one tab (dark, layout-owner build only)

* fix(layout): a window save stores main's repaired pane tree, so the duplicate-terminal repair survives the save (dark)

* test(layout): the SSH duplicate-terminal case builds an SSH-hosted tab
2026-10-17 16:03:56 -07:00
Jinwoo Hong 9586a3fbb5 feat(sidebar): main serves workspace icons as small data URLs for the phone (dark) (#30046)
* feat(sidebar): main serves workspace icons as small data URLs for the phone, unused until the phone switch

* fix(sidebar): settle review findings in the icons RPC and the manual-redirect port fix

* docs(sidebar): scope the icon fetch-slot bound to a lone read

* fix(sidebar): gate the icons RPC behind the sidebar-inputs switch; prove re-encoding end to end

* fix(sidebar): restore two files the merge reformatted; one pure annotation for the icons params

* fix(sidebar): restore two files the pre-commit formatter rewrote during the merge

* fix(sidebar): icons fetch through their own manual-redirect request; shared desktop HTTP client back to main

* fix(sidebar): settle review findings in the icons manual-redirect request

* fix(sidebar): end a bodyless icon response at once; clearer fetchRepoIcon doc
2026-10-17 15:10:49 -07:00
Brennan Benson 216e3e42a6 fix(native-chat): a Codex chat is Working only while Codex holds the send (#29922)
* fix(native-chat): a Codex chat is Working only while Codex holds the send

Working read 'a send still pending delivery', so any echo or idle signal
that never arrived (a hook-blocked prompt, an answer naming no turn, idle
before a timed-out send was written) kept the chat Working, Stop up, the
queue frozen and /compact refused until the agent exited.

Codex now reports which sends it still holds: unanswered, answered into a
turn that has not ended, or answered into none while a status read after
that answer says the thread runs. Replies and statuses are ordered as they
are read, so a stale status cannot release a newer send. The host reads
that set (plus the short window while it hands a send over) for Working,
publishes a send the child stopped holding as in doubt on every page and
frame so older clients agree, and republishes when the set changes with no
row. The Codex idle latch and its release are removed.

* fix(native-chat): name the handover journal type; reverse without mutating

* test(native-chat): a lost Codex answer while idle is no longer the chat's work; run the held-sends test with the database runtime

* fix(native-chat): bound work updates and own command handovers

* refactor(native-chat): reuse session delivery plumbing

* test(native-chat): allow separate ownership restatements

* test(wire): resolve the release tab predicate after relocation

* test(native-chat): reuse existing promise and empty-batch primitives
2026-10-17 13:14:15 -07:00
Jinwoo Hong b389854b25 feat(sidebar): ui.setCollapsed changes one section's collapse without undoing another device (#30044)
* feat(sidebar): ui.setCollapsed changes one section's collapse, ordered per writer

* fix(sidebar): ui.setCollapsed accepts ui.set's callers; require a fresh writer per counter

* feat(sidebar): register ui.setCollapsed only with ORCA_SIDEBAR_INPUTS=main

* test(sidebar): hidden-app check of ui.setCollapsed in both switch builds

* test(sidebar): off-census covers every gated method; e2e skips before launching

* test(sidebar): type the gated method-name set as strings

* test(sidebar): type the collapse test's dispatch context
2026-10-17 12:56:37 -07:00
Jinwoo Hong 4b1eabd12e fix(terminal): resume a relaunched workspace's sleeping agents only when shown (#29459)
* fix(terminal): resume a relaunched workspace's sleeping agents only when shown

After a relaunch every terminal tab of the opened workspace mounts, and each
pane's connect resumed its agent from the saved sleeping record whether or
not the pane was visible, so all of them restarted at once.

A hidden pane with a sleeping record now arms the same reveal wake a
hibernated pane uses and spawns nothing. A hidden local reattach first asks
the host whether the session is still alive; only an authoritative "exited"
holds it, and the reveal re-runs the same reattach. Held panes count as
owning their record so the activation sweep does not relaunch them. Targeted
background mounts (phone, CLI, orchestration) still start their tabs'
agents immediately, and the phone wake still wakes held panes.

* fix(terminal): keep a held resume through an exit its wake did not start
2026-10-17 12:52:25 -07:00
Jinwoo Hong cd29f5f3c2 feat(sidebar): main keeps a registry of workspace creations in progress, checked against the window in dev and test (#30021)
* feat(sidebar): main keeps a registry of workspace creations in progress, checked against the window in dev and test

* fix(sidebar): open the runtime creation entry after the create's own repo resolve

* refactor(sidebar): one creation handle opened after the create's repo lookup; move create startup resolution to its own module

* feat(sidebar): put the creation registry behind the ORCA_SIDEBAR_INPUTS dark build switch

* test(sidebar): cover the creation registry with the switch off and the gated creation id
2026-10-17 12:43:12 -07:00
Jinwoo Hong 6fcc183ab9 feat(sidebar): put main's sidebar inputs behind the ORCA_SIDEBAR_INPUTS dark build switch (#30050) 2026-10-17 04:06:43 -07:00
Jinwoo HongandClaude 345ef81bfa feat(accounts): offer to restart running Claude sessions on the new account after a switch (#29898)
* refactor(terminal): let account-switch pane restarts name their agent

The queued account-switch restart only knew how to relaunch Codex. The
queue now records which agent each pane restarts as, and the resume
startup builder takes that agent, so the same mounted and detached
restart paths can move Claude sessions too. Codex behaviour is unchanged.

* feat(accounts): offer to move running Claude sessions after an account switch

Switching the selected Claude account only reached Claudes started later,
so users had to /exit and resume every running session by hand. After a
switch from the status bar or Settings, Orca now finds local terminal
panes running a resumable Claude session in the switched lane and shows
one toast offering to move them. Confirming restarts idle sessions with
claude --resume <id> in place; sessions mid-reply move when their turn
ends, and are dropped if the pane closes or the user switches again.

* fix(accounts): wait out permission prompts and keep hand-started Claude args

A Claude session at a permission prompt is mid-turn, so a move now waits
for it like a session that is replying. Resuming a Claude pane with no
recorded launch config no longer adds the user's default agent arguments
or environment, so a hand-started claude is not resumed with a
permission bypass. Codex keeps its existing fallback.

* feat(accounts): track which Claude account each terminal pane runs on

Orca had no record of the account a running Claude used, so an account
switch could only assume every session was on the old one. A renderer
tracker now attributes sessions that start after launch to their lane's
selected account and records the account Orca restarts a session on.
Sessions it cannot attribute stay unknown and keep today's behaviour.

* feat(accounts): ask in a dialog before restarting Claude sessions on a switch

Replaces the move toast. After a Claude account switch, a dialog names the
new account and how many sessions are still on the old one, with Keep as
is and Restart, plus Remember my choice. Closing or Escape keeps sessions.
The remembered choice lives in Settings > Accounts as When you switch
accounts while Claude is running: Ask, Always restart, Never restart.

* refactor(accounts): read Claude session accounts from their transcripts and use one restart queue

Which account a running Claude uses now comes from the transcript path its
hooks already report (<CLAUDE_CONFIG_DIR>/projects/...), so the renderer
tracker and its guesses are gone and unknown sessions are never counted.
Restarts queue straight into the store's pending map through one
queuePaneAccountRestarts action; the pane effect and the detached
scheduler hold a Claude restart while its turn runs and skip it when the
session can no longer be resumed. Codex behaviour is unchanged.

* style(accounts): left-align Keep as is in the Claude account switch dialog

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

* copy(accounts): say busy rather than replying, and drop the menu's switching note

The deferred restart waits on any working or blocked turn, not only a reply. The
switch dialog now covers running sessions, so the menu footer note is redundant.

* copy(accounts): say busy sessions wait for idle before restarting

* test(accounts): type the switch-session store stub without broad object

* fix(accounts): keep a queued Claude restart when Codex restart notices are cleared

Codex notice cleanup shares the pending-restart map with Claude switch restarts;
it now drops only Codex entries.

* fix(accounts): wait out Claude questions and keep accepted restarts across switches

- A Claude permission prompt or question reports 'waiting'; a queued restart now
  waits for 'done' instead of only 'working'/'blocked', so it no longer drops them.
- A later switch keeps accepted restarts still waiting on a turn (they relaunch on
  whatever is selected) and drops only those whose session is already on the new
  account, scoped to the switch's lane. The blanket replaceQueued option is gone.
- A server account switch returns before touching the local dialog or queue.
- Pane restart state reads through one selector to stay inside the subscription
  budget, and the focus-read baseline follows the restart-startup rename.

* test(accounts): feed the account-restart e2e fixture the shared restart queue

* feat(accounts): make the switch dialog's checkbox one-way, like native chat's resume prompt

"Don't ask again (restart automatically)" turns on automatic restarts however the
dialog is left, including Escape; Settings → AI Provider Accounts turns it off.

* feat(accounts): choose which Claude sessions restart after an account switch

With more than one session, the switch dialog lists them by workspace using the
native-chat resume tree rows, all ticked; Restart covers only the ticked ones.

* Merge origin/main into claude-sign-in and rename the host-twin teardown's restart queue

* fix(accounts): localize the session tree's agent label

* fix(accounts): restart a pane on the PTY it has when the dialog is answered

A reattach can rebind a pane while the dialog is open and a closed pane has no
PTY, so the ids it listed may name nothing.

* fix(accounts): read a layout's pane PTYs optionally

* fix(accounts): offer to move sessions of a saved account that runs on System default

A saved account with no login of its own runs on System default, so its sessions'
transcripts read as System default. The switch now compares where launches run
(runsOnSystemDefault on the account summary) and asks nothing when that is unchanged.

* refactor(accounts): give the Claude account switch one boundary and key the whole prompt

The post-switch coordinator now takes the before/after account snapshots and
derives launch folders and labels itself, so the status bar and Settings stop
assembling the same request. The status bar's settings projection reuses the
host's row, which keeps runsOnSystemDefault: a covered account switched from
the status bar now finds its System default sessions. Never restart returns
before any session scan. The outcome collapses to show-confirmation | handled.
The dialog keys one component that owns the whole Dialog with a plain boolean.

* refactor(terminal): subscribe mounted panes to this tab's ready account restarts

Replaces claudeTurnStatus, the whole agent-status map passed through the
controller as a re-run signal, with a shallow selector of the PTY ids whose
queued restart can run now. Other tabs' status updates no longer re-render or
re-run every mounted pane once a Claude restart is queued. The effect re-checks
readiness against the current store before consuming. The detached Claude test
now runs through the scheduler's real subscription instead of manual sweeps.

* docs(accounts): shorten Claude account-move comments to their whys

* test(terminal): give the account-restart e2e a callable store and a queued restart

The mounted pane now reads its ready restarts from the store through useShallow.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-17 02:11:10 -07:00
Jinwoo HongandClaude e6b7c77e1a feat(sidebar): main produces per-workspace PR facts, checked against the window in dev and test (#30026)
* feat(sidebar): main produces per-workspace PR facts, checked against the window in dev and test

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

* refactor(sidebar): share the PR cache key candidates instead of splitting an import

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-17 01:27:27 -07:00
NeilandClaude 0ba5cccf9d fix(mobile): keep a headless host's chat tab through snapshot rebuilds (#30028)
On a host with no window, chat tabs live only in the runtime's session snapshot. A forced rebuild from the saved session (closing a saved editor tab, an expired SSH reattach) dropped them, and every terminal-only group merge removed them from the tab order.

Refs #29968

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-17 01:23:10 -07:00
NeilandClaude 7adcefb078 fix(ai-vault): hide Orca's chat-naming requests from Session History (#30029)
Naming a chat runs a one-shot agent CLI request in the chat's folder, and the CLI saves it beside the user's chats. Session History listed it, and opening it from a phone resumed the naming request instead of the chat.

Fixes #29973

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-17 01:22:15 -07:00
Jinwoo Hong 03cefcb84c feat(sidebar): main keeps one live set of paired-server rows, checked against the window in dev and test (#30027)
* feat(sidebar): main keeps one live set of paired-server rows, checked against the window in dev and test

* fix(sidebar): settle review findings; main also publishes paired-server host facts
2026-10-17 01:13:34 -07:00
Jinwoo Hong 6c7ed18e20 feat(sidebar): main publishes desktop focus, pins, project and host order, and SSH/WSL host state, checked against the window in dev and test (#30018)
* feat(sidebar): main publishes desktop focus, pins, project and host order, and SSH/WSL host state, checked against the window in dev and test

* fix(sidebar): read pins through the host-filtered metadata helper; name pins as workspaces
2026-10-17 00:51:57 -07:00
Jinwoo Hong 95580d9dd8 test(e2e): open and close structured chat tabs with an isolated Claude stand-in (#30011)
* test(e2e): open and close structured chat tabs through an isolated Claude stub

* test(e2e): satisfy changed-code lint in the structured chat stub
2026-10-17 00:25:36 -07:00
Brennan Benson 035588e914 test(cross-version): read isStructuredTab from the shared module the newest release defines it in (#30000) 2026-10-17 00:11:43 -07:00
Brennan Benson 58f1f7de1e fix(mobile): edit queued messages in place (#28646)
* fix(mobile): edit queued messages in place

* fix(mobile): use the platform input font size for queued edits

* fix(mobile): handle missing host support while probing queued edits

* Keep phone queued edits owned through save settlement

* Keep phone queued edits local to mounted chat

* fix(mobile): retire queued editor when its card disappears

* fix(mobile): retain queued edits while reconnecting

* test(mobile): await reconnect timer inside act callback

* fix(mobile): publish queued edit transport after commit

* test(mobile): await queued Edit inside act callbacks

* fix(mobile): hand a stale queued Save to the composer and reopen on the newer text

* fix(mobile): close an unchanged queued Save locally and keep stale typing in its own chat

* fix(mobile): explain disconnected queued edit refusal

* fix(mobile): combine queued session contract imports
2026-10-17 00:06:07 -07:00
Jinjing 05086a892e Let Cmd+J open hosting-provider domains such as github.io (#29989)
Typed hosts like github.io, vercel.app, or readthedocs.io were treated as bare public suffixes and sent to search. They are registrable domains, so they now navigate directly.

- Suffix check now uses ICANN-only rules. The private-section list made `foo.github.io` a domain, but it also let the bare suffix pass, so the classifier now treats the hosting-provider suffix itself as a navigable domain.
- Website navigation now outranks a name match only when the query equals a worktree, tab, or page name in full. Partial matches such as "project.dev server" no longer block the "Go to" row.
- Browser tab creation from a URL forwards the target group as `clientTargetGroupId`, so older hosts that publish the page before the create response still place the tab in the invoking split.
2026-10-16 23:46:30 -07:00
Jinwoo Hong 77c511b316 feat(sidebar): main produces per-workspace activity facts, checked against the window in dev and test (#29980)
* feat(sidebar): main produces per-workspace activity facts in shadow mode

* perf(sidebar): agent pings keep last-read surfaces; shadow counts comparisons

* fix(sidebar): settle review findings in the activity-facts producer and shadow check

* fix(sidebar): refresh on inventory verdict clears; resync agents only when tabs move

* fix(sidebar): scope the shadow comparison by each row's owner, not the focused host

* refactor(sidebar): name the shadow scope after what it keeps

* fix(sidebar): classify sidebarInputs as host-owned in the operation ownership census
2026-10-16 23:40:35 -07:00
Neil 76fc1e5acd fix(web): pair and stay paired from plain-http LAN and Tailscale pages again (#29984)
Partially reverts #27540 and the plain-http part of #27552, which broke web
pairing on upgrade for 1.4.227 users who open Orca at a LAN or Tailscale address:

- The host no longer refuses a first pairing from a plain-http page on another
  machine (insecure_origin, ORCA_ALLOW_INSECURE_WEB_PAIRING).
- Such a page keeps its pairing code in local storage and signs in with it, as
  in 1.4.227, so reloads, new tabs and bookmarks stay paired; no notice.
- Session-only browser keys (pairing.device-key-ephemeral.v1, the idle sweep)
  stay for browsers without Ed25519.
- A web client whose credentials are refused shows the host's reason instead
  of an empty workspace and "Session restore failed".
2026-10-16 22:50:27 -07:00
Brennan Benson dd3bbf680e Catch up desktop chats from the newest page (#29125)
* fix(native-chat): retire acknowledged send echoes after catch-up

* test: follow phone lint rules in reconnect regression

* test: format reconnect message expectation

* Keep current chat requests independent of loaded history

* Read current chat requests in bounded cursor pieces

* Bound desktop catch-up after independent request support

* Fix current request subscription static checks

* Match generated request schema import ordering

* fix(native-chat): correct current request type boundaries

* Accept readonly client capability fixtures

* Exercise current request reads in wire compatibility inventory

* Align current request fixtures with provider commit and RPC surface

* test(native-chat): include current request browser capability

* Keep the mobile chat session hook within its line budget

* Format mobile current request readers

* fix(native-chat): reopen once for a current-request version whose read keeps failing

A deterministic read failure reopened the subscription, whose first frame re-read the same version and reset the backoff, so the pane resubscribed every 750 ms forever.

* test(native-chat): type the current-request snapshot fixture

* test(native-chat): wait for the hydrated open before driving the subscription
2026-10-16 17:46:54 -07:00
Jinwoo Hong 3615d0423b Layout-owner follow-ups: closed waiting splits, paired-server tabs by host, first-tab e2e wait (dark) (#29866)
* fix(layout): E1 follow-ups: closed waiting splits, paired-server tabs by host, first-tab e2e wait

- A pane main closes before its tab mounts drops that tab's waiting split for it.
- Mounted tabs skip main's pane tree for paired-server workspaces by host kind, as frames do.
- ensureTerminalVisible waits for the activation tab before creating one.
- Main-asked splits write their pane through admitRuntimePane; startInAdmittedPane loses its single-caller `shown` option.

* refactor(layout): paired-server check in its own module, out of the frame sync
2026-10-16 16:22:42 -07:00
Neil dd70294f0c fix(ssh): turn a host's orca CLI control on by default and stop resetting saved choices (#29856)
* fix(ssh): allow a host's orca CLI to control Orca by default, and stop resetting saved choices

An absent allowRemoteCliControl now means on; only an explicit false turns the
desktop browser bridge and relay-era orchestration commands off. Removes the
one-time reset of saved true values, the consent stamp writes and the reset
notice, which would have silently turned off hosts upgraded from stable.

* fix(ssh): keep the CLI control choice when adding a host from the sidebar

* fix(ssh): read an older client's omitted CLI control switch as off over RPC

* fix(ssh): check the managed fence before routing settings in browser bridge candidates
2026-10-16 16:08:37 -07:00
Brennan Benson 8c1ade9e44 Keep pending chat decisions available outside loaded history (#29121)
* fix(native-chat): retire acknowledged send echoes after catch-up

* test: follow phone lint rules in reconnect regression

* test: format reconnect message expectation

* Keep current chat requests independent of loaded history

* Read current chat requests in bounded cursor pieces

* Fix current request subscription static checks

* Match generated request schema import ordering

* fix(native-chat): correct current request type boundaries

* Exercise current request reads in wire compatibility inventory

* Align current request fixtures with provider commit and RPC surface

* test(native-chat): include current request browser capability

* Keep the mobile chat session hook within its line budget

* Format mobile current request readers

* fix(native-chat): reopen once for a current-request version whose read keeps failing

A deterministic read failure reopened the subscription, whose first frame re-read the same version and reset the backoff, so the pane resubscribed every 750 ms forever.

* test(native-chat): type the current-request snapshot fixture

* test(native-chat): wait for the hydrated open before driving the subscription
2026-10-16 16:01:58 -07:00
Jinjing c31712f1a0 fix(tabs): remove close-button tooltip (#29851) 2026-10-16 15:50:34 -07:00
Kelvin Amoaba fe41a9a5e8 fix(clipboard): paste CleanShot JPEG screenshots stored under the macOS PNG type (#29685) 2026-10-16 21:44:15 +00:00
Jinjing 005f06bbc7 Run automated workspace setup in a dedicated Setup tab (#29819)
* Run automated workspace setup in a dedicated tab

* Preserve native-chat setup route coverage after placement retirement

* Preserve Setup tab design and independent review evidence

* Classify activation test fixtures consistently for routing checks

* Sync runtime English catalog after removing setup preferences

* Update listener savings model after retiring setup action
2026-10-16 14:05:50 -07:00
Neil 95d41afec2 test(e2e): tolerate startup evaluate and daemon pid-file teardown races (#29831) 2026-10-16 13:17:59 -07:00
Jinjing bb7e74d236 fix(e2e): keep dedicated specs out of general CI shard plan (#28161)
- Specs with their own CI jobs were also being assigned to general E2E shards, so they could run twice or in the wrong job.
- planE2e now drops dedicated specs before balancing and fails if no general specs remain, instead of producing an empty plan.
- The mobile subscribe spec builds a paired runtime connection from the pairing offer before sending requests, matching the updated remote runtime helper signatures.
2026-10-16 12:55:32 -07:00
Brennan Benson b3048a2b9c Wait for agent readiness without blocking native chat (#27925)
* Finish structured agent readiness before delivering held work

* Adapt permission fixtures to startup lifecycle

* Keep model discovery for chats before their first start

* Use one host readiness promise for provider operations

* Await provider opening in the execution host

* Await Claude initialization in host-owned open

* Observe Claude readiness through the host status

* Keep optional readback behind host readiness

* Recheck launch permission after host readiness

* Preserve the awaited child during permission revalidation

* Record failed owned opening before the first message

* Abort a matching provider open when its child exits

* Cover provider exit during an unanswered host open

* Cover explicit failure facts on a host-stopped child

* Keep startup waits cancellable and preserve operation order

* Keep live choices and delivery order while agents start

* Apply startup picks and let parked messages release operations [skip ci]

* Save a waiting startup pick after Stop ends its opening [skip ci]

* Save choices when startup ends or a replacement is still opening

* Check saved choices separately from Claude startup reports

* Align startup fixtures and preserve observed Claude exits

* Order startup picks before later messages and retain flow regressions

* Keep reviewed lifecycle contracts while pruning duplicate tests

* Save picks after a proven exit without requiring a child

* Type the startup reply fixture against the Claude control contract

* Honor the before-input callback in the startup reply fixture

* Keep startup option menus independent and show the saved choice

* Exercise startup picks across real menus and the runtime

* Keep saved effort visible when picking a model during startup

* Include the running-turn scope in repeated Stop fixture

* Use the current attach contract in import fixtures

* Align carried-message fixture with startup event contract

* Keep launch-only permission picks usable while prior writes wait

* ci: rerun on main with the locale fix

* Preserve goal retries and chat launch selections

* Give launch regression its request identity

* test(native-chat): type the provisional-launch hook's session prop
2026-10-16 12:44:35 -07:00
Jinjing 922014afcb Let Cmd+J open typed websites in a new browser tab (#29050)
* Add website navigation to the Cmd+J palette

Typing a URL or host such as brex.com or localhost:3000 in Cmd+J now
offers a "Go to <url>" row that opens the site in a new browser tab in
the invoking group. Previously the query only went to search, and the
new tab always opened the default page.

- Classify input with the existing tab-create URL classifiers. Blocked
  schemes such as javascript: and file:, oversized queries, and plain
  words stay on the normal search path.
- Pass an optional URL through openNewBrowserTabInActiveWorkspace. A
  requested URL skips address-bar focus so the page can load directly.
- Rank the website row first unless an exact entity match or an
  issue/PR URL should lead. Query-bound actions carry sourceQuery and
  are ignored on select if the live input has changed, so a stale row
  cannot open the wrong site.

* Open typed websites from Cmd+J in a browser tab

Cmd+J now opens a typed site such as brex.com or localhost:3000 in a new
browser tab. Bare dotted names only count as sites when the suffix is a
listed domain, so file names like App.vue or Cargo.lock still resolve as
files. Browser open failures show a toast instead of an unhandled rejection.

* Fix Cmd+J website action availability
2026-10-16 09:29:22 -07:00
OrcaWinandOrcaWin fea129713d test: narrow remote input model handler registration (#29747)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 09:23:33 -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
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 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
Kelvin Amoaba 942ffe2f9e fix(terminal): right-click pastes once into Codex (#29647) 2026-10-16 12:11:06 +00: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
Neil e6d871c5e7 test(e2e): read Space rows from the separate Space window (#29627)
Space opens in its own window since #29513, so the full-suite spec waited on
the main window for checkboxes that now render in space.html.
2026-10-16 04:23:17 -07:00
NeilandClaude 52554b303f fix(ssh): keep desktop 2 connected with its live relay terminal when desktop 1 already moved the host (STA-10604) (#29625)
* fix(ssh): keep a host connected for its bridged relay terminals when another desktop already moved their project (STA-10604)

Desktop 2's move onto the server desktop 1 already runs refused to link a
project its own relay-era terminal still runs in, and the connect then failed
outright: this version has no relay to fall back to. The decision now keeps
that host connected and unmoved, starts the legacy relay bridge, and the old
tab reattaches its shell through it. The SSH host card names the terminals and
how to clear them; the next connect after they exit links the project.

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

* fix(ssh): release a bridged ssh: row pane's claim on detach too

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

* fix(ssh): admit the bridged mark in the renderer, and remount bridged tabs even when the connect reply lands first

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

* fix(ssh): keep the unverifiable line for a bridged host whose terminal can't be confirmed

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

* fix(ssh): keep the linked-project terminal guidance neutral; only the live bridged line reassures

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-16 04:21:24 -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
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 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 98457f6334 test: frame inline Kitty RGB uploads within protocol limits (#29519)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 00:54:02 -07:00
Jinjing e5b7c564a5 Make failed check details readable and easy to retry (#28702)
* Bound and sanitize CI failure excerpts with linear ANSI stripping

* Fix excerpt regression checks and reduce bounded marker overhead

* Require signal proof for benchmark timeouts and load consumer fixtures portably

* Validate benchmark timeout framing and run required cases with a pinned CI baseline

* Strip dense generic ANSI escapes with bounded forward scanning

* Use the standard UTF8 encoder for byte-cap test oracles

* Gate CI log performance suites behind a dedicated job

The wall-clock performance suites run about 1k child workloads up to 63 MiB, so they were sharing runners with unit tests and could fail on noise. They now run only in their own `check_log_performance` job, opted in with `ORCA_CHECK_LOG_PERF=1`.

- Remove the pinned-baseline checkout and `ORCA_CHECK_LOG_BASELINE_DIR`. The baseline comparison is now a manual step that reads the pinned ref from local Git history.
- Run the current-implementation checks with `compareBaseline: false`, which skips baseline builds and audits.

* Inline check-log fixture and drop dedicated perf CI job

- Replace the captured failure-log JSON with a synthetic log built by `createCheckLogFixture()`, so no scraped job output or provenance metadata is kept in the repo.
- Remove the `check_log_performance` CI job. The log performance suites now run only when `ORCA_CHECK_LOG_PERF=1` is set, as a manual benchmark.
- Update the benchmark scripts and tests to use the new fixture helper and drop the `fixturePath` parameter.

* feat(checks): add optional job log outcome

* fix(checks): preserve host capture lifetimes and safe outcomes

* fix(checks): retrieve and retry bounded failed-job logs

* test(checks): cover queued snapshots and captured error safety

* test(checks): verify sanitized host excerpts and paired failures

* test(checks): identify measurements and preserve paired cleanup

* Keep check details load failures safe and localized

* Describe failed check logs as bounded excerpt context

* Normalize check log excerpts once at renderer ingress

* fix(checks): prioritize failure excerpts and retain reading position

* fix(checks): show truthful log outcomes and explicit refresh guidance

* fix(checks): fit failure context in narrow panes and skip generic headings

* fix(checks): prioritize captured failure diagnostics over inline loggers

* fix(checks): stop stack association at a new diagnostic

* feat(checks): add optional job log outcome

* fix(checks): preserve host capture lifetimes and safe outcomes

* fix(checks): retrieve and retry bounded failed-job logs

* test(checks): cover queued snapshots and captured error safety

* test(checks): verify sanitized host excerpts and paired failures

* test(checks): identify measurements and preserve paired cleanup

* Use the generated check-log fixture in host retrieval tests

* Keep check details load failures safe and localized

* Describe failed check logs as bounded excerpt context

* Normalize check log excerpts once at renderer ingress

* Repair ingestion test fixture and benchmark names after dependency merge

* fix(checks): prioritize failure excerpts and retain reading position

* Use the replacement generated fixture for check-details presentation tests

* fix(checks): show truthful log outcomes and explicit refresh guidance

* fix(checks): fit failure context in narrow panes and skip generic headings

* fix(checks): prioritize captured failure diagnostics over inline loggers

* fix(checks): stop stack association at a new diagnostic

* ci: rerun UI checks after restack

* fix(checks): classify sidebar job failures consistently
2026-10-16 00:53:34 -07:00
Neil db22421ae7 fix(ssh): agents on a managed SSH host can drive the desktop Orca browser again, behind the per-host switch (#29384)
* fix(ssh): an opted-in desktop serves its browser to a managed SSH host's orca CLI again

* fix(ssh): scope bridged pages through the renderer, render them as desktop pages, and route the e2e

* fix(ssh): bridge refuses file URLs and clipboard reads, revokes on disconnect, closes desktop tabs

* fix(ssh): judge bridged paste chords as the page sees them; accept long workspace ids

* fix(ssh): bridged clipboard denial follows popups; revoked commands never leave the browser queue

* fix(ssh): refuse option-like host values bound for agent-browser argv; report undeliverable results

* fix(ssh): bound bridged error results and fall back when the host refuses one

* fix(ssh): bridge only routed host tabs, and bound bridged page scripts by a deadline and revocation

* fix(ssh): cap waiting bridged commands below the desktop socket's result capacity

* fix(ssh): bridge revokes on routing changes, checks each page's route at run time, and cancels host-driven downloads

* fix(ssh): name the bridge registry's owner type

* fix(ssh): bridge refuses pages showing a local document, and never starts a command past orcad's deadline

* fix(ssh): bridged commands may leave Chromium error pages, and stop starting before orcad's deadline

* fix(ssh): ask for a fresh opt-in to host CLI control saved before it drove the desktop browser

* test(ssh): type the bridge registry deadline test
2026-10-15 23:40:57 -07:00