Commit Graph
17078 Commits
Author SHA1 Message Date
Neil ea532813b1 refactor: group native chat turn presentation (#34629) 2026-10-27 17:33:03 -07:00
59dbb54dad ci: keep Git compatibility on Blacksmith (#34625)
Its three parallel real-Git lanes, two of them through Docker, push
git-binary-compatibility.test.ts past the 30s test timeout on the 4-vCPU
hosted runner (64s file time vs 14s), failing PR #34600 twice after #34566.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-10-27 17:29:39 -07:00
Neil 5105fd27ba test(e2e): fake WSL connector reports a stopped distro's dropped bridge as distro-stopped (#34624)
Production liveness publishes distro-stopped when a stopped distro loses its
bridge; the e2e fake published closed. An explicit disconnect still reports
closed.
2026-10-27 17:25:31 -07:00
Neil b7cd885aec perf(wsl): stop the idle profile-state writer thread on WSL hosts (#34545)
* perf(wsl): stop the idle profile-state writer thread on WSL hosts

The writer thread holds ~13-15 MB while orcad sits idle. On WSL hosts the
authority now closes it after a minute without a command and reopens it,
at the last acknowledged revision, for the next one (~22 ms). The desktop
and SSH hosts keep the always-on writer. Also covers an empty and a
misnamed keep-existing launch value.

* perf(wsl): count and log idle profile writer reopens

Writes arriving just over the idle window apart would churn the writer
thread unnoticed. Each reopen now counts, with one log line per ten
minutes so the field shows it.

* fix(wsl): retry a failed idle writer reopen instead of wedging saving

A failed reopen (spawn failure, thread exit, EMFILE) left the faulted
writer in place, so every later write was refused until orcad restarted.
A non-conflict initialize failure now rejects that one command and puts
the authority back in the stopped state; the next command retries at
once, repeated failures back off up to a minute, and a revision conflict
stays terminal. Abort no longer waits a tick when nothing is stopping.

* fix(wsl): let the final flush through a reopen backoff and report only terminal reopen failures

A final or maintenance flush now gets one reopen attempt even inside a
backoff, so shutdown never drops state for a transient spawn failure. A
retriable reopen failure is logged as a warning naming the retry delay
instead of reporting that saving has stopped; only a revision conflict
reaches onFailure.

* test(wsl): prove an unset idle stop arms no timer instead of sleeping

The no-option case waited in real time to show the writer stayed open.
With no idle timer armed nothing can close it later, so assert that
directly.
2026-10-27 17:15:43 -07:00
Pandu dwi PutraandBrennan Benson ec49e9fac0 fix(native-chat): list OMP skills in the / menu as /skill:<name> (#31999)
* fix(native-chat): list OMP skills in the / menu as /skill:<name>

* test(native-chat): OMP now carries the Pi-shaped skill profile

* Publish native OMP skills with compatible command catalogs

* Index native skill descriptions once per picker build

* Combine catalog test composer imports

* Correct native catalog test types and project inputs

* Run cross-platform picker scaling contract with mobile tests

* fix: discover native commands before the first chat message

* test: isolate native command discovery from mobile typechecking

* fix: release command discovery ownership after managed root exit

* refactor: reuse the ACP child owner during shutdown drain

* test(acp): load filesystem implementation before test execution

* test: drive discovery close completion explicitly

* test: await discovery admission cleanup between demand waves

* test: control discovery close ordering in demand waves

---------

Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
2026-10-27 17:14:20 -07:00
OrcaWinandOrcaWin 99199b2bd2 fix(i18n): localize GitHub project view errors and states (#34621)
* fix(i18n): localize GitHub project view errors and states

Main now tags Orca-authored project-view failures with an optional
reason code plus host, rate-limit numbers and diagnostic detail; the
English message is unchanged for mobile, older clients and logs. The
renderer maps type/reason to translated copy in the error state, picker,
item dialog and mutation toasts, falling back to the English message for
older hosts and GitHub's own text. Also wraps the layout labels,
unsupported-layout, not-found/too-large copy, picker partial-failure
summaries and the gh sign-in help.

Closes #34589

* test: expect input_too_large reason on oversized project refs

* fix: make project view error copy switches exhaustive

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 17:11:45 -07:00
OrcaWinandOrcaWin eb7448b260 fix(skills): force English git messages in copied POSIX skill install commands (#34599)
* fix(skills): force English git messages in copied POSIX skill install commands

skills@1.7.2 falls back to fetching a pinned commit only when git's
clone error is in English, so the npx command Orca shows or copies for
WSL, macOS and Linux failed under translated git (e.g. tr_TR). Prefix
those commands with env LC_ALL=C, matching the earlier in-app fix
(#28994). Native Windows cmd/PowerShell commands are unchanged.

* fix(skills): skip LC_ALL prefix when a remote runtime is focused

A focused remote runtime may be a Windows orcad host where env is unavailable.

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 17:11:41 -07:00
OrcaWinandOrcaWin b11b81702a fix(i18n): truncate Session History scope labels in narrow sidebar (#34597)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 17:11:37 -07:00
OrcaWinandOrcaWin 6a395dc4c4 test: remove 76 low-value cases and three suites (#34612)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 17:09:30 -07:00
Neil 336abf20a3 refactor: group session launch failure timestamp (#34602) 2026-10-27 17:07:09 -07:00
EvgeniiandOrcaWin 16547ff203 fix(i18n): localize the rest of the source control dropdown (#34145)
* fix(i18n): localize the rest of the source control dropdown

The Commit & Push, Push, Force Push, Pull, Fast-forward, Sync, Publish,
abort and Push-before-PR rows and their tooltips were English literals
next to rows that already go through translate(). Route them through
translate(), reusing the primary button's and the conflict card's keys
where the words match, and add 42 keys to the English catalog.

Commit blockers stay English inside eligibility, which compares them,
and are translated only when the dropdown shows them.

* test(i18n): pin the other two commit blockers under the pseudo-locale

The pseudo-locale test only reached the stage-file blocker, so an English
return for the conflict or commit-message blocker still passed. The new
case checks both in the Commit, Commit & Push and Commit & Sync titles.

* i18n: translate source control dropdown keys; trim duplicate pseudo-locale test

Add zh/ko/ja/es/fr/pt translations for the 42 dropdown keys this PR adds to en.json,
matching each catalog's existing source-control glossary. Drop the second pseudo-locale
test; the first already covers commit-blocker titles through the active locale.

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 17:03:13 -07:00
Neil b930606ee9 chore(wsl): require the allowlist check in any file that hand-builds a wsl.exe exec (#34615)
resolveCommand only checks what it resolves, so a file that also builds its
own wsl.exe exec no longer passes the import check on a resolveCommand call
alone. Note editor --remote wsl+<distro> launches as out of scope.
2026-10-27 16:53:48 -07:00
OrcaWinandOrcaWin 965286939d ci: sweep caches on idle non-main branches every three hours (#34605)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 16:53:14 -07:00
Neil 5e9e4c84a3 test(wsl-host): type into the WSL host terminal only after its shell prompt (#34607)
On CI the first keystrokes typed right after the WSL host terminal attached
were sometimes dropped (the shell received "L HOST TERMINAL ..."), leaving an
open quote, so the marker never printed. The spec now waits for the prompt,
which names the project folder, before typing. The dropped input itself is a
separate follow-up.
2026-10-27 16:42:54 -07:00
Neil acec0e7aa0 test: remove two load-dependent CI flakes (#34613)
- git-binary-compatibility: give the docker image runs of the ref-pairing case
  a 90 s budget; each Git call is a docker exec and the case normally takes
  22-25 s of the 30 s default.
- claude-transcript-catch-up: fire the 5 ms catch-up deadline with fake timers
  only after the fallback lookup has started, instead of racing a real timer.
2026-10-27 16:38:25 -07:00
Brennan Bensonandbeduldul 47018d4844 fix(source-control): decode Kimi generated text by selected format (#34237)
* fix(source-control): read the Kimi answer from stream-json

Kimi Code's text mode prefixes thinking and hook output with a bullet, so the
commit message arrived mixed with narration. The recipe now asks for
--output-format stream-json and the answer is taken from the last assistant
record, which is the commit message (#33556).

A record that requests a tool is narration rather than an answer, so it clears
the candidate: a stream that ends on a tool call yields no answer, which
finalizeFromAgentOutput already treats as a failed run. Only a body whose every
non-empty line is a record counts as stream output, so a plain answer that
happens to contain a JSON line is left alone.

* fix(source-control): decode Kimi output only for the selected protocol

* fix(source-control): satisfy generation hook checks

* Preserve Kimi generation failures and normalize options linearly

* Fix Kimi argument failure messages

* Bound Kimi option failure recognition

* Fix Kimi generation test fixture types

---------

Co-authored-by: beduldul <alkaysan07@gmail.com>
2026-10-27 16:33:33 -07:00
Neil 90c713af1f fix(wsl): refuse Windows drive folders on a WSL host, offer Add on this computer (#34530)
* fix(wsl): refuse Windows drive folders on a WSL host and offer to add them on this computer

A /mnt/<drive> project on a WSL host shows false line-ending changes, misses
edits made from Windows, and searches slowly. Add Project refuses typed,
picked and dropped Windows drive folders for a WSL host and shows the refusal
inline with Add on this computer, which switches the open dialog to this
computer. The WSL-host orcad re-checks by /proc/self/mountinfo (after
resolving symlinks) in repo.add, repo.create, repo.clone, explicit
folderWorkspace.create and the nested scan/import, answering with the
existing runtime_error code plus optional data, so older clients still show a
readable message. Everything is behind the WSL hosts gate; SSH is untouched.

* test(wsl): hold the e2e's this-computer add instead of racing its failure

On the Linux CI host the switched local add of a Windows path fails its nested
scan and hands off to the Open as Folder modal, closing Add Project before the
test looked. The refusal itself already came before any scan. The e2e now
records the local add at its scan step and asserts it went to this computer
with the Windows path; a unit test pins that a refused pick never reaches the
host path step.

* test(wsl): type the e2e's held-scan window hooks instead of Reflect
2026-10-27 16:29:54 -07:00
EvgeniiandOrcaWin 6c469aea6d fix(plugins): reject locale ids Intl cannot parse (#12533)
* fix(plugins): reject locale ids Intl cannot parse

`pluginLocaleIdSchema` checks the shape of a locale id but not its grammar,
and the shape check is looser than BCP 47 in one direction: `en-US-US`
(duplicate region) and `en-aaa` (a subtag that is neither region nor script)
both match it. A pack declaring one installs, loads, and translates every
string — and then `Intl.DateTimeFormat` throws inside `getIntlLocale()`, which
swallows the error and falls back to English. Nothing is logged, so the pack
author sees a working pack with English dates and no way to tell why.

Delegate the grammar to `Intl.getCanonicalLocales` in a `.refine`, so the tag
is rejected at install where the author can still act on it. The bundled
`pt-BR` pack and every other well-formed tag are unaffected.

* Condense this branch's comments to one line

AGENTS.md asks for one-line comments that say why, and main's comment
cleanup (#33249) applied that across the repository. This brings the
comments this branch adds in line with it. No code changes.

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 16:22:09 -07:00
7a834988dc ci: run mobile main tests on the hosted ARM runner PR verify uses (#34611)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-10-27 16:20:41 -07:00
Neil 5784e146de feat(wsl): internal distro allowlist that keeps WSL execs out of other distros on shared test boxes (#34539)
* feat(wsl): internal distro allowlist for WSL execs on shared test boxes

ORCA_INTERNAL_WSL_DISTRO_ALLOWLIST (comma-separated distro names) keeps every
wsl.exe call out of distros not on the list: process-host's resolveSpawn,
the main and daemon node-pty spawns, and the two codex-accounts calls that
bypass process-host. Pure list/status/version calls stay allowed; any other
form must name an allowlisted distro, and --shutdown or a default-distro exec
is refused. A malformed value refuses every distro and logs once. Unset, the
check reads the variable and returns, so behavior is identical to today.

* fix(wsl): cover every direct wsl.exe exec with the internal distro allowlist

- Restore #34525's worktree-create payload and captured-host test, reverted by
  accident in the first commit.
- Check the allowlist in execFileCapture, the choke point for WSL Git, gh and
  worker-thread captures, and before the WSL git-read probe, the Codex hook
  path canonicalization and the CLI login spawn. The WSL watcher now spawns
  through process-host.
- Stop scanning wsl.exe argv at the first positional argument, which wsl.exe
  runs in the default distro.
- check-process-host-imports fails on any direct wsl.exe exec outside
  process-host that does not call assertWslDistroAllowed.

* fix(wsl): check the distro allowlist where resolveCommand produces the wsl.exe form

Every Git, gh and glab path into a distro resolves through resolveCommand, so
gitExecFileSync, gitSpawn, git stream reads and wslAwareSpawn are covered too;
the execFileCapture check is now redundant and removed. The import check also
treats buildWslExecArgs as a wsl.exe exec and accepts resolveCommand as covered.
2026-10-27 16:19:13 -07:00
Jinjing 2f6c84c5f4 fix(i18n): localize browser history copy (#34609) 2026-10-27 16:19:03 -07:00
OrcaWinandOrcaWin 791502fae4 ci: move secondary, scheduled and contract workflows to GitHub-hosted runners (#34568)
* ci: move secondary, scheduled and contract workflows to GitHub-hosted runners

Public-repo standard hosted runners are free under Enterprise. Release, build,
benchmark, e2e and unit workflows stay on Blacksmith. ci-xterm-cache seeds both
cache stores since its PR consumer's pool is undecided.

* test(pi): resolve the smoke bundle's external packages from the repo

#34148 pulled zod into the commit-message planner graph; the bundle in the
OS temp dir could not resolve it on any runner.

* ci(unit): use four workers on the hosted four-core x64 runner

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 16:15:14 -07:00
OrcaWinandOrcaWin 70a6f7d184 test: remove 269 low-value cases and 26 suites (#34584)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 16:13:03 -07:00
NeilandWilliam Poisel 9a62614615 fix(cli): help lists only the flags each command actually takes (#34598)
* fix(cli): hide unsupported profile-state flags

* fix(cli): derive --page and remote-selector help from what each command takes

--page is now a property the browser spec modules set for commands that act on
one page, rather than offered to every command group not on a deny-list, so
serve, environment, agent, connector, host, vm and profile commands stop
advertising and accepting it. Local-only commands offer only --help and --json
plus a selector they take as their own argument, and a test ties their help to
the same local-only list dispatch uses.

Co-authored-by: William Poisel <53629276+epoisel@users.noreply.github.com>

---------

Co-authored-by: William Poisel <53629276+epoisel@users.noreply.github.com>
2026-10-27 16:06:49 -07:00
f4d98b74e3 ci: run hourly and daily dev builds on free hosted runners (#34585)
Hourly and daily builds publish unvetted dev channels on a schedule, so their
latency is not user-facing. Move the macOS build to hosted macos-15, the
Windows build to hosted windows-2022 (the release path), template
qualification to hosted lanes, and the small routing/publish jobs to
ubuntu-latest. Adhoc and release builds stay on Blacksmith.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-10-27 16:02:46 -07:00
Neil eb7f4d9c31 test(wsl-host): native chat on a WSL host through the fake transport, including a stopped distro (#34573)
* test(wsl-host): native chat on a WSL host through the fake transport, including a stopped distro

* test(wsl-host): type the chat spec's focus host id

* test(wsl-host): harden the WSL host chat spec and re-run fake-connector specs on change

* test(wsl-host): scope the chat reply check to the transcript and test the fake's route

Find the prompt only in the transcript so the composer can't stand in for it,
re-check the boot-free stop window after unfocusing, right before the focus,
give the fake's distros.json temp file its own name so it can't collide with the
spec's, and test that the fake connector routes to both WSL host specs.
2026-10-27 16:02:12 -07:00
Neil 5e49b6dd11 refactor: group native chat context usage (#34595) 2026-10-27 15:47:15 -07:00
Neil 5a29a68ffa test(wsl): find the chat lane's claude on the guest PATH, with a Windows-side decoy (#34551)
* test(wsl): find the chat lane's claude on the guest PATH, with a Windows-side decoy

* test(wsl): prove the Windows decoy is reachable before asserting it never ran; record probe errors
2026-10-27 15:40:15 -07:00
OrcaWinandOrcaWin 1864543ade ci: warm GitHub-hosted runner caches and drop the serve-switch installer cache (#34576)
* ci: warm hosted runner caches and drop the serve-switch installer cache

* ci: seed only restored caches from hosted warm legs

* docs(ci): hosted dev builds and no larger runners

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 15:33:07 -07:00
OrcaWinandOrcaWin 03d359749e ci: stop publishing the pnpm store from GitHub-hosted runners (#34588)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 15:32:51 -07:00
NeilandEotel c63b949604 fix(updater): accept the supervised serve's other spelling of its profile path (#34570)
* fix(updater): accept aliased supervised serve profile paths

* test(updater): cover the service's other casing of the serve profile path

Co-authored-by: Eotel <49769982+Eotel@users.noreply.github.com>

---------

Co-authored-by: eotel <49769982+Eotel@users.noreply.github.com>
2026-10-27 15:27:24 -07:00
Neil 1cabd0f952 Make context and tab menus compact and native-style (#34543)
* Make context and tab menus compact and native-style

Shared menu primitives get 13px/24px rows, inset separators, full-size
shortcuts, frosted translucency with solid fallbacks, and submenus that
level with their trigger. Tab menus keep only meaningful icons and align
the rest on one text column via inset.

* Keep launch menus and shortcut chips consistent with row text size

* Use the primitive label style in worktree menus
2026-10-27 15:23:25 -07:00
Jinwoo Hong 4e326e2371 Show Orca publishing guidance only when the host has it on (STA-12225) (#34547) 2026-10-27 18:20:40 -04:00
OrcaWinandOrcaWin 9cc555e2de ci: run off-critical-path PR jobs on free GitHub-hosted runners (#34566)
Keep preflight and the unit-test matrix (the PR critical path) on Blacksmith; move routing, aggregation, contract, packaging and mobile checks to hosted standard runners, which are free for public repos under Enterprise concurrency.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 15:19:23 -07:00
Neil f3adb8f85a refactor: group native chat work-run boundaries (#34528) 2026-10-27 15:18:29 -07:00
Kelvin Amoaba 941f4ece37 feat(mobile): support the iPhone Duo folded and unfolded, with controls in its side status bar (#34484) 2026-10-27 22:16:33 +00:00
ef21574a41 fix(sidebar): remove Claude subagent-view eye indicator (#34558)
* fix(sidebar): drop Claude subagent-view eye icon; badge viewed subagent only

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

* fix(sidebar): hide subagent-view indicator on collapsed rows too

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

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-10-27 15:16:02 -07:00
OrcaWinandOrcaWin 3058cdd1a8 ci(node-server): run PR and scheduled qualification on free hosted runners (#34560)
Only explicit fast_runners callers (manual, hourly/daily/adhoc builds) keep
Blacksmith; qualified-orcad-template's cache/save jobs always use ubuntu-latest.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 15:14:01 -07:00
Kelvin Amoaba 917ef9c737 feat(browser): install Chrome extensions from the Web Store into Orca's browser (#30940) 2026-10-27 22:04:12 +00:00
OrcaWinandOrcaWin c791ee2d98 test(wsl): stop the bash bridge flood test re-concatenating every chunk (#34524)
decode() collected payload chunks even when no payload was expected, and with
expected = 0 every data event ran Buffer.concat over all chunks so far. The
128 MB desktop-reads-slowly flood therefore copied quadratically: ~9 s idle under
bun, over 30 s under node or a loaded CI runner, timing the test out.
Collection now lives in received(), used only by the tests that check a payload.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 14:58:58 -07:00
Brennan Benson e225433c77 Lint: flag store selectors that subscribe to the whole host-status map (#34517)
* lint: flag whole host-status map selectors

* lint: keep whole host-status map findings advisory
2026-10-27 14:56:45 -07:00
Neil 84decfd2a2 feat(editor): VS Code markdown highlighting and sticky headings in source mode (#34537)
* feat(editor): VS Code markdown highlighting and sticky headings in source mode

* fix(editor): address review on markdown TextMate highlighting

- resolve fence grammars from the first word of the info string
- give fence grammars the cold-compile retry budget
- fall back to Monarch markdown when TextMate fails to load
- bound heading-scan line length
2026-10-27 14:46:30 -07:00
OrcaWinandOrcaWin 649dc1a6fb test: remove 113 low-value tests (#34541)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 14:45:01 -07:00
Neil 8fe31c930e feat(wsl): note why an idle distro stays held, and fail the holder's scan closed (#34534)
* feat(wsl): note why an idle distro stays held, and fail the holder's scan closed

When user work keeps the holder from releasing, it writes the first few process names (at
most 5) to ~/.orca/wsl-holder-blocked, replaced whole and cleared on release, for the desktop
to read later. A /proc without the holder's own entry, or a status file it cannot parse, now
keeps the hold instead of reading as idle.

* fix(wsl): count an unreadable /proc entry only when it is the user's own

Review of #34534: under hidepid=noaccess root's status files are unreadable, so each read as
this user's work and the distro never released. An unreadable entry now counts only when its
directory belongs to this user. The holder also clears a half-written note on start and
rewrites the note only when it changed.
2026-10-27 14:42:00 -07:00
OrcaWinandOrcaWin 7b8ca17c64 build(runtime): target Node 24 while retaining host compatibility (#34177)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 14:40:37 -07:00
Jinjing 54411a9a96 fix(chat): open chat name settings from naming failures (#34533)
* fix(chat): link naming failures to chat name settings

* fix(chat): hide naming settings link when controls are unavailable
2026-10-27 14:27:53 -07:00
OrcaWinandOrcaWin 9fd9cd7362 test: remove 260 low-value tests (#34535)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 14:24:21 -07:00
Brennan Benson 9510726341 Stop host status changes from rebuilding the sidebar workspace list (#34500)
* Stop unrelated host status publications rebuilding sidebar workspace state

* Follow sidebar selector lint conventions

* Scope sidebar status reads to mounted consumers

* Cover each unrelated sidebar status publication

* Fix sidebar isolation lint and formatting

* Type the composed sidebar header fixture without assertions

* Remove unused React imports from sidebar contract tests

* Reuse folder record selector and prune stale focus allowance
2026-10-27 14:15:30 -07:00
Jinjing a2b378018a Withhold virtual review tabs from mobile sessions (#34254) 2026-10-27 14:09:22 -07:00
Brennan Benson e71d4358c1 Native chat tabs can hand off work from their right-click menu (#34504)
* Add native chat hand-off menu on main

* Fix saved chat hand-off observations and RPC exports

* Reuse indexed chat tabs for hand-off subscriptions

* Match saved-chat clear fixture to current journal API
2026-10-27 14:06:57 -07:00