* feat(mobile): define the on-device speech contract for the native audio module and page bridge
* feat(mobile): dictate on the phone first and replay to the computer when the phone fails
* refactor(mobile): type the on-device speech module without a cast
* fix(mobile): point dictation's finish ref at the committed callback
* test(mobile): wait on the takeover request instead of a fixed sleep
* fix(mobile): release each dictation request's own share of a replayed backlog
* fix(mobile): let the computer's text replace the phone's after a fallback
Adds oxc-transform-react as a devDependency and a ratchet that runs React
Compiler in analysis mode over the shipped renderer sources. Files can't gain
bailouts (new files must compile fully), and new code the compiler would run
differently is banned: hooks it memoizes into a cached block, bare `void x;`
reads, member postfix updates used as values, and "use no memo" opt-outs.
Both baselines are generated by --update / --prune.
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
* refactor(renderer): organize runtime clients and feature state owners
* fix(refactor): preserve incoming consumers and validation routing
* fix(refactor): consolidate defining-owner type imports
* perf(mobile): skip the Suspense fallback on page boot
* fix(mobile): keep open-target boots on the lazy path
* test(mobile): pin that the page waits for its held route chunk
* refactor(mobile): preload every page layout and keep screens apart
* feat(mobile): let pages read and write the device store
* fix(mobile): import zod as a namespace in the page store verb
The page bundle check rejects `import { z }`: it ships zod's locale tables.
* refactor: organize remaining terminal pane features by owner
* refactor(terminal): consolidate replay guard type imports
* refactor(terminal): retarget notification mocks and generated consumer import
* refactor(terminal): repair benchmark owner lookup and stale mock export
* perf(mobile): trim the page bundle back under its old budget
* build(mobile): simplify the route entry anchors and zod table guard
* fix(mobile): import zod as a type in the RPC result reader
* fix(packaging): require macOS 13.4, which the bundled speech engine needs
* fix(updater): keep the macOS requirement title clear of the close button
* fix(packaging): check out the Darwin floor table for adhoc builds and raise the cask floor
* refactor(updater): reuse the parsed Darwin floor for the macOS requirement
* fix(updater): use a margin to keep the macOS requirement title clear of the close button
* fix(updater): say the macOS requirement comes from Electron and the speech engine
ProseMirror reads a click's selection from the selectionchange event, which a
hidden Xvfb window delivers after Playwright's next step. The spec focused Find
right after clicking, so the editor still held an old selection when focus left,
and the Shift-click extended from the document start. Wait for that event after
the caret click and the range Shift-click; route Find sources to its specs.
Co-authored-by: Claude <noreply@anthropic.com>
* test(e2e): wait for the shell-ready deadline after a startup exec
Since #30978 the terminal host no longer probes for a prompt when a profile
exec drops Orca's ready marker; it submits the startup command once at the
15 s shell-ready deadline. The oracle allowed only 8 s, so the headless serve
case failed unless the exec barrier happened to run long. Wait until that
deadline (measured from terminal creation) plus the recovery budget, and
route the spec from the shell-ready barrier and shell startup sources.
* ci(e2e): route the startup-exec oracle helper to its spec
The spec forged an SSH owner for a local file and relied on the read
falling back to local transport. Since #31617 a tab reads only from its
captured owner, so the forged tab correctly shows 'Couldn't verify which
host owns this file'. Use a paired client that opens the same checkout
locally and on its runtime host instead, and route editor model identity
sources to the spec.
A link whose page is already open now reuses that tab (#32907), so the paged
preview's click of the same URL never added the second tab the spec counted.
Also route CSV viewer sources to the CSV specs.
permission dropdown, and fresh profiles keep OpenCode on its own settings, so
the agents without Auto read Mixed after Full access -> Approve for me. Assert
that, track OpenCode in the stored-permission checks, and route the spec on
permission settings sources.
Claude launches now get --plugin-dir prepended (subagent navigation, #33322),
so the stand-in read '--plugin-dir' as its marker path and the spec never saw
the detached child. Route the spec on descendant-kill and Claude launch-flag
sources.
Since #34683 a move journal promotes the WSL hosts gate to serve-only, so startup
recovery now runs and undoes a move interrupted before blobs-transferred. The
spec restarted at source-fenced and expected the fence to survive; assert the
undo there, fence from blobs-transferred, and expect the committed refusal to
name the host (#34880). Route fence and recovery sources to the spec.
Co-authored-by: Claude <noreply@anthropic.com>
Terminal padding now insets the bottom edge too (#36789), so the terminal sits
paddingY above the pane bottom. Route pane geometry sources to the spec.
The one-time 'This page renders on your desktop' tour opens beside the address
bar of the first client-hosted page and intercepts clicks on the address-bar
suggestion. Seed it as seen for this spec via a new paired-client launch
option, and route address-bar conversion sources to the spec.
Since #31080 a client keeps one saved entry per server, so pairing the same
host a second time under another name is refused. The steady 'Direct host' is
now a different server than the interrupted one. Tooltip checks name the host
so a closing tooltip from the previous card cannot match. Route the spec from
its pairing-store and runtime-status sources.
Board drops send wakeWslDistro (#36230) and network failures toast localized
copy (#34621). Route GitHub Projects sources to the board spec so PRs run it.
Since #33622 a confirmed HTML preview link honors openLinksInApp (default off,
so it opens the system browser) and no longer calls
openBrowserProfileTabInActiveWorkspace, so the spec's store spy never fired.
Opt the client into in-app links and observe the opened page URL directly.
Route doc-preview sources to the spec.
Orca already drops protected strings when it loads a language pack and keeps
its own English text for trust, permission and destructive dialogs.
validate:plugin and orca plugin validate still rejected the whole pack, so the
community directory refused otherwise-good packs. They now report how many
protected strings are ignored as a warning; every other pack rule stays strict.
* test: stop unit tests from running the developer's real agent CLIs
A live relay test reached the host's real `claude --version` through the
inherited PATH. On a machine whose claude wrapper never exits, each run left
an orphaned loop behind (14 were found on one host, running for days).
- Add a unit-test setup guard that shadows agent CLI names on PATH with
stand-ins that fail the test which ran them.
- Give the live relay test its own claude/codex stubs.
- Kill the whole process tree when the WSL guest's version probe times out.
* test: keep structured-session tests off the real codex CLI
These hosts get a scripted transport, but the at-rest `/` command read
spawns the resolved codex command directly, so on a machine with codex
installed each run started a real `codex app-server`. Point them at a
missing binary, as on CI.
* test: isolate agent discovery in session fixtures
#38014 deleted tests/e2e/voice-microphone-selection.spec.ts but the feature-area
route still selects it, so every PR touching dictation or src/main/speech fails
'changed e2e specs' with 'No such file or directory'.
* perf(mobile): stop live input and keyboard height re-rendering the whole session
* refactor(mobile): drop the web soft-keyboard state hook nothing reads
* refactor(mobile): read the session keyboard lift from the shared occlusion hook
* test(mobile): give the command dock render probe a live input store
* test(mobile): give the review note test a query client
* build(mobile): raise the page code budget to 9.75 MiB
* build(mobile): re-measure the page chunk sweep after the speed batch
* test(runtime): follow the terminal RPC module move in the output credit test
* feat(mobile): let the host page open a target inside its own document
* fix(mobile): skip a duplicate open, re-render the stack only for a waiting route
* fix(mobile): resolve the open target through Expo and open a target that changed before mount
* test(mobile): keep Back in one open-target case
* refactor(mobile): hold routes under the top with one released flag
* refactor(mobile): own the navigator ready listener in the effect
* fix(mobile): leave single-route stacks drawn from the start
* refactor: group structured session modules by owner
* test: retire status history work-count oracle suite
* refactor(main): organize journal storage and projection owners
* Consolidate restart recovery fixture imports
* Consolidate concrete session option model imports
* feat(chat): shared contract for forking a chat from a response
Adds the create-time fork source, the host fork capability, the agent fork
level, the forked-from record relationship and the forked-from divider row.
* feat(chat): advertise each agent's fork level and a chat's fork support
* feat(chat): carry a fork source through chat launch, reload and retry
A launch with forkFrom {sessionId, throughItemId} keeps it on the create call,
the saved launch record, reload, retry and its holders, sends no new-chat
options, and is refused before create on a host that does not advertise forks.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* feat(chat): fork a native chat from a finished response on desktop
Finished root responses offer "Fork from this response" where the host and
agent can fork: disabled while support is unknown or a fork is opening, opened
in a new tab right after the source, with one toast naming the agent on
failure. The forked-from row draws as a divider linking to its source.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* feat(mobile): fork a chat from a response in the message actions sheet
The sheet offers "Fork from this response" with the desktop's eligibility and
host capability, creates the fork through the phone's chat create, and draws
the forked-from divider with a link to the source chat.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* feat(chat): a fork create replays only as the same fork
* Add native conversation copy adapters
* Create native chat forks with derived source markers
* fix(chat): offer a fork only on rows that show the agent's own message
A displayed row can be a tool call or a status projected as a plan while
reading as a response; both clients now check the journal row's own kind.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(chat): open phone and paired-desktop forks right after their source
The phone names its source tab as the create's placement and the host takes
that tab's group; a paired desktop sends the address captured at the click
when the fork has no tab of its own yet.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(chat): float a mid-turn response's fork action instead of adding a line
The action on a response the turn continues past hangs from a line of no
height, as the reply controls hang into the gap, so tool-heavy turns keep
their spacing.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(chat): follow the chat's own fork verdict on both clients
The options read already says whether the installed agent forks; an observed
no hides the action, an unanswered read keeps it disabled, and yes enables it.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Preserve native copy boundaries and rewind behavior
* Preserve imported fork tips and serialize create replays
* fix(mobile): open a fork's source through the session's own chat opener
The forked-from link now asks the controller's existing opener for the source
by history id, so it follows that opener's host, selection and reveal rules
instead of navigating on its own.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Project fork markers from touched journal groups
* Retain fork group restoration for delayed readers
* fix(chat): keep a mid-turn response's fork in its own right gutter
The floated action covered the start of the next row. It now sits beside the
response's last line, in a gutter as tall as the prose, so it adds no line and
never reaches the following row.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Preserve native fork chain boundaries and durable streamed copies
* Place phone forks beside their source in window publications
* fix(tabs): adopt a host's new tab where the host placed it
First adoption put every unseen tab at the end of its group, so a fork the host
published after its source landed last. A new tab now follows its nearest host
predecessor when that tab is here; tabs already adopted keep the user's order.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(chat): reserve the fork gutter on every root response from the first frame
The gutter came and went with the fork offer, so prose reflowed when a turn
finished or support resolved. A pane that draws forks now keeps it on all root
responses, and the fork sits only there, not also beside Copy.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Return Codex copies without automatic provider renaming
* Resolve chat placement once at the current layout owner
* Preserve chat publication when saved opens are skipped
* Retry chat opens when queued placement changes
* Bound stale chat placement retries
* test: expect the OpenCode reader's imported fork tip
* perf(chat): keep the fork offer stable while a chat streams
Every stream commit made a new forkable-id set, so the fork context changed and
every offered response re-rendered. The set is reused while its members hold,
and rows get an action object that changes only with support or pending.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix: keep the fork params and Claude fork worker inside main's new lint limits
* Test fork copy and source refresh scaling
* fix: merge duplicate imports and stringify the OpenCode fork tip id for main's lint rules
* Keep fork placement behind session tab projection boundaries
* test: annotate the Claude copy test's hoisted account homes instead of asserting
* fix: add the fork action and forked-from strings to the English catalogs
* test: give fixtures the fork copy their agents declare; add the forked-from string to the boot catalog
* test: keep registry fixtures consistent with the fork copy their agents declare
* fix(orcad): ship the Claude fork worker with the server; update tests for fork fields
* Test saved fork selections through import and first send
* Preserve ordinary chat publication while saving placement
* Show fork beside the copy button on phone chat responses
Long-press opens text selection on every current phone, so the actions sheet that held fork never opened. The fork button now sits next to each response's copy button.
* Keep the phone fork slot fixed and offer it on every forkable response
The fork slot is now held by the row's own kind, as desktop's gutter is, so finishing a turn or learning the host's support never moves the timestamp. Responses with no copyable text (a visual only) still get fork, and each button re-renders only when its own offer changes.
* Follow main's moved runtime modules in fork code and tests
* test: build the phone response-actions fixture without type casts
* Let the phone read the host's agents so its fork action can turn on
Phone QA found the fork button always disabled: the phone asks the host which agents can fork, and the host refused that read from paired phones.
* Retry the phone's agent-list read, and read again after a reconnect
A read lost to a dropped connection or a timeout left Fork disabled until the chat was reopened.
* Own the phone's agent-list retry timer in its own effect
CI's effect-cleanup check could not see a timer set inside the read's callback; each retry is now a state change with an effect that sets and clears one timer.
* Give each phone connection its own agent-list retries
A count left over from an earlier connection could leave a new one with no retries, so one failed read kept Fork disabled after the transport moved.
* Scope the phone's agent-list retries to each spell of discovery
When the host's fork support dropped and came back on the same connection, the earlier failures carried over, so one more failure got no retry. Each stretch of discovery now owns its reads, failures and retry timer.
* Keep the forked-from source link reachable by screen readers
The divider's separator role and row label hid the source chat button inside it; the rules are now decorative and the text and button read normally.
* Keep fork names owned by adopted chat records
* Use the fork icon for Fork from this response
* Show the phone meta actions only when a row has one
An empty actions group still shifted the time by the icons' edge margin on rows with no copy, fork or rewind.
* fix(chat): put Fork beside Copy in the response's hover row
The fork button sat alone in a right gutter far from the other row actions.
It now joins the response's existing hover controls next to Copy, where those
controls show, and the gutter is gone.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(chat): keep a finished turn's actions on its last words and hold the Fork slot
A turn whose last prose was followed by tool or thought rows showed no Copy
and no Fork anywhere until it was collapsed. The actions now belong to the
turn's last prose row, decided when the transcript's rows are built, and keep
the gap below it whole so they never cover the next row. Root responses also
keep an empty Fork slot when not offered, so resolving support never moves
the row's other actions.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(chat): give a turn's actions only to a reply with words
An image-only reply after the turn's text took the response actions but could
not draw them, so the text lost Copy and Fork. Slot construction now picks the
turn's last reply by the same words the row draws and copies.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(chat): let an image-only response hold a turn's actions when its text is folded
A collapsed turn that ends in an image hides its earlier text, so no drawn row
could show the response actions and Fork vanished. Each turn's actions now go
to its last drawn response with words, else its last with images. Copy and its
context-menu target appear only where there are words to copy.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix Claude fork cuts after local commands
* Extract the conversation copy input contract
* Preserve caller results at Claude fork boundaries
* test: check the copied fork for the wake answer without a type assertion
---------
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>