Subscriber delivery reads current work before the history page, then lets
that work restate unanswered sends over the page's rows. When a send's
settlement committed between the two reads, the page carried it accepted
but the earlier work restated it pending, so the frame at the new cursor
published the stale state. Later caught-up frames restate only still
unanswered sends, so the client never learned of the acceptance: the
Claude echo case kept a "pending" bubble although the journal held it
accepted. A restatement only describes sends its read saw unanswered, so
an accepted or rejected page row is newer and now wins.
structured-agent-session-claude-echo-working (failed once in CI, never
reproduced) with an 8 ms SQL reply delay injected locally plus CPU load:
before, most repeats stayed pending for 15 s while the stored row was
accepted at the subscriber's own cursor; after, 7/7 passed in ~100 ms.
Pageless agent commands prefer the workspace's active client page, and creating
an offscreen or renderer tab never cleared it, so the next command after
`orca tab create` acted on the user's page. Yield client selection wherever a
create moves the bridge's active tab, as orcad already does.
The idle sweep stopped any still-starting agent whose chat had been quiet past the idle window on
the wall clock, which counts sleep. A message sent just before the Mac slept was rejected on wake
as "Claude couldn't start". A start's own deadline already runs on awake time, so the sweep now
leaves a start alone while that deadline still times it.
The streamed pane's context menu opened the page or link URL as-is in
the desktop's default browser, so a server's localhost page opened this
machine's localhost. Use resolveRemoteFailureExternalUrl, as the
streamed error page already does, and leave the items out when it
refuses.
The desktop's screencast subscription dropped the stream's dialog and
dialogClosed events, so an alert, confirm or prompt on a Server
(streamed) page froze it with nothing to answer. Ask with the local
browser's dialog, answer through browser.dialogAccept/dialogDismiss,
and close it when the host closes the dialog or the stream stops.
Streamed (offscreen) pages only republished their session-tab row on commit,
in-page navigation, first favicon and load failure. A title parsed after
commit, a live document.title change and the end of a load never reached the
desktop tab strip or the phone, and the row hardcoded loading and back/forward
as false. Publish title and load-state changes through a per-page coalescer
and read real loading and history state into the row.
The button threw away activateBrowserPagePaletteResult's failure, so a
missing page, tab or workspace made it do nothing. It now shows the open-tab
switcher's messages, shared through one helper. A blocked activation stays
quiet like every other caller: the activation reports it.
Restarting after a mid-command exit runs the exit settlement, a fresh
acquire and the queued send's handover through the SQL workers before
turn/start, which outran vi.waitFor's 1 s poll under load. The shared fake
Codex now resolves nextRequest(method) when a child receives that request;
compact-exit awaits it instead of polling the calls list.
Seen once in a contended local sweep (8 ms SQL reply delay plus CPU load):
"expected [] to have a length of 1" at the turn/start poll. The new
version passed 5/5 under the same delay.
The single idle-sweep tick keeps a chat whose delivery loop is still
running, and the loop parks only after SQL reads that follow the second
send's completion event. When the tick ran first it touched the session
instead of retiring it, and the 1 s hasSession poll failed. Wait for the
loop to park (wake resolves when it does), as goal-steering does.
With an 8 ms SQL reply delay injected locally plus CPU load: old 2/5
failed (expected true to be false), new 5/5 passed.
* fix(mac): give Orca's main executable its own Mach-O UUID
macOS Local Network privacy identifies an app by its main executable's
UUID. The packaged executable is stock Electron's, so it shares that UUID
with every other app on the same Electron version and macOS can apply
another app's Local Network decision to Orca. Rewrite LC_UUID in every
slice to a value derived from the app id, executable name and CPU type,
before signing.
* fix(mac): re-sign rewritten executables ad hoc, cover the terminal host, assert UUIDs at release
Rewriting LC_UUID breaks Electron's linker ad hoc signature, and arm64
kills unsigned code, so identity-less local builds (where app signing is
skipped) produced an Orca.app that died at launch. Re-sign the rewritten
executable ad hoc, outside the bundle so codesign does not treat it as
the bundle; real signing replaces it later.
The terminal host's executable is a stock Node binary whose UUID is
shared by every copy of that Node release, so give it its own stable
UUID the same way. Packaging and release verification now fail when a
shipped executable does not carry its expected UUID.
* fix(mac): scope the executable UUID rewrite to the main app
The terminal host gets a separate design; leave it unchanged here.
* fix(explorer): resync a recovered remote watch only after the host watcher is installed
The contact-regained resync fired when the files.watch subscription was accepted, before the
restarted host reported its watcher ready, so a file created in that gap was neither in the
re-read listing nor reported by the watcher. The managed-orcad explorer recovery spec now waits
for that resync before writing its probe file.
* fix(explorer): re-read a recovered remote explorer once when its host watcher fails to install
* test(explorer): the recovered watch resyncs after its ready signal
* fix(explorer): re-read a remote watch on acceptance and again once its host watcher is installed
A recovered watch re-reads when the restarted host accepts it, so outage changes
still appear if the watcher install stays pending, and again on ready so writes
made before the install appear. A first subscription also re-reads on ready,
which replaces the trimmed-watch first-ready catch-up for remote targets.
* test(explorer): the recovered explorer shows a file written while the host watcher installs
Counting resyncs is not an install barrier: two recovery attempts can both
re-read on acceptance before any watcher exists, and a ready that lands before
acceptance re-reads once. Assert the user-visible result instead, which holds
for any order of acceptance, install and the write.
* fix(speech): spell near misses of dictionary terms the term's way
* fix(speech): ship the common-word list as a 2% Bloom filter to fit the phone page budget
A run without --page fell back to the chat's latest agent page whenever it
had no remembered page, which is every older run after a restart or once 500
runs push it out. The chat's browser activity now belongs only to its newest
browser run, which remembers that page for when a newer run takes over. An
older run that this renderer never saw as the newest shows no button.
Add an on-by-default Claude usage polling switch with live-terminal-only behavior when disabled, cancellation and account attribution safeguards, and translations for all supported locales.
Fixes#27151.
Fixes#39502.
Fixes#37037.
Co-authored-by: Sibyl <scauyb@qq.com>
* fix(opencode): attach @-mentioned files to OpenCode chat prompts
OpenCode's ACP agent reads a file only from a resource_link block and
ignores @path text, so mentioned files never reached the model. Keep
the text as typed and link each mentioned file inside the session
folder.
* fix(opencode): reuse the chat mention scanner and compare paths byte-exactly
* fix(opencode): leave mentioned files over 20 MiB as text
DeliveryOrder.reconcile became async when the first-queued read moved to the
SQL readers, but the ready-operation path still called it without awaiting
and reserved the operation's place right after. The operation then took its
place before the queued send it was meant to follow, so a goal, rewind or
other operation requested while the agent starts could run ahead of a
message sent earlier; a failed read also became an unhandled rejection.
Await it, restoring main's order (reconcile, then reserve).
Found by typescript/no-floating-promises over src/main/native-chat.
The operation-order cases polled a settled flag and the compact spy with
vi.waitFor's 1 s default. Under SQL worker contention the goal or rewind
answers after more than a second, so the poll gave up while the operation
was still on its way (CI: "expected false to be true", then "closed by
quit" from the unhandled result). Await the result itself and a promise the
compact stub resolves.
With a 30 ms SQL reply delay injected locally plus CPU load, 3 repeats: the
old file failed "releases a startup goal" (expected false to be true) and
"answers a goal" (compact called 0 times); the awaited version passed all.
* fix(ime): keep plain-committed Hangul so macOS 2-Set can rebuild it in place
Right after an input-source switch, macOS 2-Set can commit a lone jamo as
plain text and then rebuild it (ㅇ + ㅏ → 아) by replacing that committed
range. The native text forwarder emptied the field after every commit, so
the replacement had nothing to land on and the vowel was dropped (#9738).
Keep Hangul commits in the field (Latin commits still clear for #11504),
and erase replaced text from the PTY before the replacement is sent.
* fix(ime): only erase retained Hangul when the replacement is forwarded and still at the PTY cursor
Drop retention on blur, on any composition start, and on chord/named keydowns
the pane handles before the forwarder (macOS Ctrl+C, non-Latin control chords).
Erase only for insertText/composition replacements that end at the field tail.
* ci(e2e): route terminal IME changes to IME specs again after the input/ owner move
#39113 moved IME and keyboard policy files under terminal-pane/input/, but the
native IBus and synthetic IME routes still matched the old paths, so IME changes
selected neither lane.