Skip to content

[upstream #36200] fix(daemon): adopt a terminal host that comes up after startup fell back to in-process PTYs - #347

Open
innocarpe wants to merge 10000 commits into
mainfrom
daemon-late-host-adoption
Open

innocarpe wants to merge 10000 commits into
mainfrom
daemon-late-host-adoption

Conversation

@innocarpe

Copy link
Copy Markdown
Owner

Portfolio mirror of my contribution to upstream stablyai/orca.
Exhibition only — the real review/merge target is upstream.

Upstream

Summary

ELI5 If the background terminal host is late when Orca starts, Orca runs terminals inside the app so you can keep working. Until now it never switched back, so every terminal of that launch was lost on the next quit or update, even after the host came up seconds later. Now Or

Note

  • Do not merge this into innocarpe/orca main until the upstream PR is merged.
  • After upstream merges: sync fork from upstream, then close this mirror PR.
  • This open PR exists so visitors see in-flight work on this fork's Pull requests tab.

nwparker and others added 30 commits October 29, 2026 02:38
…stablyai#35761)

Warm start (an app relaunch or reconnect with the distro and orcad
running) to first terminal output is the flag-on gate at 2.5 s p50; cold
start (distro restart) is tracked against 3.0 s p50. Five warm reconnects
follow the cold runs, and the receipt reports n, p50 and p90 of first
output, ensure, create and send-to-output for each, with the runs.
… cannot write into an outer repo (stablyai#35859)

* test: clear inherited GIT_* env once per test file so real-Git suites cannot write into an outer repo

* test: clear only repo-locating Git env so the compat lane keeps GIT_EXEC_PATH
…i#35882)

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…wn act (stablyai#35854)

* fix(wsl): Commits history wakes a stopped distro only on the user's own act

Showing Commits woke the distro on every mount, remount and re-show. Now
only the user expanding Commits in the same worktree, or the user's own
switch to the workspace (once per switch), may start it; the Refresh
button keeps its explicit wake (E9).

* test: a mount and a base-ref move read Commits history in the background

stablyai#35778's base-move refetch test expected every shown-history read to
wake a stopped WSL distro; only the user's own act does now.
…stopped distro (E9) (stablyai#35827)

* fix(wsl): Codex WSL hook installs and host hook checks never start a stopped distro (E9)

(a) installManagedHooksIntoWslRuntime checks the settled running gate inside
its trust queue right before the first UNC read, and again before the
post-hash fallback trust write; a later reconcile checks before revoking or
reinstalling. A stopped or unverifiable distro skips (null, as with no WSL
plan). The canonical-path probe runs through process-host behind
blockedWslDistroForExec; a refused probe settles as unavailable and keeps the
known identity. The guest shell preflight and a pane launch's home preparation
run as user acts on their distro.

(b) repo.hooksCheck takes an optional background flag (older hosts ignore it);
the renderer sends it, and the host refuses a stopped distro's background
check the same way the desktop's hooks:check does.

* fix(wsl): a pane launch is not a user act for the Codex hook install

A passive restore or remount reaches launch preparation too (stablyai#35813), so it no
longer runs as a user act; a stopped distro skips the install and the relay
installs once the distro runs. A skipped WSL home now returns not_installed
instead of falling through to the host writer, which would have written the
WSL home over UNC.

* fix(wsl): a fallback grant skipped mid-install reports trust pending

hooks.json is written before the hash wait, so a skip after it is not a clean
skip: return an error status saying the trust is pending instead of null.

* chore: drop the stale process-host direct-import baseline entry
…tablyai#35799)

* fix(windows): start the WSL holder with only a NUL handle to inherit

libuv starts every Windows child with bInheritHandles=TRUE and no handle
list, so a detached holder that outlives Orca kept any inheritable handle
Orca had open, such as a launcher's pipe or a DevTools socket. Start it
through CreateProcessW with PROC_THREAD_ATTRIBUTE_HANDLE_LIST naming one NUL
handle for its stdio. The build probes now check the newest export without
calling it, and the lane receipt labels ConPTY's own startup output.

* fix(windows): report isolated holder exits and kills the way libuv does
…ai#35890)

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…tore (stablyai#35889)

When a host restart restores a pane by starting a new shell, the pane kept
the dead process's title and the client's xterm kept its input modes. A
pane that had Claude open came back as bash but still read as Claude, so
the reattach picked the agent-preserving reset and mouse moves and focus
changes were typed into the shell as escape codes.

Two process-bound facts now follow the respawn verdict:

- Title: the cold-restore payload no longer carries the checkpoint's last
  title into the new process's records, and durable checkpoints of the new
  process take the title from the live terminal only. The title, agent
  identity and title-derived status reflect the new shell.
- Input modes: a pane records which process incarnation its xterm's modes
  belong to. When the host binds a different known incarnation, the pane
  grounds the process boundary before the new process's replay, the same
  ground a fresh spawn already writes, so only modes the new process set
  are armed.

Older servers still report incarnations, so new clients ground their modes
against them; older clients get the neutral title from new servers and
take the shell reset path.

Fixes stablyai#35559
…ablyai#35893)

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…hile recent (stablyai#35897)

The explorer's workspace-open read and the first git status took a pending
user switch with no age limit, so a switch no consumer used (sidebar closed)
could be redeemed long after the distro stopped. They now use the same 10 s
window as pane restore and git history, through one shared
takeRecentWorkspaceSwitchWake.
…provider spawns (stablyai#35895)

The passive-restore hold lived in the daemon adapter, so a degraded or
off daemon (LocalPtyProvider) never applied it, and even with the daemon
the startup cwd probe (wsl.exe --exec test -d) ran first and could boot
the distro. The hold now runs in the shared startup-target resolution,
before that probe and before any provider spawns (E9).
…ath (stablyai#35899)

A background read of a \\wsl.localhost folder workspace's status (sidebar
polling, runtime status RPC, a passive terminal restore) stat'ed the folder
and booted its stopped distro. The status now reports 'unavailable' without
touching it; a passive restore holds with Start; a spawn the user asked for
checks the folder as their act, which may start the distro as before.
…e is rejected (stablyai#35791)

When a structured worker's dispatch preamble is definitively rejected, the
dispatch_preamble_undelivered error now appends the provider's failure detail
("Details: ...") unless the rejection sentence already quotes it. The quoted
text is bounded and normalized by the same quotedProviderDetail helper the
rejection writer uses.

Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
…st window (stablyai#35798)

Requiring posthog-node at bundle evaluation and constructing the PostHog
client in initTelemetry put ~58ms on the main-process startup path before
any window showed. The SDK is now required lazily inside
createPostHogClient, and initTelemetry defers client creation until the
first window is shown (15s fallback for headless serve / GPU failures).

Captures tracked before the client starts are held with their original
timestamps and replayed in order on start. Opt-out and shutdown start the
client first so held events flush and telemetry_opted_out still enqueues
before optOut(); a client start failure no longer blocks either path.

Fixes stablyai#35752

Co-authored-by: Neil <neil@stably.ai>
…d hosts (stablyai#35900)

- A blur with no edit saves nothing, so it never starts a stopped distro.
- The write gate also covers a host-path repo whose Git runs in WSL (its
  save's ignore check); clearing runs no Git and stays lazy.
- A paired host's refused read is re-asked on focus and every 30 s while
  visible, through a watchRefusedWslRead extracted from the base-ref
  watcher, which now uses it too.
…il Start (stablyai#35864)

* fix(wsl-host): a chat holds Send while its WSL distro is stopped, until Start

* test(wsl-host): find the held Send by the reason it waits
…start a stopped distro (stablyai#35885)

* fix(wsl): Source Control's PR push-target and Create PR checks never start a stopped distro

Showing Source Control resolved the linked PR's push target
(worktrees:resolvePrBase) and its Create PR eligibility
(hostedReview:getCreationEligibility); both read the repo's git config over
\\wsl.localhost and ran git and gh in the distro, starting a stopped one
(E9). Both now refuse a stopped distro unless the user is creating or
launching from the PR, or pressed Create PR (optional wakeWslDistro), in
the IPC handlers and their runtime twins.

* fix(wsl): gate the GitLab MR push-target lookup the same way

Source Control's push-target ensure also resolves a linked GitLab MR
(worktrees:resolveMrBase / worktree.resolveMrBase), which read the repo and
ran glab and git in a stopped distro. It now refuses unless the user is
creating from the MR, which passes wakeWslDistro.

* test(runtime): let the mocked running gate cover guardWslUncPathAccess too

Runtime specs fake win32 with no wsl.exe and mock blockedWslDistroForPath
to running; the real guard calls its own module's check, so the PR-base,
MR-base and eligibility gates refused there. The guard mock now asks the
mocked check, keeping per-test overrides working.
…ce root (stablyai#35907)

The workspace port scanner resolves each workspace root's realpath to match
listening ports; for a \\wsl.localhost root that 9P touch started a stopped
distro about 17 s after it was terminated (E9). It now leaves a stopped
root's alias unknown, as a timed-out lookup does, and never wakes.
…tablyai#35857)

* fix(automations): a scheduled run never starts a stopped WSL distro

Scheduled runs whose target is on a stopped (or unverifiable) WSL distro skip with a coded, retryable wslDistroStopped reason naming the distro, checked at the tick and again at dispatch; repeated ticks fold into one skip. Run now is the user's act and still starts it.

* fix(automations): gate host-path WSL projects by their distro; translate the skip

A host-path project whose Git runs in WSL passes its project distro to the stopped-distro check (as stablyai#35778 does). wslDistroStopped is translated into the 10 other locales.
… distro (stablyai#35865)

* fix(wsl): main's background terminal starts never start a stopped WSL distro

Every start main makes through the runtime controller is background work unless its caller names the user's act (CLI and window creates and splits, paired-client creates and tab opens, agent launches and sessions, conversation resumes). stablyai#35813's hold now also holds those fresh and restored starts while the distro is stopped or unverifiable.

* fix(wsl): headless Run now starts as the user's act; update create expectations

A headless automation's Run now names the user's act through launchAgentTerminal, so it may start a stopped WSL distro; a scheduled run stays background and is held. The paired-client background create expectation now includes wslUserAct.

* fix(wsl): main's background start checks a folder workspace's path passively

With stablyai#35899's folder stat gate, the runtime preflight passes passiveWslRestore = !wslUserAct, so a background start never stats a stopped distro's folder as a user act before the daemon hold.
…roke (stablyai#35913)

* perf(native-chat): stop re-rendering composer controls on every keystroke (stablyai#35836)

Each keystroke (and each IME compositionupdate) re-rendered the composer's
action bar and TipTap editor, which re-applied editor options and re-decorated
the view, even though neither had changed. The draft store also gave each write
a fresh image-row array, which invalidated every image consumer.

Memoize NativeChatComposerActions and NativeChatPromptEditor (initialValue only
seeds the editor at mount), pass them stable handlers that call the latest
committed closure, and keep the stored image row's identity when it's unchanged.
Draft-store writes, onDraftChange and every consumer still see each edit
synchronously, so composition semantics are unchanged.

CDP-simulated pinyin IME, 4x CPU throttle, median per compositionupdate:
14.5ms -> 6.8ms (PTY composer), 14.3ms -> 7.2ms (structured composer).

* chore(native-chat): note the prompt editor memo's stable-props contract
…summaries, filter counts, automations) (stablyai#35914)

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…predates --effort (stablyai#35878)

* fix(claude): resume a chat with a saved effort on a Claude Code that predates --effort

A chat resumed with its saved effort always launched Claude with --effort,
which Claude Code before 2.1.38 rejects as an unknown option, so the chat
could never start again. New chats carry no saved effort and started fine.

Gate effort on the CLI version facts Orca already probes for
--thinking-display and --plugin-dir, which now answer supported,
unsupported or unknown. A chat with a saved effort waits out the version
probe and puts --effort on the command line only where the CLI has it.
Live effort and Fast changes use a control request Claude Code before
2.1.50 never answers, so on those CLIs saved choices stay saved but are not
sent, the chat offers no effort or Fast choice, and a live change is
refused at once instead of after a 30 second wait. Unknown versions keep
today's behavior.

Fixes stablyai#34795

* test(claude): give the scripted runtime a current Claude Code's flag support

Production always passes flag support, so a runtime without it now reads
as a CLI whose version is unknown and keeps saved effort off the command
line. The scripted CLI stands for a current Claude Code, so name its
version and keep its saved choices on the launch.

Refs stablyai#34795
Every value import of ssh2 sat on the main-process startup graph, so
Electron paid for loading ssh2 before any window even when no SSH host
is configured. Route all runtime ssh2 access through a lazy loadSsh2(),
define the BaseAgent subclasses on first use, and read ssh2's default
host-key algorithm list on first connect instead of at module load.

Profiles with saved SSH targets still load ssh2 during startup, right
after the profile store loads and before any window or reconnect, so
SSH users keep the old timing. A failed eager load is logged and
surfaces at connect instead of aborting startup. Profiles without SSH
targets never load ssh2 until first use.

An oxlint no-restricted-imports entry rejects value imports of ssh2
outside tests, and a guard test imports the SSH connection graph to
prove ssh2 stays unloaded. SSH suites mock the loader seam instead of
the ssh2 package, so no global vitest setup is needed.

Fixes stablyai#35731

Co-authored-by: Chad Tolkien <chad@sodadigital.com.au>
stablyai#35923)

- Commit-message generation keeps the host's optional errorCode, errorParams and
  errorDetail and translates every known text-generation code, matching desktop's
  rules: unknown codes, older hosts or missing values show the host's English
- Background tasks, subagent groups, the model label and agent-session write
  notices use localized mobile adapters instead of the shared English sayers

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…le (stablyai#35920)

After a serve restart where the daemon survives, a paired client could
drop mouse and focus reporting for a still-live agent. The host publishes
the pane with its tab-default title until it seeds the daemon's live title
about 180 ms later. A reattach image replayed inside that window was judged
against the default title, read as a plain normal-buffer program, and got
the reset that disarms its modes, though the image itself carried them.

The snapshot now carries the host's tracked title when the image was taken,
as an additive `lastTitle` field in the snapshot info, gated on the image's
seq. Every reset that judges a replayed image as a live agent's (the
post-replay reset, the focus-in that follows it, the hidden-restore reset,
and the model-snapshot reattach) uses that title when present, so the
decision describes the same moment as the replayed bytes. Local Electron
model snapshots already carried this title and now use it the same way. The reattach policy itself is
unchanged: non-agent normal-buffer panes still shed modes a dead child may
have left (stablyai#7329, stablyai#7893).

Older hosts omit the field and clients fall back to the published title.
Older clients ignore it.

Refs stablyai#35559
…tro (E9) (stablyai#35858)

* fix(wsl): a passive restore's env prep never starts a stopped WSL distro (E9)

resolvePtySpawnHostEnv runs before stablyai#35813's hold. Every spawn but a passive
restore now runs its prep as a user act on its distro, so explicit launches
are unchanged. prepareForCodexLaunchAsync checks blockedWslDistroForExec once
for WSL targets and, when blocked, skips the guest-home probe, the legacy auth
drain, the config and instructions sync and the session bridge, returning the
home without probing. When not blocked, the home is warmed with getWslHomeAsync
so the sync reads hit the cache instead of a 5 s wsl.exe. The state-DB
recovery and the explicit plugin readiness wait are gated the same way.

* fix(wsl): only a launch someone asked for acts on its distro; gate the relay start

A passive restore or a non-WSL launch never runs as a user act, not even on
the default distro (a null distro resolved to the default before). The
daemon-off local provider applies the same rule, receiving wslPassiveRestore
from the spawn options. Starting the hook relay (ensureForDistro from every
WSL spawn's env build) now checks blockedForExec before the state check, so a
passive restore on a stopped distro starts no relay.
…stablyai#35927)

The renderer maps main's terminal_held_wsl_distro_stopped start failure to stablyai#35813's shared stopped card; its Start calls layout.startWslHeldPanes, which starts each pane through ensureRestoredPaneStarted as the user's act.
…ck (stablyai#35936)

The same-process serve restart step relied on timing to land the reattach
replay inside the window where the host still publishes the tab-default
title, which happened about one run in five. Pin the client's published
pane title to the tab default and clear its pane status for the duration
of the restart, so the replayed image's own title alone must prove the
live agent. The check fails 3/3 without stablyai#35920 and passes with it.

Refs stablyai#35559
…te starts its own terminals (stablyai#35935)

RPC errors for a terminal held on a stopped or unchecked WSL distro keep runtime_error but carry a readable message and the hold in data. A headless launch the runtime held records the coded wslDistroStopped skip. A worktree create someone asked for (UI, CLI, agent, paired client) starts its setup and default terminals as their act; an automation's create stays background.
OrcaWin and others added 29 commits October 29, 2026 17:18
…ders (stablyai#35743)

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…ablyai#34980)

* fix(editor): give the emoji picker dismissal and app theme behavior

Move the slash-command emoji picker onto the shared Popover so Escape and
outside clicks dismiss it, follow the app theme instead of the OS theme,
name the dialog for assistive tools, and close it when its editor is hidden
so the portaled picker cannot float over another tab or workspace.

* fix(editor): dismiss emoji picker when its workspace is hidden but still painted

Extract the link bubble's ancestor visibility check (opacity-0, inert, aria-hidden,
hidden, display/visibility) into editor-anchor-visibility.ts and reuse it, with an
ancestor MutationObserver, for the portaled emoji picker.

* fix(editor): read latest dismiss callback via useEffectEvent instead of render-time ref write

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
stablyai#34992)

* fix(editor): keep keyboard completion results visible

* fix(editor): keep completion menus placed and keyboard results visible

* fix(editor): restore link bubble anchor and keep completion menus tied to their editor

Restore the link bubble's required anchorElement, keep editor clicks and
refocus from dismissing completion menus (selection sync still governs),
close them when the editor is hidden, and cover keyboard scrolling and
outside dismissal.

* fix(editor): share stablyai#34980's editor-visibility dismissal so completion menus close when their workspace is hidden but painted

* fix(editor): read latest dismiss callback via useEffectEvent instead of render-time ref write

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
* Add quick access to Plugins settings

* Forward Plugins shortcut from guest pages and show keycap hint
…ll-state filter, category chips and trusted-code access copy (stablyai#36100)

* Plugins settings: one list with an Installed badge, inline switch and install-state filter

* test(plugins): drive card enablement through the inline switch

* plugins: keep the installed-read error on Not installed; cover installed cards past the cap

* plugins: inline category filter chips with icons from one category-icon module

* plugins: single-select category chips, marketing icon table, Remote/VMs label, trusted-code access copy

* plugins: Not installed waits for the installed-plugin read

* ci: retrigger
…66) (stablyai#36145)

Catch-up pages called the native ledger once per dismissal, each call
re-reading, encoding and writing the full 24h UserDefaults ledger. A new
rememberAll bridge merges a whole page in one locked read/encode/write with
identical semantics (max seq per identity, refreshed 24h expiry).
…ding the paste (stablyai#35625)

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…own edits (stablyai#35056)

* fix(mobile): preserve literal code through rich Markdown edits

* fix(mobile): preserve inline code containing backticks

* Preserve adjacent inline-code text when saving mobile Markdown

* Preserve quote paragraphs and blocks in mobile Markdown

* fix(mobile): preserve selected text when creating code blocks

* test(mobile): choose native history shortcut from browser host

* Preserve paragraph-owned mobile code blocks when saving

* Preserve code selected inside mobile headings after saving

* fix(mobile): keep code serialization space-normalized and trim review tests

- Inline code and code blocks keep turning browser-created NBSPs into spaces;
  only the reader-side entity fix is needed for literal code.
- Inline code line breaks save as spaces so table rows and headings stay intact.
- Code blocks keep trimming trailing newlines left by placeholder <br>s.
- Heading- and paragraph-owned code blocks join adjacent inline code runs.
- Empty nested quotes reopen as a plain empty paragraph.
- Trim synthetic and behavior-locking tests.

* fix(mobile): keep quoted text literal when block reading would rewrite it

Quoted list continuations and lazy lines were restructured on save because the list reader drops them; reopen quote blocks only when they save the source or the same bytes as the literal paragraph.

* test(mobile): use template literal for saved code-block markdown

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…, tight continuations, bare markers) (stablyai#35187)

* fix(editor): preserve sibling tasks beneath ordered list items

* fix(editor): preserve wrapped inline markup in task items

* fix(editor): keep nested task continuations valid and editable

* fix(editor): keep literal task markers out of mixed checklists

* fix(editor): apply review fixes to task-list parsing stack

- Trim synthetic test matrices to the behavioral cases
- Regenerate pnpm-lock (drops a stale github-slugger importer entry)
- Assert the plain bullet's node type under an ordered parent

* fix(editor): keep one-column-deeper ordered tasks as sibling checkboxes

Dedent an ordered item's task block by the first task's column instead of
keeping its leading whitespace. A task one column deeper stays a sibling
checkbox, and text at or within the first task's column stays nested as
before. Strip leftover paragraph indent from task children.

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…ablyai#36142)

* fix(native-chat): keep chats stopped by a delivered kill readable after a downgrade

v1.4.244 accepts only three death kinds and sets aside any other record,
so a chat Stop force-killed (exit never observed) vanished after a
downgrade. Store the delivered kill as the absent pid an older build's
restart probe would itself record, plus an exact marker this build reads
back; in-memory code still sees kill-delivered.

* test(native-chat): explain release-checkout timeout

* test(native-chat): cover downgrade recovery and workspace rekeying

* test(native-chat): preserve checked record types at test boundaries
…lyai#35176)

* fix(editor): preserve trailing mixed-list items when outdenting

* fix(editor): keep ordered numbering for trailing items moved by outdent

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…i#36175)

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…-wait mean (stablyai#36181)

The Asia drain and departing-redial runs asserted a 20ms-sampled mean of lock-waiting director
backends under 0.5; it flaked at 0.56 and 0.57 on loaded runners. A focused test now holds the
source cell row and proves a reconnect placement still lands on a target (and that holding the
target rows does block one); the load runs keep their outcome assertions and report the mean.
…i#36168)

The cards are read by the user, not the agent, so 'your coordinator' read as if addressed to the agent.
…ok paths (STA-3786) (stablyai#36152)

A host-native hook path proves the agent ran on the host, so the 5s
session-ID fallback no longer walks every running distro's roots over 9P
while the transcript is unflushed. Mirrors the existing guest-hook-path rule.
…de blocks through rich Markdown saves (stablyai#35259)

* fix(mobile): keep table-cell and list-item line breaks on their own source line

Table cells and list items save line breaks as <br /> (and sibling P/DIV
blocks inside an item as breaks), and reopen attribute-free <br> tokens
as breaks, so Shift+Enter or Enter no longer splits a row or ends a list.
Typed '<br>' text gets only its '<' entity-escaped, raw text newlines
become spaces, and browser caret placeholder breaks are dropped (a cell
that holds only a placeholder saves empty; a cleared item keeps a <br />
so its marker still parses).

* fix(mobile): keep fenced code blocks inside Markdown list items

Indented fences under a list item (README steps such as
'1. Install:' followed by an indented bash fence) now read as a code
block inside the item and save back under the item's continuation
indent. Only items whose continuation holds a fence change; headings,
quotes, rules and tables after the fence end the item and read as
before. Top-level and list code blocks share one PRE writer, blank
separator lines are not indented, and a fence needs no blank line
beside it so tight items stay tight.

* fix(mobile): keep caret code blocks out of the paragraph they follow

Code block with a collapsed caret after text in its block ran native
insertHTML, which merged the PRE into that paragraph as prose. Prepend
a <br> only when content precedes the caret, so block-start, empty-line
and empty-document insertions stay as they were.

* fix(mobile): keep authored runs of trailing table-cell breaks

* fix(mobile): use template literal for list code-fence probe

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…yai#35081)

Task checkboxes take their own text (excluding the checkbox label, nested lists and code blocks) as an aria-label, refreshed on every change, with 'Task' as the fallback for an empty item.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
* Allow plugin shortcuts in browser guest pages

* Clarify plugin shortcut availability in the UI
…sn't take it down (stablyai#36178)

* fix(windows): start the WSL holder outside Orca's jobs so a crash doesn't take it down

* test(windows): prove the job closed with a non-breakaway control before checking the holder
stablyai#34592)

* fix(pi): the thinking menu before the first message matches the chat's

Pi's pre-session catalog now asks Pi for its models over RPC and builds each
menu with the same projection a running chat uses, falling back to the text
listing only when Pi cannot answer over RPC.

* fix(pi): preserve remembered off effort on precise model lists

* test(pi): focus effort regression and stop fallback contracts

* test(pi): allow metadata reads between ordered option writes

* fix(pi): derive supported effort without replacing accepted intent

* test: cover host effort projection and refreshed frozen queues

* test: consolidate session option imports

* test: normalize absent catalog fixture records

* test: isolate host fixture types from client projects

* Preserve legacy effort capture for other agents
…5085)

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…tablyai#35110)

* fix(mobile): preserve blocks and images when formatting inline code

* test(mobile): drop collapsed-selection inline code case

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…ai#35157)

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…lyai#35171)

* fix(mobile): retain editor styling when switching color schemes

* test(mobile): fit theme-switch harness hooks under the file line cap

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…#36192)

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…ack to in-process PTYs

When daemon startup failed or outlasted the startup gate, the app never
adopted the host afterwards, so every terminal for the rest of that launch
ran in-process and died on the next quit or update. Install a late host
behind the degraded provider so in-process terminals stay on the local
provider and only fresh terminals move to the host once it is healthy, and
retry adoption a few times after a failed startup.
@innocarpe innocarpe added the bug Something isn't working label Oct 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.