Commit Graph
20022 Commits
Author SHA1 Message Date
OrcaWinandOrcaWin de3da487fa test: stop worker-teardown console race from failing unit shards (#39813)
Vitest rejects a console-log RPC still in flight when a worker tears
down, failing a shard whose tests all passed. Ignore only that rejection
(the lost line belongs to a finished file and passed-only shards drop
it anyway), and stop the two specs seen in CI from spawning real git and
wsl.exe in fire-and-forget background work.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-08 02:55:36 -08:00
NeilandCopilot b4a522deeb Use Appearance's searchable picker for terminal themes (#39800)
* fix(settings): unify terminal theme pickers

Reuse the Appearance searchable selector and palette swatches while preserving imported-theme actions and independent terminal theme slots.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(settings): don't replay a handled theme import after remount

Settings search unmounts the theme row, so the picker remounted with
handledImportSignal=0 and reopened at Imported without a new import.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-11-08 02:50:22 -08:00
NeilandCopilot fc8dcd65eb Simplify delete workspace dialog (#39801)
* feat(sidebar): simplify delete workspace dialog

Replace the "Don't ask again" checkbox with an "Always delete" option in a
split-button dropdown on the Delete button, matching the force-delete toasts.
Shorten the description and change-loss copy so the dialog reads lighter.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(sidebar): keep delete change-loss warning protected and shown when status is unknown

Default Delete forces removal, so restore the permanent-loss notice while a
target's Git status is still checking or unavailable. Mark the dirty-change
hint as protected copy so language packs cannot replace the loss warning.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-11-08 02:29:48 -08:00
Brennan Benson 7a8c16caa5 Preserve the chat's history when forking (#39168)
* Preserve the chat's history when forking

* Preserve fork receipts and finished conversation history

Save native-copy receipts on the real create path, retain standalone Codex copies and Claude compaction bridges, and omit unfinished helper output. Restore rewind read-error refusals and update the affected provider fixtures.

* Keep fork coverage tied to OpenCode's copied messages

* Preserve the actionable refusal when chat creation stops

* Keep completed helper answers when copying chat history

Follow spawning tools and active helpers to their descendants without making an omitted goal row invalidate a settled helper's independent output. Reuse the public copy-error distinction so private transcript exceptions stay behind the generic create refusal while authored fork errors remain actionable.

* Keep fork history stable with OpenCode 1.x

* Exclude later continuation notices from fork snapshots

* Keep fork continuation notices tied to retained work

* Keep fork catch-up recoverable and preserve copy cancellation

* Keep OpenCode coverage timeouts on the read refusal path
2026-11-08 01:48:11 -08:00
Neil fca1d7b134 fix(mobile): prevent duplicate queued sends after chat remount (#39809) 2026-11-08 01:16:15 -08:00
Jinwoo Hong 4fabde28b1 feat(cli): one enclosing-workspace rule, --environment local, copyable addresses, and --parent-environment (#39733)
* feat(cli): one enclosing-workspace rule, --environment local, and copyable workspace addresses

current/active and cwd inference now pick the innermost workspace of either kind (worktree or
folder workspace); at equal depth the caller terminal's own workspace wins, otherwise the choice
is refused as ambiguous. --environment local names this machine's own Orca over an ambient
ORCA_ENVIRONMENT or pairing code. worktree ps/show/current print an environment: line and an
address: line (JSON environment, address, addressUnavailable, parent) that always carries its
--environment, and name a parent's environment only when it is verified.

* test: answer the folder catalog read in agent launch cwd tests

* feat(cli): worktree rm refuses current/active and names the selector to pass

Removal needs an explicit workspace, as git worktree remove needs a path. The refusal runs before
rm decides between a worktree and a folder workspace, and reports what current resolves to now
(one selector, the ambiguous choices, or none) in text and as invalid_argument data.

* fix(cli): keep the remote-environment guidance when rm refuses current

* fix(cli): surface folder-catalog failures for omitted targets; no address for a duplicated folder parent

* fix(cli): surface a worktree-list failure for omitted browser and terminal targets too

* test(cli): folder rm refuses current/active before the folder removal path

* fix(cli): refuse a cwd owner whose folder host can't be derived instead of skipping it

* fix(cli): compare cwd owners by filesystem identity, refuse every equal-path tie, surface worktree-list failures

Paths on the caller's own filesystem compare by realpath (reusing resolveRealPathSync), so /tmp
and /private/tmp aliases find the deeper owner in both the folder prefilter and ranking; other
hosts' paths stay lexical. Equal-depth owners with different repo registrations now refuse without
a caller instead of picking by catalog order. An omitted target no longer swallows worktree.list
method_not_found; only the optional folder reads fall back.

* fix(cli): read the realpath helper from shared so the packaged CLI ships it

* refactor(cli): move the catalog row type and unresolved-owner refusal out of the selection/catalog cycle

* fix(cli): resolve every caller-filesystem workspace path, not only basename matches

A workspace registered through a differently named symlink was skipped by the basename gate.
Containment now realpaths cwd and each row on the caller's own filesystem once per command,
shared by the folder prefilter and ranking; folder hosts are derived first so another host's
paths are never resolved locally.

* test: answer the folder catalog read in the ambiguous orchestration-check caller test

* feat(cli): --parent-environment names where a worktree's parent lives

worktree create and worktree set take --parent-environment <local|saved id|name>
next to --parent-worktree. The parent is resolved in that environment only, and
sent to the child as a verified cross-store ref after the child's cross-machine
capability check. Without the flag, the parent stays in the child's environment;
active/current always mean this machine's own Orca.

Preflight failures happen before any change: environment_not_paired,
environment_unavailable, LINEAGE_PARENT_NOT_FOUND / LINEAGE_PARENT_AMBIGUOUS
naming the searched environment, and incompatible_runtime with data.environment
and data.requires.

* fix(cli): parent lookup errors name and list the environment searched

LINEAGE_PARENT_AMBIGUOUS and LINEAGE_PARENT_NOT_FOUND now always carry
data.environment and a listing command for the environment the parent was
looked up in, for parents in another environment and in the child's own. Steps
inherited from the runtime listed the caller's default route instead.

* docs(cli): a local address names the Orca that printed it
2026-11-08 04:08:07 -05:00
OrcaWinandOrcaWin 0da741a22f test: remove 988 low-value tests (#39797)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-08 00:42:37 -08:00
Jinjing 9a1c3a362d more accurate chat ui invocation count (#39784)
* rm doc

* wip

* wip

* wip

* wip

* wip

* Handle opening message receipt collisions
2026-11-08 00:40:56 -08:00
Jinjing c60bd0f2a3 fix: align sidebar activity badge with visible agents (#39783)
* fix: align sidebar activity badge with visible agents

* fix: retain activity focus read ratchet entries
2026-11-08 00:22:21 -08:00
Jinjing 5e496520c5 Allow interleaving projects and groups in the sidebar (#39768)
* Allow interleaving projects and groups in sidebar

* Fix drag refs during render
2026-11-08 00:16:23 -08:00
NeilandCopilot 178a9f27bd fix(new-workspace): keep project list closed when Add project dialog lazy-loads (#39764)
The Add project dialog focused Browse in a mount effect before its focus
trap registered, so the composer trap bounced focus back to the Project
field, which reopened the project list on top of the new dialog.

Focus Browse from the dialog's onOpenAutoFocus instead, and close the
project list when focus leaves the field and its popup.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-11-08 00:09:44 -08:00
OrcaWinandOrcaWin ee6506714e test: remove 244 low-value tests (#39781)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-08 00:06:49 -08:00
Jinwoo Hong 14492c79cd fix(runtime): keep the output of a worker whose terminal dies during startup (#38475)
* fix(runtime): keep the output of a worker whose PTY dies during startup

A PTY exit frees its recent-output buffer before the readiness failure is formatted, so a launch that killed its terminal reported only terminal_exited. The exit now keeps what the last command printed on the PTY record, and the readiness failure for that exact incarnation reports it like a launch whose shell survived. The start receipt redacts dispatch capabilities from the reason.

Builds on #37866 by @gsxdsm.

* fix(runtime): bind saved exit output to its incarnation and survive a repeated exit

* fix(runtime): redact secrets from a failed worker start's reason
2026-11-08 03:03:33 -05:00
OrcaWinandOrcaWin d058920e15 test: remove 357 low-value tests (#39743)
* test: remove 362 low-value tests

* test: retain five boundary regression cases

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-07 23:40:13 -08:00
Neil 5df115db15 fix(relay): runtime edge control on the director, safer skipped exports, faster evacuation (#39773)
- Directors with an edge read director/edge.json from the relay-control bucket through the shared
  flag channel: mode on/off/down and rolloutPermille (0..1000). Boot defaults are mode on and the
  env percent; every cohort decision reads the applied flags. Off empties the cohort and hosts
  leave normally; down also skips the export at once (reason mode_down). The permille bucket keeps
  every host of P percent in at P x 10 permille. A control change re-arms the evacuation sweep
  within 5 s.
- A skipped export (120 s outage clock or mode down) removes the host's relay_devices rows before
  placing it, so revokes made on the edge are never undone; logs a count only.
- Evacuation: 100 drains per tick with 10 in flight, each pass starting at a random point of the
  keys and wrapping around; pages stay 500 rows and an idle pass reads each edge row once.
- Fence retries: 56 attempts (last about 25.5 h after the failure), 50 per sweep with 10 in
  flight; fence_abandoned now carries outcome, cell and epoch like fence_failed.
2026-11-07 23:38:33 -08:00
Neil c362cb183e relay-edge: keep valid desktops through JWKS outages, deep object probe, cohort-scaled alerts (#39772)
* relay-edge: keep valid desktops on JWKS outages, deep object probe, cohort-scaled alerts

- auth: tell 'token invalid' from 'keys unavailable'. An auth-refresh that cannot get keys keeps
  the control and its session unchanged (metric auth_refresh:keys_unavailable); the exp+grace
  close still applies. A control upgrade without keys gets 503 instead of 401 (shipped desktops
  treat both as a retried connect failure). The last good JWKS is kept in the colo's Cache API
  (24 h max age) as a fallback for cold isolates; a stored set lacking the token's key never
  reads as invalid.
- admin export ignores closing controls, like drain, so a just-drained host is not busy.
- GET /__health/object: canary HostRelay reads its SQLite (SELECT 1), no writes; per-source
  limited; 503 on failure or after 3 s. The alerts Worker probes it (object-probe, > 2 s alerts).
- alerts: MIN_VOLUME stays configurable, reconnect-surge rule (control hellos >= max(3x previous,
  RECONNECT_SURGE_MIN)), optional cloudflare-errors rule from the GraphQL Analytics API
  (CF_GRAPHQL_TOKEN). Rules moved to alerts-rules.ts.
- metrics: heartbeat events carry their 1-in-10 sampling factor as their last double.

* relay-edge: persisted JWKS trusted for 30 min, as the cells' stale window

* relay-edge alerts: opt-in reuse of the Analytics Engine read token for the GraphQL error rule
2026-11-07 23:38:28 -08:00
Jinjing e55b23c10e Prevent hover previews from interfering with context menus (#39757)
Keep workspace renames and input focus intact while dismissing hover
cards and help popovers on pointer or context menu interactions.
2026-11-07 23:37:21 -08:00
Jinwoo Hong 0d5a07fd0a fix(orchestration): report an idle worker once per coordinator message (#38484)
* fix(orchestration): report an idle worker once per coordinator message

A worker that ends turn after turn without worker_done (one that wakes on its own schedule, or one the user talks to) raised a HIGH escalation every turn. An idle finish now answers the coordinator's latest mail to the Dispatch, so it is reported once per mail; errors, prompts and exits still report every time.

Fixes the problem reported in #37868 by @gsxdsm, without a new worker command.

* fix(orchestration): key an idle report by mail that reached the worker, and make relay repeats a no-op

* fix(orchestration): key an idle report by coordinator mail the worker consumed

Delivery stamps can land before a chat admits the mail, and a bounded scan can miss the watermark; read mail is what a later turn answers. Helper reports into the same mailbox do not count.

* fix(orchestration): count consumed coordinator mail so out-of-order reads still re-arm the report

* fix(orchestration): leave heartbeats out of the consumed-mail key

* fix(orchestration): tell coordinator mail from helper reports by sender, not type

The consumed-mail key had its own type list, so a settled helper's status mail could still re-arm the idle report. A message counts unless its sender is one of the worker's own helpers, using the existing creator and assignee relationship.

* fix(orchestration): match a helper by its pane too, and only for mail it sent while helping

* fix(orchestration): leave any working peer's mail out of the consumed-mail key

A worker's own heartbeats and a sibling's broadcast also land in its mailbox. Mail from any worker of the Run sent while its Dispatch was open does not count, except the creator Dispatch that coordinates this one.

* fix(orchestration): count a peer's mail as a worker's only while its Dispatch was open
2026-11-08 02:30:03 -05:00
Jinwoo Hong 9f140c62b0 fix(terminal): see a prompt's turn start while child work keeps the agent busy (#38394)
* fix(terminal): see a prompt's turn start while child work keeps the agent busy

A Claude Code agent sitting at its prompt with background agents or shells
running reports working, held open by that child work. A prompt sent with
terminal send then started a turn without moving the row's state clock, so
the receipt never saw turn_started and warned the Enter may have been
swallowed, even when the prompt was submitted and answered.

Submission observation now reads the main agent's own turn start. The
receipt warning says the start was not seen yet rather than implying a
swallowed Enter, and terminal send --help describes --wait-submit and
--retry-request.

* test(terminal): type the child-work test's main-agent row instead of casting it
2026-11-08 02:27:37 -05:00
Jinjing ec07019a12 Use Ctrl+K for search on Windows and Linux (#39767)
* Use Ctrl+K for search on Linux and Windows

Preserve existing search and terminal clear shortcuts for legacy profiles until reset.

* Preserve existing Windows and Linux search shortcuts on rollout

* Preserve saved shortcuts in new profiles

* Keep window shortcut tests independent of defaults
2026-11-07 23:16:47 -08:00
Neil 4e66fb5510 fix(terminal): stop recovery snapshots from piling up on slow links; let opt-in pacing engage under floods (#39765)
* fix(terminal): send one ACK overflow recovery image per drained window

Recovery snapshots bypass ACK windows, so on a link slower than a flooding
TUI each ACK while overflowed published another full-screen image behind
the queued window. Measured through real orcad over a 1 Mbit/s shaped link
this queued images without bound: keystroke echo grew from 22s to 50s over
a 45s flood and the pane took 51s to settle. Holding the next image until
the output sent ahead of the previous one is acknowledged bounds that
queue to the window plus one image (echo <= 18s, settle 7s, 10x fewer
snapshot bytes). Server-only; no protocol change.

* fix(terminal): let adaptive ACK pacing engage under overflowing TUI floods

Through real orcad on a shaped 1 Mbit/s link, ORCA_TERMINAL_ADAPTIVE_ACK_WINDOW=1
never paced a 60fps full-screen TUI: once its queue overflowed, recovery
images cleared the queue, so later sends counted as idle trickle and the
estimate never collected window-limited samples. When it did, the images
(never acked) inflated paced RTT and tripped the divergence fallback.

- A stream whose output outran the window stays backlogged until an ACK
  finds its queue empty, so sends after a recovery still measure the link.
- The estimate records recovery images: they count as queue ahead of later
  sends (no drained/paced samples behind them) and as delivered bytes once
  an ACK of a later send confirms them.

Shaped-link soak (1 Mbit/s, 50ms): echo p50 13s -> 2.2s, settle 7s -> 1.1s.
Bench gains a 6.4 MB/s TUI scenario: paced 7.7s -> 1.2s.
2026-11-07 23:02:27 -08:00
Neil 83f8e6340d refactor(shared): organize file operations and storage owners (#39746) 2026-11-07 22:58:35 -08:00
Kelvin Amoaba 82c3c05a70 perf(mobile): switch back to a terminal without rebuilding it (#39705)
* perf(mobile): switch back to a terminal without rebuilding it

* fix(mobile): keep resume positions across terminal handle swaps

* fix(mobile): snapshot a cleared, reloaded or errored terminal instead of resuming it

* fix(mobile): cancel only resumable streams on a dropped connection and forget positions on a text-size change

* test(mobile): give the startup recording its catch-up read

* test(mobile): give terminal webview harnesses the resume state

* fix(runtime): end resume for a stream that saw its coverage reset while live
2026-11-08 06:54:46 +00:00
Jinjing cdc0f0306b Focus session search when switching sidebar tabs (#39763) 2026-11-07 22:54:20 -08:00
Kelvin Amoaba 5e361be030 fix(mobile): Jump back in follow-ups from W8b (#39702) 2026-11-08 06:54:05 +00:00
Kelvin Amoaba b40e868132 feat(mobile): offer to restore unsaved file and Markdown edits after the app is killed (#39710)
* feat(mobile): offer to restore unsaved file and markdown edits

* fix(mobile): keep offered edits through other discards and clear saved Markdown drafts

* fix(mobile): offer a copy of edits to a now read-only document and key drafts by host

* refactor(mobile): one guard for the draft save effect

* fix(mobile): clear an offer once its edits are saved by hand
2026-11-08 06:53:26 +00:00
Neil d5ef05a973 relay: edge fence failures (stale/conflict) recorded and retried from the evacuation sweep; cap pushes under row lock at 8 in flight (2 s); jti on edge admin tokens (#39740) 2026-11-07 22:53:05 -08:00
OrcaWinandOrcaWin 79c05e3f14 refactor(i18n): read AgentLaunchSetupPanel's copy from useTranslate (#39761)
The batch skipped it because the rewrite would cross the line budget;
with the panel's current shape the converted file fits, so convert it
in place with no split.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-07 22:50:03 -08:00
Kelvin Amoaba 29781fc694 feat(mobile): keep automation drafts across kills (#39683)
* feat(mobile): keep automation drafts across kills

* fix(mobile): drop a created automation's draft on affirm and restore saved fields under typed ones

* fix(mobile): stop saving an automation draft after it is dropped

* fix(mobile): reopen the automation editor with in-memory edits while the store can't be read

* refactor(mobile): one rule for which automation draft fields changed
2026-11-08 06:45:30 +00:00
Jinwoo HongandSeiya Iwaoka 291d584903 fix(cli): refuse ambiguous orchestration check callers (#38460)
Co-authored-by: Seiya Iwaoka <272756172+seiyaiwaoka-CR@users.noreply.github.com>
2026-11-07 22:43:36 -08:00
Kelvin Amoaba 81c97bb124 perf(runtime): push worktree row changes; host list poll becomes a 10 s backstop (#39688)
* perf(runtime): push worktree row changes; host list poll becomes a 10 s backstop

* fix(runtime): announce title-only agent status changes and gate the rows capability with the switch

* fix(mobile): keep event reads a floor apart while a read is out; announce a retired title clear

* test(runtime): assert the rows notice without counting events
2026-11-08 06:42:18 +00:00
Brennan Benson 104d01b686 Simplify the new-tab agent launch menu (#39279)
* feat(agent-launch): simplify the new-tab agent launch menu

Drop Permissions and Arguments from the launch-mode setup panel; they are
agent defaults edited in Agent settings. Put effort levels (unlabeled) and
Fast mode on one row, and make the Launch chat/terminal buttons fill the
row at a larger size with icons. Select-mode pickers (automations, new
workspace, source control, continuation) keep both controls.

* fix(agent-launch): let current Agent settings win over launch-menu speed edits

A Fast or speed-tier edit copies the current Permissions and Arguments into the
launch draft. With no Arguments editor in the launch menu, a later settings
change was silently ignored. Launch drafts now drop Arguments stamped by older
settings; the speed choice still applies. Also stop pointing hosts without a
model list at the removed Arguments editor.

* fix(agent-launch): show Fast as a button in the launch menu

Matches the mock: an outlined Fast chip with the lightning icon in place of the
"Fast mode" switch. The chat composer keeps its switch.
2026-11-07 22:37:41 -08:00
Kelvin Amoaba 3b6d5d4c15 feat(mobile): keep screen data on the phone between launches (#39719)
* feat(mobile): keep screen data on the phone between launches

* feat(mobile): keep the repo list snapshot id across launches

* fix(mobile): don't read a key again that the boot read just found empty

* fix(mobile): late-restored strips, revocation fence and reads never built on stored data

* test(mobile): give the session startup recording the late strip watch

* fix(mobile): remember Workspace options, keep the revocation fence until reauth, store no terminal output

* test(mobile): give the view settings recording its remember hook

* docs(mobile): say what a restored key means to a fetch

* style(mobile): format host-query after rebase onto Q11
2026-11-08 06:26:49 +00:00
buf0-bot[bot] 83a3d33681 Update README downloads badge (#39760)
Co-authored-by: buf0-bot[bot] <252831055+buf0-bot[bot]@users.noreply.github.com>
2026-11-08 06:26:44 +00:00
Neil 3a0e9a27d0 refactor: organize backend runtime by defining owner (#39625)
* refactor(main): organize runtime implementation owners

* test: retire wall-clock CLI title recovery case

* refactor: route new folder mutation to runtime store owner

* test: import folder mutation store contract from its owner
2026-11-07 22:24:34 -08:00
OrcaWinandOrcaWin 8f60fbb5a9 refactor(i18n): finish the review notes send menu and resume groups on useTranslate (#39755)
Both would go over budget once converted. The send-target ordering and
the resume tree's group node move to their own modules first, then the
codemod converts the menu, its target rows and the resume tree nodes.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-07 22:15:43 -08:00
Brennan Benson 1f5a5e155c /btw asks a side question in a fork beside the chat (#39268)
* feat(chat): /btw asks a side question in a fork beside the chat

In a Chat UI chat that can fork, /btw <question> (or /side) forks the chat
through its newest finished response, sends the question there, and moves the
fork beside the chat the way dragging it does. The source chat is untouched;
the draft clears only once the question went out. Agents that cannot fork keep
their own /btw.

* fix(chat): type-guard the side chat command names

* fix(chat): side chats own the screen from Send and never place an unsent question

- Placement starts at Send, retires for good on any other selection in the
  workspace or on leaving it, and looks only at the requesting workspace.
- A question that never went out leaves its fork in the background; an
  unconfirmed one says to check the side chat before asking again; a failure
  the new chat already reported is not repeated.
- The command menu shows "Available after the first reply" / "when this reply
  finishes" while it is open, using the drawn turn order.
- File pills count as attachments; picking /btw completes the row.

* fix(chat): /btw reads the newest response the drawn transcript offers Fork on

The menu reason and Send now follow the transcript's own Fork rule as drawn,
reported when it changes, instead of rebuilding turn membership in the composer.

* fix(chat): side chat failures always reach the source; watch window starts when the fork opens

- A failed side question toasts in the source even when the fork recorded it,
  since the fork stays in the background.
- The 60 s placement window starts once the fork exists, not at Send.
- The fork-point scan stops at a /clear and, for tip-only agents, at the
  newest turn; split placement looks only in the requesting workspace.

* fix(chat): /btw forgets a fork point the transcript no longer offers

- Send and the menu reason refuse a reported response that is no longer
  forkable, and an unmounted transcript reports nothing to fork.
- The fork-point scan skips subagent sections before its early stops.

* perf(chat): /btw steps over a running turn instead of walking its rows

The slot builder groups root responses by turn in its existing pass; the side
chat's fork point reads those groups newest first and skips a running turn
whole, so streamed replies add no per-row work.

* fix(chat): /btw looks past responses outside any turn and skips the scan when nothing is forkable

* perf(chat): find the /btw fork point while laying out the transcript

Per the review ruling: the slot builder keeps the newest row that offers Fork
in its existing pass, only when /btw listens, and returns one point; the
response groups and their second search are gone.

* test(chat): /btw fork point contract through the transcript and Send hooks

* refactor(chat): response rows and /btw share one Fork rule

* test(chat): /btw fork point ignores pending-only renders and an emptied conversation

* test(chat): /btw contract counts every eligibility lookup and covers an undrawn transcript

* fix(chat): /btw shows ahead of agent commands, sends on one Enter, and focuses the side chat

- Side-chat rows lead the slash menu, so a long agent catalog no longer
  pushes them past the menu's row limit.
- Enter on a fully typed /btw sends it instead of only completing the row.
- Placing the side chat also moves keyboard focus to its composer.

* fix(chat): picking /btw completes the row again, as the common pattern does

Sending a fully typed /btw from the menu bypassed a same-named skill's
release and sent on a mouse click; a pick now always leaves '/btw ' to
add a question to.

* fix(chat): on layout-owner builds the moved side chat keeps its composer focus

Main selects a tab it moved once its frame shows it there, so placement no
longer selects it first in the source pane; moveTabToNewPaneColumn reports
whether main or this window moved it, as moveTabToGroup does.

* fix(chat): side chat placement owns main-drawn moves through to the drawn result

Per the review ruling: the placement claim stays alive while main draws the
move, reads the side chat's own new pane and selection as its own, and selects
and focuses the side chat once the frame shows it moved, in place when main
refuses, and never after the user selected elsewhere. The owner command takes
an optional completion in place of its own moved-tab selection.

* fix(chat): selecting the side chat in the pane it is leaving still retires the claim

Only what main's move changes elsewhere (a new pane holding only the side
chat, another pane showing it) reads as the request's own; the selection
counter in the placement contract reads every pane's selection, and the move
helpers' completion is exercised through main's frame transport.

* fix(chat): a side chat main never moves is selected where Fork put it

When main neither draws nor answers the move before the watch ends, the
side chat is selected in place rather than left hidden; the owner command's
completion path (no moved-tab intent, hand-back asks first) is tested.

* fix(chat): a side chat this window moves keeps its focus request

The move's own changes count as the request's from before the move starts,
so a synchronous move no longer retires the claim before the side chat is
selected and focused.

* fix(chat): picking an unavailable /btw row does nothing, as the common pattern does

* refactor(native-chat): keep /btw hooks compilable by React Compiler

* fix(chat): say side chats aren't ready while a fork from the chat is opening

* test(chat): assert the opening-fork refusal without its copy

* fix(native-chat): share one latest-turn scan between /btw and transcript rows
2026-11-07 22:14:45 -08:00
OrcaWinandOrcaWin 0545d1d89e test: mount the settings nav language test inside TranslationScopeProvider (#39754)
Without the provider useTranslate() falls back to the stable module
translate(), so `t` never changes in the test and only an unmemoized
render could pass it. Mount it the way the app does.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-07 22:13:26 -08:00
Kelvin Amoaba 3e9ca6e85a perf(mobile): open the PR tab with its last state and refresh only what a write changed (#39709)
* perf(mobile): open the PR tab with its last state and refresh only what a write changed

* fix(mobile): allow the phone's comment re-read and settle review findings

* fix(mobile): keep PR reads current across path switches and overlapping writes

* refactor(mobile): share PR query keys and simplify PR write rollbacks

* chore(mobile): list every PR action and comment write kind explicitly

* fix(mobile): read the push-time PR reread through an effect event

* fix(mobile): report a comment write interrupted by a path switch as unconfirmed

* fix(mobile): settle a comment write whose reply was lost from the re-read comments

* style(mobile): format host-query after rebase onto Q12
2026-11-08 06:12:07 +00:00
Jinjing 18eadb8628 Reorganize the worktree context menu (#39739)
Group related actions into submenus and clarify the scope of sleep and
delete actions for workspaces with descendants.
2026-11-07 22:05:03 -08:00
OrcaWinandOrcaWin 800ed1976e refactor(i18n): read render-path translations from useTranslate in the remaining renderer files (top-level components, app shell, entry points, hooks, lib) (#39427)
Applies pnpm i18n:reactive-translate --helpers. Output is unchanged: t delegates
to translate() and helpers default the threaded parameter.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-07 22:03:03 -08:00
OrcaWinandOrcaWin d50ca31308 test: drop the workspace cleanup facet rows' work-count assertions (#39748)
Three tests only counted how often facet, measurement and query passes
ran, and a fourth checked a zero count beside its real assertion.
AGENTS.md bans work-count tests, and they fail under React Compiler,
which memoizes differently. The behavior checks stay.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-07 21:54:24 -08:00
Kelvin Amoaba b4eda05c81 perf(mobile): show the last task list per filter while it refreshes (#39668)
* perf(mobile): show the last task list per filter while it refreshes

* perf(mobile): read Tasks repos six at a time

* fix(mobile): hold Tasks paging while kept rows re-read

* test(mobile): pin Tasks paging held during a query switch

* perf(mobile): read Tasks repos four at a time, the desktop's gh limit

* test(mobile): give the Linear connect recording the revalidating input

* perf(mobile): open Tasks on its kept hydration and lists through host query families

* fix(mobile): keep the desktop's newer Tasks state and only cancel screen-read queries

* fix(mobile): type the Jira refresh harness and Tasks list read for CI
2026-11-08 05:53:45 +00:00
Kelvin Amoaba 2a62af0262 feat(runtime): confirm a structured chat send by clientMessageId past the first journal page (#39667)
* feat(runtime): confirm a structured chat send by clientMessageId past the first journal page

* fix(mobile): ask the send's own chat before handing it back

* fix(mobile): read send-recorded support when the deadline fires and settle rows that land mid-lookup
2026-11-08 05:53:23 +00:00
Kelvin Amoaba 1ef68f5062 perf(mobile): stop polling automations when the desktop reports changes (#39664)
* perf(mobile): stop polling automations when the desktop reports changes

* perf(mobile): ship the host event router in the query hooks' chunk
2026-11-08 05:52:59 +00:00
Kelvin Amoaba db7ff5c8ff fix(mobile): re-subscribe Home and the follow-up preference after the client event stream ends (#39655)
* fix(mobile): re-subscribe Home and the follow-up preference after the client event stream ends

* fix(mobile): try a refused client event wire once per connected edge

* refactor(mobile): mark replayed client event readies in the shared stream

* test(e2e): give the phone feed socket client a state listener
2026-11-08 05:52:38 +00:00
Kelvin Amoaba 408a262a87 fix(mobile): re-probe an empty "+" agent list and derive the sheet state (#39651)
* fix(mobile): re-probe an empty "+" agent list and derive the sheet state

* refactor(mobile): mark the agent refresh sent from the transport's beforeSend
2026-11-08 05:52:22 +00:00
OrcaWinandOrcaWin 0b5c8f66a0 refactor(i18n): read render-path translations from useTranslate in smaller component areas (managed runtime through WSL move) (#39425)
Applies pnpm i18n:reactive-translate --helpers. Output is unchanged: t delegates
to translate() and helpers default the threaded parameter.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-07 21:43:29 -08:00
Neil d406a22214 perf(git): reuse the branch-compare changed-files list while its inputs are unchanged (#39747)
* refactor(git): share the .gitattributes ancestor stamp paths

* perf(git): reuse the branch-compare changed-files list per commit pair

* perf(git): charge cached change lists for the stdout their paths retain

* perf(git): bound branch change-list reuse to five minutes for unstamped system attributes

* refactor(git): share the deadline-bounded stamp probe

* perf(git): bound branch change-list attribute stamps by a 2s deadline and 4096 paths
2026-11-07 21:42:01 -08:00
965540a7bb perf(worktrees): re-rank only the worktrees a sort save moved (#39723)
A Smart-sort save rewrote every listed worktree's rank whenever the order
changed, so every repository on the host got an order-only
worktreesChanged event. planWorktreeSortOrderUpdates now keeps the
longest run of rows whose ranks already descend in the requested order
and re-ranks only the rest. It falls back to the full re-rank when a gap
is too tight for distinct whole ranks, or when the planned ranks would
not descend strictly (float rounding at huge ranks).

When the requested order holds a row the write cannot save (WSL-move
fenced or unknown host), the write keeps the full re-rank, since that
row's unqualified rank may belong to a same-ID twin and must never
anchor a partial re-rank.

Replaces #37142.

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
Co-authored-by: BTForIT <223167996+BTForIT@users.noreply.github.com>
2026-11-07 21:34:57 -08:00