Commit Graph
13441 Commits
Author SHA1 Message Date
OrcaWinandOrcaWin e11b8ac37e test: remove 49 low-value cases and four suites (#34407)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 05:25:04 -07:00
Neil b35fb1ccfb fix(orchestration): route dispatched workers to the skill and stop heartbeat loops before worker_done (#34404)
The orchestration skill description only advertised coordinator work, so a
dispatched worker never loaded it and built its heartbeat loop from the
preamble alone. Neither the preamble nor the guide said to stop a background
heartbeat loop before worker_done, so the loop outlived the task.

Add worker-role triggers (heartbeats, ask, worker_done) to the description and
stub, and tell workers in the preamble and guide to restart an expired
heartbeat loop mid-task and stop it before worker_done.

Fixes #26605
2026-10-27 05:12:22 -07:00
Seiji KoharaandNeil 9b0170cbfa fix(i18n): localize hosted review creation errors (#33368)
Main now tags each Orca-authored PR/MR create failure with a reason code
(the English error is unchanged for mobile, older clients and logs), and
the renderer maps the reason to translated copy in the Source Control
notice, the Checks panel and the pre-create blocked notice. Sign-in steps
are single-sourced across providers.

Fixes #33321

Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
2026-10-27 05:02:01 -07:00
OrcaWinandOrcaWin 0f76063ce6 test: remove 70 low-value cases and four suites (#34400)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 04:58:01 -07:00
70d81598b0 fix(i18n): localize sidebar copy and correct Japanese mistranslations (#28921)
Route hardcoded sidebar strings (cache timer, delete-worktree dialog,
imported-worktrees line, remote file browser, setup-script prompt, card
agents/ports/status, add-repo busy labels, batch action menus) through
i18n keys, and fix literal-sense Japanese translations in ja.json.

Co-authored-by: Koji Miyazawa <24467062+kojikojikojikoji@users.noreply.github.com>
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
2026-10-27 04:56:46 -07:00
Takuya AkiyaandNeil 176852ad5a fix(terminal): highlight the active IME conversion range (#27903)
Japanese IMEs convert one clause at a time, but the terminal's preedit overlay
painted the whole composition uniformly, so the clause the candidate window
targets was invisible. Read the IME's selection from xterm's textarea on the
insertCompositionText input event (Chromium only updates it there) and paint
that range of the preedit in the theme's selection colors. Cell-grid advance
corrections are unchanged and nothing reaches the PTY; a collapsed caret or a
range outside the preedit highlights nothing.

Fixes #27873

Co-authored-by: Neil <neil@stably.ai>
2026-10-27 04:51:06 -07:00
Neilandkambarakun d69d16a3fa fix(agent-dashboard): restore focus to the opener when the drawer closes (#34398)
The store-driven Agents drawer has no Radix trigger, so dismissing it with
Escape or the close button dropped focus to document.body. Capture the
focused element on each open transition and return focus to it on close,
unless focus already moved elsewhere or the close hands focus off (outside
pointer dismissal, agent reveal, switching to the pop-out).

Co-authored-by: kambarakun <kambarakun@gmail.com>
2026-10-27 04:39:50 -07:00
OrcaWinandOrcaWin 0e871e8108 test: remove18 low-value settings cases and an auth-warning suite (#34394)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 04:36:17 -07:00
Neil bd88b2acea fix(orchestration): resolve worker-start new-child/new-top-level targets without requiring a managed caller worktree (#34388)
`orca worker start --worktree new-top-level --repo <selector>` no longer
requires the dispatching terminal to sit inside a managed git worktree; the
explicit repo is all a top-level worktree needs. new-child (and
new-top-level without --repo) still need a caller worktree, and now fail
with an actionable invalid_argument error before any effects are recorded
instead of a bare selector_not_found.

Fixes #22345
2026-10-27 04:28:58 -07:00
OrcaWinandOrcaWin ffed50d6d3 test: remove 48 low-value presentation cases and four suites (#34386)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 04:14:14 -07:00
Neil 295ed991dd refactor: group shared native-chat session options (#34356) 2026-10-27 04:14:07 -07:00
Neil 9f5c32b0d1 fix(kiro): manage status hooks in agent configs kiro-cli agent upgrade rewrote (#34385)
kiro-cli agent upgrade (and Kiro CLI 3.0) turns an agent's hooks into a
list of {name, trigger, matcher, action, timeout}. Orca rejected that shape,
so status reported an error and on/off left the files untouched. Orca now
refreshes its list entries in place, appends missing ones, removes only its
own on off, and writes the list form into upgraded agents that have no hooks
yet so they stay in the universal format. The remote installer shares the
same path.

Fixes #34194
2026-10-27 04:08:12 -07:00
Neil c2b4819ec0 fix(wsl): re-read a settled exit only from a probe started after the window (#34374)
* fix(wsl): start no running-distro read inside the stop settle window

settledStartedAfter slept with one setTimeout until the settle anchor. Node truncates timer
delays to whole ms against a ms loop clock, so the wake can land up to ~2ms before the anchor
by performance.now(), and the probe then started inside the window and could still see the
stopping distro as running. That is the hook relay stop-settle flake ("expected true to be
false"). Sleep until performance.now() has passed the anchor.

* test(wsl): spy on setTimeout without a type assertion

* test(wsl): fire the spied timer far early so a single sleep always fails

* fix(wsl): re-read a settled exit only from a probe started after the window

After a watch or holder exit, the liveness supervisor slept EXIT_SETTLE_MS and re-read the
running list with no bound, so it could join a list probe that started inside the settle
window and still listed the stopping distro. The re-read now passes the exit time, and the
wiring reads through the gate's settledStartedAfter with exit + EXIT_SETTLE_MS as the bound.
2026-10-27 03:55:25 -07:00
Seiji KoharaandNeil 2327180d12 feat(quit): add Quit and Stop All Sessions to the app menu and tray (#32153)
* feat(quit): add Quit and Stop All Sessions to the app menu and tray

Quit keeps daemon sessions alive for warm reattach. The new item, placed
directly above Quit in the macOS app menu and menu bar icon, the Windows
File menu and tray, and the Linux File menu, asks for confirmation, runs
Settings' Kill all sessions in the renderer, and quits only when every
session stopped. Closing the tabs first means nothing reopens or resumes
on the next launch. Serve hosts do not offer the item.

* fix(quit): keep Orca open when Kill all cannot prove every session stopped

- Kill all no longer reads a daemon generation that failed to list as
  "no sessions": a failed poll keeps the last confirmed remaining set,
  and a failed initial listing sets listingIncomplete.
- Quit and Stop All Sessions stays open on an incomplete listing or a
  terminal tab opened during the sweep, logs why it stayed open, and
  reveals the window before the final quit.
- Share the main-window message box helper, stub the request on the web
  client, and add Portuguese strings.
- Cover the windowless path, request expiry, the in-flight guard, and
  failed listings in tests; bound the E2E exit wait.

* fix(terminal): count Kill all per daemon generation within a time window

- A poll updates only the daemon generations that answered, so one
  failing generation no longer hides the kills of the others.
- Poll for 6.5 s of wall-clock time instead of 65 attempts, because a
  wedged generation fails each listing only at the request timeout.
- Flag a sweep with no daemon provider as listingIncomplete.
- Log the leftover-tab exit, share the one-shot window intent with
  Open Settings, and cover the sender check, the reveal before the final
  quit, and retries in tests.

* fix(quit): stay open while a newer build's daemon is held

- Set listingIncomplete while this build holds a newer protocol's
  daemon, whose sessions it can neither list nor stop.
- Reuse getDaemonAdapters in Kill all, type the shared one-shot helper
  by its flag factory, and move the app-menu quit handlers next to the
  tray options so both serve/desktop splits are tested.
- Cover a quit that outlasts the request expiry and a failed request
  pull, and fix the docs lead-in for the new quit-time case.

* fix(quit): explain, without stopping anything, while a newer version runs terminals

- Check the newer-version daemon hold before the confirmation and show
  an explanation instead, so Kill all no longer closes every tab and
  then refuses. listingIncomplete stays as the backstop.
- Translate the explanation, describe listingIncomplete generically,
  and assert the single timed-out poll in the Kill all test.

* fix(quit): explain before asking whenever Kill all cannot list every session

- Show the explanation instead of the confirmation while the daemon
  provider is missing (still starting or failed) as well as while a
  newer version's daemon is held.
- Name only the steps that work (wait for terminals to open, reopen a
  terminal opened in a newer version), avoid stating a hold as fact, and
  label the dialog's button through the catalog.

* fix(quit): add the relaunch step to the explanation and align the ja wording

* test(pty): keep a confirmed stop when its generation fails a later poll

* test(quit): give the E2E timeout bump its reason

* fix(quit): stay open when the daemon still lists a session after Kill all

Kill all counts only the sessions of its first listing, so a session
started since then, for example from the CLI or an automation before its
tab reaches the renderer, would outlive the quit. Main now lists every
daemon generation again before quitting, and quits only after a listing
in which every generation answers and none lists a session. It polls
within Kill all's 6.5 s window so the tab sweep's PTY shutdowns can
finish; otherwise the renderer shows the existing error and Orca stays
open.

ui:quitAfterStoppingAllSessions becomes an invoke that answers whether
main quits.

* feat(quit): rename to Quit Completely with a macOS hover hint, and explain plain Quit in the confirmation

* fix(quit): show progress while Quit Completely runs, and refuse at once when the daemon can't be fully listed

---------

Co-authored-by: Neil <neil@stably.ai>
2026-10-27 03:52:06 -07:00
OrcaWinandOrcaWin 1b86ad9f95 test: remove 44 low-value settings cases and four suites (#34379)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 03:50:48 -07:00
OrcaWinandOrcaWin acdb9b4fe8 test: remove 35 low-value permission and search cases (#34375)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 03:33:48 -07:00
Neil 71f0c74d9e fix(wsl): start no running-distro read inside the stop settle window (#34372)
* fix(wsl): start no running-distro read inside the stop settle window

settledStartedAfter slept with one setTimeout until the settle anchor. Node truncates timer
delays to whole ms against a ms loop clock, so the wake can land up to ~2ms before the anchor
by performance.now(), and the probe then started inside the window and could still see the
stopping distro as running. That is the hook relay stop-settle flake ("expected true to be
false"). Sleep until performance.now() has passed the anchor.

* test(wsl): spy on setTimeout without a type assertion

* test(wsl): fire the spied timer far early so a single sleep always fails
2026-10-27 03:29:12 -07:00
OrcaWinandOrcaWin 184748c3fd test: remove 66 low-value cases and four suites (#34370)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 03:17:27 -07:00
e49cab0a92 fix(workspace-board): paired hosts keep their own custom status columns (#34362)
* fix(workspace-board): paired hosts keep their own custom status columns

A desktop client grouped a paired host's workspaces with its local column
list, so cards in host-only columns (e.g. status-6) fell back to the default
column. Fetch each host's workspaceStatuses via the existing ui.get RPC and
merge them after the local columns for grouping, without persisting them.

Fixes #34227

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

* fix(workspace-board): keep paired host columns safe from local column edits

- Removing a local column resolves cards against the merged board list, so a
  host card in a host-only column is never rewritten.
- New column ids are unique against the merged list, not just local ones.
- The context menu status submenu and the closed-sidebar order use the merged
  columns too; the shared-status helper moves to the menu policy module.
- A host that sends no columns adds none instead of the defaults; identical
  replies keep the stored identity and out-of-order replies are dropped.
- The merged list is named boardStatuses and tolerates stores without the
  host fields, so the earlier WorktreeList fixture edits are reverted.

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

* fix(workspace-board): keep host cards whose host still defines a removed id

Removing a local column whose id a paired host also defines rewrote that
host's cards to the local fallback. Skip runtime-host cards when their own
host still has the column.

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

* fix(workspace-board): keep host column ids in the composer and drop a retired host's columns

Creating from a host-only lane now keeps that column's status, a host that is
removed or re-paired to another machine no longer leaves its columns behind,
and the new tests use checked fixtures instead of casts.

Co-authored-by: Kooooojun <edisonhuang1122@gmail.com>

* fix(workspace-board): deliver a host's workspaceViewChanged so its columns refresh

Co-authored-by: Kooooojun <edisonhuang1122@gmail.com>

* fix(workspace-board): show and offer a paired host's columns only for that host's cards

The board adds a host's column only when one of that host's own cards uses it,
never the host's copy of the default column, so local cards keep falling back
to the local list. The context menu offers host columns only when every card
is on that host, the composer applies a lane's host column only when creating
on that host, and status writes drop another host's column id.

Co-authored-by: Kooooojun <edisonhuang1122@gmail.com>

* fix(workspace-board): read cards through the record selectors and skip foreign-lane drops

Board lanes and the context menu now leave out a host's copy of the default
column, so a host card's menu matches its lane. Lanes skip the card scan when
no host adds a column. A drop into another paired host's lane is ignored
instead of re-ranking the lane.

Co-authored-by: Kooooojun <edisonhuang1122@gmail.com>

* fix(workspace-board): sync tasks against every offered column and test host-lane drops

Task-status sync now finds a paired host's column that no card uses yet, as the
card's menu offers it. A write left empty after dropping another host's column
is skipped. New tests cover board and sidebar drops into a host-only lane.

Co-authored-by: Kooooojun <edisonhuang1122@gmail.com>

* fix(workspace-board): resolve host columns by runtime owner and compare mixed selections per card

A paired host's SSH workspace, which the host's runtime owns, now gets that
host's columns like its other cards. A mixed selection marks and moves each
card against its own host's columns. A status write for a card the store does
not know yet passes through unchanged.

Co-authored-by: Kooooojun <edisonhuang1122@gmail.com>

---------

Co-authored-by: Kooooojun <edisonhuang1122@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 03:02:14 -07:00
Neil 325ab0d886 fix(projects): register a folder once when two adds race on a server (#34303)
* fix(projects): register a folder once when two adds race on a server

A paired server's repo.add looked for an existing project, then awaited icon
and upstream detection before saving. Two adds of the same new folder both
passed the check and saved it twice. Re-check right before saving, as the
desktop's local add already does.

Part of STA-12331.

* refactor(projects): reuse the add's store when adopting an existing project
2026-10-27 03:01:27 -07:00
OrcaWinandOrcaWin df95be4090 test: remove 17 low-value cases and six suites (#34359)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 03:00:53 -07:00
Neil afdb59a241 fix(startup): discover worktrees without waiting for slow hosts (#34331) 2026-10-27 02:48:31 -07:00
Neil 2dca6a8eb2 test(wsl): hand the reap test's fake cat its real stdin (#34352)
* test(wsl): hand the reap test's fake cat its real stdin

The fake cat backgrounded the real cat with `&`, which a non-interactive sh starts on
/dev/null (dash even under `<&0`). The socket reader therefore ended at once, before orcad
hung up, and the relay killed its partner, sometimes before that cat's TERM trap was set:
on Linux under load the trap count stayed at 1 even after #34329 (3 of 6 rounds of 50
failed). The fake cat now passes stdin on fd 5, as the relay itself does, so the socket
reader ends only when orcad hangs up and the stdin reader blocks until killed.

* test(wsl): mark the fake cat armed only once its child is known; tighten the comment
2026-10-27 02:36:25 -07:00
HansssandNeil 433d044d65 fix(i18n): localize every contextual tour step (#12713)
Only the automations and client-hosted-browser steps had an id-keyed
entry in the localized step copy map, so every other contextual tour
(workspace board, agent sessions, browser, tasks, floating workspace,
workspace creation) rendered English titles, bodies, and action labels
next to localized Back/Next/Done controls.

Give every tour step a required stable id and move the copy lookup into
contextual-tour-step-copy.ts. The map `satisfies` a record over all step
ids, so a new step without localized copy is a type error. Primary and
secondary action labels (Split terminal, Got it, Browser settings) are
localized through the same entry. Existing automations and
client-hosted-browser keys are unchanged so shipped translations keep
resolving.

Add the new strings to en and translate them for ko, es, ja, zh, fr,
and pt.

Co-authored-by: Neil <neil@stably.ai>
2026-10-27 02:34:54 -07:00
Neilandoutof-place b066fc447f fix(i18n): translate native notification copy (#34348)
Bell, test, task-complete, tool-preview, permission-probe and startup
registration notifications now read their sentences from the i18n
catalogs instead of English literals. The notification translator
accepts interpolation values; the English default fills them so
headless hosts produce unchanged English copy. The startup permission
prompt waits for main-process i18n before it is shown.

Fixes #27068

Co-authored-by: outof-place <contact@outofplace.space>
2026-10-27 02:29:25 -07:00
OrcaWinandOrcaWin f699660080 test: remove 32 low-value cases and five suites (#34346)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 02:22:43 -07:00
Neil 3b7ee71b0f refactor: group repository settings composition (#34347) 2026-10-27 02:17:28 -07:00
C.P. 04f5104e15 test(native-chat): close queued-message journal DB before fixture cleanup (#25478)
The queued-message test rig deleted its temp state directory while the
shared journal SQLite handle was still open, so teardown failed with
EBUSY on Windows. Close the rig root's journal database after the host
drains, then remove the directory.
2026-10-27 02:13:21 -07:00
Brennan Benson 6708d27687 Cookie import adds cookies without signing you out of sites (#34113)
* Import cookies without clearing existing sessions

* fix(browser): keep new cookie imports merge-only

* fix(browser): admit native cookie preparation through session lock

* fix(browser): retire superseded shipped cookie imports

* test(browser): make cookie expiry fixtures deterministic

* test(browser): restore cookie clear mock type import

* fix(browser): show skipped cookies in import result toast

* test(browser): expect native cookie imports to preserve existing coordinates

* fix(browser): report only successfully imported native cookie domains
2026-10-27 01:50:25 -07:00
Neil c8823b4c6f refactor: group shared native chat composer input (#34328)
* refactor: group shared native chat composer input

* refactor: consolidate concrete composer imports
2026-10-27 01:50:08 -07:00
Wooseong KimandNeil e3affc0e9a fix(github): enqueue a merge-queue PR when auto-merge is disabled (#24327)
On repos whose base branch requires a merge queue and that disable
auto-merge, gh pr merge --auto always calls enablePullRequestAutoMerge,
which GitHub rejects. Call the enqueuePullRequest mutation directly in
that case and report enqueue failures as merge-queue errors.

Fixes #19638

Co-authored-by: Neil <neil@stably.ai>
2026-10-27 01:46:34 -07:00
OrcaWinandOrcaWin 17caf3d045 test: remove 20 low-value cases and a presentation suite (#34333)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 01:45:30 -07:00
Neil 72a4fd1ac1 test(wsl): make the bash relay reap test deterministic (#34329)
It raced the relay's kill against the stub cats setting their TERM trap, and picked the cat to
keep blocked by start order. It now hangs up only once both traps are in place, and tells the
socket reader from the stdin reader by whether its stdin is the relay's socket (fd 3).
2026-10-27 01:40:54 -07:00
Neil ab9532ecd8 feat(wsl): let an idle WSL distro stop once its server idle-exits (#33084)
* feat(wsl): let an idle WSL distro stop once its orcad idle-exits

The WSL host's holder kept the distro (and the WSL VM) running after Orca quit, even with
nothing running in it. orcad now leaves a release request in ~/.orca when a managed idle stop
retired its terminal daemon; the holder waits for that orcad to exit, claims the request and
ends, so WSL can stop the distro. Live terminals, working agents, enabled automations or a
returning client keep the distro held as before. A host whose distro is stopped at startup
reads as stopped instead of unreachable, and the real-WSL lane gains a phase that proves the
release and records memory.

* fix(wsl): key the holder release on the WSL-host launch marker; name the lane phase

The real-WSL lane showed orcad idle-stopping with its daemon retired while the distro stayed
up: the setsid'd orcad's environment is not guaranteed to carry WSL_DISTRO_NAME, so the
release request was never written. Use ORCA_WSL_ORCAD_HOST, which only WSL-host launches set.
Phase 3 now carries its phase name and path filter, and records what kept a distro running.

* test(wsl): dispose the idle-release lane's guest transports

Each guest command left its exec loop running, a wsl.exe client that kept the distro up after
the holder had already let go (the receipt showed no holder, no orcad, no request left).

* test(wsl): record which wsl.exe clients keep the idle-release lane's distro up

* test(wsl): satisfy the flaky-test ratchet; feed the new idle port in the release test

* test(wsl): snapshot guest processes after launch to find what holds the session

* test(wsl): locate the step that leaves the zombie holding the idle distro

* test(wsl): log the idle-release lane's guest commands with times to place the zombie

* test(wsl): follow the remote runtime client's move

* test(wsl): record when each leftover WSL session init started

* fix(wsl): keep the distro while the user still runs anything, and never trip on the request file

Review of #33084:
- The holder now checks, before claiming a release, that no process of the user runs outside
  the holder itself (session plumbing aside: systemd --user, (sd-pam), dbus-daemon). A detached
  tmux, nohup job or dev server keeps the distro; it fails toward holding.
- A new holder drops any request left from before it started, so an older orcad's request can
  never end a holder a client just asked for.
- orcad touches the request file only for WSL-host launches and never throws over it.
- The real-WSL lane proves a detached job keeps the holder and its request, and the distro
  stops once the job ends.

* fix(wsl): a running container keeps the distro, whoever owns its shim

Docker's containerd-shim processes run as root, so the user-only scan missed them and a
release would have stopped running containers. Any containerd-shim process now keeps the hold.

* fix(wsl): read each process status only up to Uid; document what keeps the hold

Delta review of #33084: dash reads a status file a byte at a time, so stop at Uid. Document
that a root default user never releases, that per-user agents hold it, and the hidepid
exception. The lane's pkill no longer matches the shell running it.
2026-10-27 01:28:40 -07:00
Neil 0ed5f4bb21 fix(orcad): materialize the app's agent-browser driver into the local slot (#34150)
* fix(orcad): materialize the app's agent-browser driver into the local slot

Replaces #34111's ORCA_AGENT_BROWSER_DRIVER hand-off, Windows profile copy and
claimed snapshot store. Packaging now references the app's own
resources/agent-browser-<target> from the orcad template manifest
(packagedBrowser, like packagedRipgrep), so the materialized slot carries it and
every local orcad launch finds it beside orcad-server.js. macOS signs the driver
before hashing; Windows reseals it after SignPath. The resolver now also tries
the musl driver name on Linux.

Refs #33846

* build(orcad): let a checkout keep template drivers with ORCAD_OMIT_AGENT_BROWSER=0
2026-10-27 01:28:20 -07:00
OrcaWinandOrcaWin 755bbfaa13 test: remove 53 low-value cases and eight suites (#34302)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 01:16:41 -07:00
OrcaWinandOrcaWin 4378e2fd3b perf(native-chat): load the chat host and agent adapters on first use (#34318)
Startup evaluated every structured-agent adapter (claude, codex, acp, pi)
even when no chat was opened. The host install already loaded the
registrations with a dynamic import, but structured-chat-cli-fork imported
the same module statically to read sessionHistory, which the lightweight
metadata already exposes.

- structured-chat-cli-fork reads structuredAgentRuntimeMetadata (the same
  objects, so behavior is unchanged).
- installOnJournal moves unchanged into structured-agent-session-host-assembly,
  which install() loads on first host install; the existing installing slot
  already single-flights and retries it.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 01:14:23 -07:00
Neil 3cf09081da refactor: group shared native chat scope cache (#34314) 2026-10-27 01:12:21 -07:00
NeilandSeiji Kohara c0f9df5bea fix(ssh): keep the IME confirmation Enter from submitting the port-forward dialog (#34315)
The SSH port-forward dialog renders its four fields as raw inputs inside a
form with a submit button. IMEs that redispatch an unmarked Enter after
compositionend therefore trigger implicit submission with the half-typed
value. The pre-revert ImeEnterGuardedForm covered this form; #25480 moved
the guard into shared fields but did not reach these raw inputs, and the
#28609 lint rule only inspects Enter handlers, which these fields lack.

Render the fields with ImeInput so the shared gesture tracker swallows the
confirmation and its redispatch while ordinary Enter still submits.

Co-authored-by: Seiji Kohara <sage.0118@gmail.com>
2026-10-27 01:03:19 -07:00
Neil 80c9278b89 fix(wsl): say why a silent WSL guest command failed (#34304)
* fix(wsl): say why a silent WSL guest command failed

A guest command that exits non-zero with empty stderr was reported as
"WSL <distro>: command failed". When wsl.exe itself fails it writes its
error to stdout, so the real cause was dropped. Report stderr, else
wsl.exe's own error, else the exit code, for the Claude account pointer,
OpenCode reader, WSL CLI install and WSL file operations.

Refs STA-12262 (#33917)

* refactor(wsl): share the wsl.exe host-failure exit check

* test(wsl): type the guest failure fixture instead of asserting it
2026-10-27 00:58:25 -07:00
OrcaWinandOrcaWin bbc35c1a98 test: remove 30 low-value cases and 11 suites (#34288)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 00:54:59 -07:00
Neil 16ea126b4e fix(repos): remove a paired-server project while its server is unreachable (#34079)
* fix(repos): let a project be removed while its paired server is unreachable

An unreachable server's repo.rm timeout aborted the whole removal. The error toast
now offers 'Remove from this desktop now', which purges this desktop's rows, records
a pending repo.rm (persisted UI state, optional), fences the server's catalog so it
cannot re-add the project, and replays the removal once the server is ready again.
Re-adds and replays for one server are serialized so neither undoes the other.

Fixes STA-9705

* fix(repos): replay owed removals whenever the server is ready, and lift the fence on refusal

Main publishes status only on change, so a record written or seeded after the ready
snapshot now replays at once. A refused replay refreshes the server's catalog, a
retired server drops its records, a user disconnect also offers local removal, and
the field is main-owned so paired clients cannot overwrite it.

* fix(repos): keep owed removals across disconnects and re-pairs; drop them only for forgotten servers

Also picks up records written during an in-flight replay, classifies the new UI field for
WSL moves, and fixes the test's projection shape.

* fix(repos): say 'disconnected' when the user disconnected the server, and test records surviving re-pair

* fix(repos): retry a replay when the server reconnects while it is still failing

* test(repos): narrow the toast action instead of asserting its type

* test(repos): run the toast action's removal directly instead of dispatching its handler
2026-10-27 00:51:44 -07:00
Neil e59e4eb550 fix(wsl): close a WSL host channel with stdin EOF before killing wsl.exe (#34307)
* fix(wsl): close a WSL command channel with stdin EOF before killing wsl.exe

Killing wsl.exe while its guest command still runs can leave the WSL session (an /init with a
wslhost.exe helper) behind, which keeps an idle distro running. A closed channel now ends stdin
first and kills wsl.exe only if the guest has not exited within 2 s.

* fix(wsl): kill WSL-host channels still in their close grace at app quit

Review of #34307: a guest command that ignores stdin EOF would otherwise keep its wsl.exe up
past Orca's exit for the rest of the grace. Quit teardown now kills every channel still in its
grace. The abort test runs on fake timers instead of waiting the grace in real time.
2026-10-27 00:50:37 -07:00
NeilandClaude 4c66f91c84 perf(native-chat): stop unrelated host status flips from rerendering every chat (#34300)
useStructuredAgentSessionOwnPermissionState subscribed to the whole
runtimeStatusByEnvironmentId map, so each status publication for any paired
host rerendered every mounted chat (including hidden ones). Select the
derived capability verdict for the chat's own host instead.

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-27 00:34:28 -07:00
Neil 2c6dd27276 refactor: group shared native chat shell environment policy (#34301) 2026-10-27 00:30:13 -07:00
Kelvin Amoaba cbbaa2d763 fix(agents): stop reading "action required" in a Pi/OMP session name as a permission prompt (#34294) 2026-10-27 07:19:37 +00:00
Neil 1dec1ebc35 refactor(shared): group native chat visual contracts (#34296) 2026-10-27 00:03:29 -07:00
Kelvin Amoaba 30872835cd fix(browser): type text that starts with a dash literally instead of as an agent-browser option (#34289)
* fix(browser): type text starting with a dash literally instead of as an agent-browser flag

* fix(browser): keep fill scripts on eval --stdin and send well-formed batch text

* fix(browser): leave passthrough multi-command batch replies unwrapped

* fix(orcad): pass the wait process timeout through the run options

* refactor(browser): let caller stdin imply argv mode and share the batch decoder in tests

* test(orcad): decode batch commands in the provider selection fake
2026-10-27 07:01:46 +00:00
Brennan Benson a0e7fa0619 Keep Claude approval choices across model changes without freezing delivery (#34031)
* fix(native-chat): keep Claude approval choices across model changes without freezing delivery

A Claude chat saved as "Approve for me" could reopen asking for every approval,
because Orca read the folder's saved model list as launch policy, and a model
change could keep running in a weaker approval mode Claude opened with. The
first fix for this was reverted after it froze the app: restored history left
a turn reading as running, a send was refused against it, and delivery retried
the same send with nothing changed.

- The saved approval choice goes to Claude as-is; the menu offers every mode.
- Orca records the mode Claude actually opened in. A send that picks a new
  model reopens Claude first when that mode differs from the one requested,
  only when the chat owes no work; Orca mail notices never reopen it.
- A message sent while a Claude turn is running joins that turn on its current
  choices; new choices apply at the next new turn. Nothing is refused.
- History catch-up closes every turn it opens, in the thread it opened in.
- At startup, a turn reading as running under the new agent that the agent is
  not running is ended as interrupted.
- Delivery goes round again only after a step shows what it changed (a commit,
  a different child, a start it joined ending, or a wake); otherwise it waits
  for the next change instead of repeating the same step.

Tracked in STA-10953.

* fix(native-chat): preserve execution evidence at dispatch

* Fix delivery iteration ownership and progress contracts

* Correct journal fixture types in delivery regressions

* Separate Claude input choices from error correlation
2026-10-27 00:01:09 -07:00
Brennan Benson 1c4d4a03bc feat: drag to reorder queued messages on desktop and phone (#34026)
* feat: drag to reorder queued messages on desktop and phone

* fix: use the queue grip button padding from its primitive

* fix: preserve the queue grip touch width with hit slop

* test: carry queue animation mocks into the chat view harness

* test: complete the shared chat view harness registrations

* test: carry the queue move cross-version wire contract

* Scope queue move feedback to the issuing chat and preserve phone touch width

* Keep queue reorder presentation stable during measurement and pending moves

* Keep measured row handoff tokens constant size

* Avoid rebuilding queue arrival IDs on unchanged renders

* Fix mobile queue regression test fixture boundaries

* Share the queued message leading slot with its reorder grip

* Fix queue regression fixture quality findings

* Check queue icons within the leading slot

* Allow every unsettled queued message to reorder

* Supply stable scope in queued row test mock
2026-10-26 23:57:36 -07:00