Commit Graph
16398 Commits
Author SHA1 Message Date
Jinwoo Hong c19f12804a test: reset the provider session generation per test store (#40586)
A shared test worker carried settings.test.ts's generation bumps into
jira-web-client-status.test.ts, which then read local#3 instead of local#0.
2026-11-09 22:39:18 -05:00
OrcaWinandOrcaWin fa2a622f9f test: remove low-value launch status and crew hook suites (#40608)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 19:24:51 -08:00
Jinjing ce1d0d99b8 Preserve review links during rebases (#40583)
* fix(review): keep the active review linked through a rebase

A detached HEAD (rebase, bisect, checkout of a commit) is no longer treated
as a branch switch. Only an attached observation can clear the active
review and push target, judged against the branch that last proved
ownership: the in-session branch before the detach, else the owning host's
rebase verdict from the listing, else unknown (never cleared). linkedItems
are never cleared.

- shared rule (hosted-review-branch-ownership) used by the renderer writer
  and the runtime WorkspaceGitIdentity
- readRebaseOperation: spawn-free, fail-closed owner-side verdict; git am is
  not a rebase
- listings annotate detached rows with the verdict
- explicit push-target pushes refuse while a rebase is active or unverifiable
- opt-in verifyRebaseOperation status verdict gates review AI launches at
  the action boundary

* fix(review): gate mobile review actions and bound the rebase listing probe

- mobile fix-checks, resolve-comments and hosted conflict launches require a
  fresh owner-side rebase verdict after agent resolution; local conflict
  recovery and generic launches are unchanged
- the listing's detached-row rebase probe has a 2s budget; unread rows stay
  unknown, and a checkout whose read outlived its budget gets no new one
  until it settles
- an empty or malformed HEAD is unverifiable, not a proven detach
- the apply-backend real-Git test is gated on Git 2.26

* fix(mobile): let folder repo review actions launch without a Git verdict

Repo-backed folder workspaces have repo::path ids, so the mobile review-action
gate sent git.status for them and refused the launch. The gate now reuses the
repo the launch context already resolved and, like desktop's isFolderRepo
check, skips the verdict for folder repos; Git workspaces still need a fresh
'none'.

* fix(review): reconcile detached ownership per host and selection

* Fix review action rebase checks for the selected workspace

- Read fresh rebase state from the owning host without a full status scan.
- Rotate detached worktree probes so later worktrees receive checks.
- Avoid reopening the composer when a rebase check refuses launch.

* refactor(review): scope rebase fix to branch ownership

Preserve review associations through detached HEAD using the last confirmed attached branch. Keep unknown ownership conservative and retain host isolation and relink race protection.

Remove the background rebase scanner, rebase-verdict transport, and launch/push gating from this change. Keep the deferred gating work separately and replace the real-Git pipeline tests with focused metadata regressions.
2026-11-09 19:22:27 -08:00
Neil 457c602b4f refactor(automations): group feature modules under defining owners (#40605)
* refactor(automations): group authoring, host catalog, listing and run owners

* Preserve protected automation confirmation copy after owner moves
2026-11-09 19:20:58 -08:00
Wooseong KimandNeil 83d20ac87d fix(claude): keep each account's newest groveChoiceSeenAt during profile state sync (#40381)
Refreshing a managed Claude profile copied the personal ~/.claude.json
groveChoiceSeenAt map over the profile's map, dropping the profile
account's Consumer Terms confirmation. Every new terminal then made
Claude wait on a network check before starting.

Merge groveChoiceSeenAt per account like projects and mcpServers, and
keep whichever timestamp is newer for accounts present on both sides.

Fixes #40380

Co-authored-by: Neil <neil@stably.ai>
2026-11-09 19:14:31 -08:00
Jinwoo Hong 06ee32a8b9 perf(daemon): stop scanning launched agents' output for command-finished (#40599) 2026-11-09 22:07:33 -05:00
OrcaWinandOrcaWin 61d9cea4cf test: remove low-value native chat recovery suites (#40601)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 19:03:51 -08:00
Wooseong KimandNeil 86f9bb2a16 fix(native-chat): highlight the slash item whose name best matches the typed query (#40487)
Commands render before skills in the slash menu, so typing an exact skill
name could leave a fuzzy command highlighted and Enter would pick the wrong
item. After each edit or caret move the picker now highlights the row whose
name ranks best against the query. Arrow-key navigation still owns the
highlight between edits, and a catalog refresh keeps the row the user
arrowed to (by id) instead of jumping.

Co-authored-by: Neil <neil@stably.ai>
2026-11-09 18:59:14 -08:00
Neil e6308fb35c refactor(skills): group catalog, installation, sharing and freshness owners (#40581)
* refactor(skills): group catalog, installation, sharing and freshness owners

* fix(skills): retarget inventory benchmark to catalog owner
2026-11-09 18:53:22 -08:00
Benson LUOandNeil 38fe0766c3 fix(gitlab): never resolve github.com or bitbucket.org remotes as GitLab projects (#40410)
A stray github.com or bitbucket.org entry in glab's config made the failed
`glab auth status --hostname <host>` probe print a status block headed by a
bare hostname, which the configured-host parser accepted as evidence. The
known-host inventory could likewise list github.com. Because GitLab has
precedence among forge providers, GitHub and Bitbucket repos were offered
GitLab merge requests and GitLab login prompts.

Before trusting any glab evidence, resolveProjectRefForRemote now returns null
when the remote's real host (aliases folded via normalizeForgeWebHost) is
github.com or bitbucket.org. Scp remotes on an SSH alias named e.g. `github`
are unaffected.

Fixes #40386

Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
2026-11-09 18:48:58 -08:00
Wooseong KimandNeil be108a4981 fix(plugins): emit workspace.changed when focus moves between identical workspaces (#40505)
The watcher deduped on the public payload (branch, displayName, terminals),
so moving focus between two workspaces that project to the same payload was
dropped. Dedupe on the focused worktree id as well; the emitted payload still
omits that id because it can embed a provider path.

Fixes #40502

Co-authored-by: Neil <neil@stably.ai>
2026-11-09 18:43:32 -08:00
c2908a07b1 Keep chat navigation focused on human messages (#33403)
* fix(chat): collapse orchestration notices and keep the rail human-only

* test(chat): assert human-only rail previews

* test(mobile): inspect compact orchestration mail through its disclosure

* test(mobile): keep orchestration coverage in a focused suite

* test: retain the agent source type used by message cases

* fix(chat): keep rail reply previews while ticks skip agent-written inputs

Restores the hover card's reply line (the issue asks to keep the existing
preview), drops the shared test fixture and folds the authorship cases
into the rail and outline tests.

* fix(chat): stop rereading an older host's outline as the history window moves

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
2026-11-10 02:34:03 +00:00
SimonandNeil 793cfe5458 fix(artifacts): wrap the share popover's Update button label in long locales (#40297)
The "Update shared content" button inherited Button's whitespace-nowrap and
fixed h-8, so long translations (e.g. Russian) ran past the button edge in
the w-80 share popover. Let the label wrap, and stack the idle and
"Updating…" labels in one grid cell so the button keeps its height while
publishing instead of resizing the popover mid-update.

Fixes #40202

Co-authored-by: Neil <neil@stably.ai>
2026-11-09 18:33:00 -08:00
Wooseong Kim e39763be4b fix(native-chat): scale chat tables with the text size setting (#40396)
Chat message tables inherited the shared document renderer's fixed
text-[13px], so they ignored the chat Text size setting. Add a chat-only
0.9285714286em (13/14) override so tables stay 13px at the default 14px
size and scale with the message like the heading overrides do.

Fixes #40389
2026-11-09 18:32:50 -08:00
Kelvin Amoaba 75d7ecd3ac feat(dictation): choose how long silence lasts before dictation stops (#40530) 2026-11-10 02:25:34 +00:00
OrcaWinandOrcaWin 3d28b6fbf8 test: remove low-value Codex lifecycle and compiler examples (#40588)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 18:25:15 -08:00
Brennan Benson 80937f7eed Show a Fast-only speed as the Fast mode switch on mobile (#40523)
On the phone, Codex's Standard/Fast speed was a Speed row opening a
list while Claude's Fast mode was a switch. A Fast-only speed now uses
the same switch row; more speeds, or a lone Flex, keep the list. The
lone-Fast rule moves to shared code so desktop and mobile follow one
rule.
2026-11-09 18:11:52 -08:00
Jinwoo Hong 4a2726b3f6 fix(renderer): keep the right sidebar toggle during workspace creation; read the latest review provider in Source Control (#40478)
* fix(right-sidebar): keep the toggle while a workspace is being created

The creation surface has no titlebar strip and the floating toggle only rendered
with workspace chrome, so closing the right sidebar during creation (or on a
failed creation, which stays up until dismissed) left no button to reopen it.
The toggle button, its shortcut and the menu item now share one rule,
canToggleRightSidebar, so the shortcut also works during creation.

* fix(source-control): read the latest review provider when eligibility fails

The failure fallback read the provider through useEffectEvent, which keeps the
first render's handler inside memo components in React 19.2. A provider that
settled after the probe started was ignored. Read it from a ref refreshed in a
layout effect instead.
2026-11-09 21:08:21 -05:00
Jinjing be7d53e0c7 test(ssh): reset user disconnect state in connection fixtures (#40525) 2026-11-09 18:08:17 -08:00
Kelvin Amoaba c8569725a9 revert(tab-group): restore the split pane landing list (#40580)
Reverts c66199ab94 (#40469). The outline buttons didn't work out; the landing goes back to the plain list from #40113.
2026-11-10 02:07:24 +00:00
Kelvin Amoaba aa9c9a6e76 feat(settings): test the microphone in Voice settings and see what the model heard (#40493) 2026-11-10 02:04:07 +00:00
OrcaWinandOrcaWin e295b0d37c test: remove low-value settings and environment cases (#40578)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 17:58:42 -08:00
Brennan BensonandNeil cae1dd44f2 perf: avoid unused workspace reference work on store updates (#40554)
* perf: defer unused workspace reference cache projection

* perf: select workspace reference cache identities directly

Resolve cache readers once per attachment request so store notifications only read raw entry identities. Keep rendering and fresh reads on the existing projection and routing paths.

Co-authored-by: Neil <neil@stably.ai>

* perf: isolate cached reference readers from store snapshots

Create memoized identity readers in a scope containing only cache name and key so they cannot retain a previous whole-store snapshot through sibling read closures.

Co-authored-by: Neil <neil@stably.ai>

* fix: preserve reference cache reader indexed types

Keep the state parameter generic so indexing a chosen cache retains the matching entry type. Runtime reader behavior is unchanged.

* fix: retain cache key correlation in the reader type

The second index loses the cache-key correlation across the record union. Assert the identical indexed return type with the structural proof documented; emitted reader code is unchanged.

---------

Co-authored-by: Neil <neil@stably.ai>
2026-11-09 17:52:04 -08:00
Neil 2104da430c refactor(native-chat): group restart recovery and notice owners (#40570) 2026-11-09 17:50:58 -08:00
Brennan Bensonandhiba malik 73f11a54f1 Quiet linked task and review counts on workspace cards (#40482)
Co-authored-by: hiba malik <hibamalik8799@gmail.com>
2026-11-09 17:36:23 -08:00
Brennan Benson 1e967661a8 Fix false Codex worker readiness after startup (#40246)
* Keep Codex session startup separate from prompt submission

* Use normalized hook timestamps in CLI regression fixture

* Preserve root evidence across cached starts and relay child hooks

* Check cached starts cannot refresh expired root evidence

* Preserve Codex child ownership through cached session starts

* Keep session startup context within its terminal and session

* Narrow the eligible Codex context directly for typechecking

* Keep Codex turn facts scoped to their root session
2026-11-09 17:35:42 -08:00
Brennan Benson 4d1c130e17 fix(source-control): stop the Change Base Ref dialog from clipping the search field's focus ring (#40521)
The dialog body is an overflow-y-auto scroll area with no padding, so the
focused search field's 3px ring was cut off at its edges. Give it 4px of
room with -m-1 p-1, as the Workspace Details dialog already does.

Tracked in #39381
2026-11-09 17:35:37 -08:00
OrcaWinandOrcaWin 5ff661378b test: remove low-value markdown, agent, and pricing cases (#40566)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 17:20:55 -08:00
Jinwoo Hong 0bebd121b6 fix(orchestration): worker worktrees follow the project's setup setting (#40547)
worker-start defaulted --setup to run, so new worker worktrees ran the
setup script even when the project had setup turned off. Without an
explicit --setup, a worker now skips setup when the project skips it by
default; run-by-default and ask keep running it as before. Remote
workers resolve this on the host that owns the project.
2026-11-09 20:16:22 -05:00
Jinwoo Hong 82c9ba9534 fix(claude): keep a model picked mid-turn over that turn's later replies (#40546)
Picking a model while a turn runs cleared the reported model, but the
running turn's next reply, still from the old model, restored it. The
composer pill prefers the reported model, so it named the old model
while the menu checked the new one. Replies from the turn that was
running at the pick no longer report a model; the next turn's replies
and init do.
2026-11-09 20:16:12 -05:00
Neil 31eff247fa refactor(renderer): organize work-item and review defining owners (#40562) 2026-11-09 17:08:01 -08:00
OrcaWinandOrcaWin 08c0ffdec0 test: remove low-value snapshot and recovery cases (#40563)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 17:03:06 -08:00
Brennan Benson e96ee25c73 fix(ui): drop modal blur when the overlay starts closing (#40552)
The workspace blur was keyed on the overlay node existing, so it held through
Radix's exit fade and snapped off after the dim was already gone.
2026-11-09 16:54:11 -08:00
Jinjing d9e2f485f3 fix(agent-picker): preserve model discovery across queued waits (#40545)
* Keep saved agent models searchable while catalogs refresh

- Load saved catalogs independently of pending refreshes.
- Preserve edited presets until a completed catalog confirms removal.

* wip

* wip

* Preserve model discovery status when a read times out

Keep catalog responses provisional while discovery continues, seed account
catalogs when late results arrive, and retire queued discovery on shutdown.

* Simplify model catalog deadlines and picker state
2026-11-09 16:40:51 -08:00
Neil b39a64d347 refactor(renderer): group clipboard and text input owners (#40337) 2026-11-09 16:36:18 -08:00
OrcaWinandOrcaWin c14ee64495 test: remove low-value IPC and SSH recovery cases (#40559)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 16:35:29 -08:00
0654f0d6d3 perf(activity): reuse tab indexes across agent status updates (#40536)
* perf(activity): reuse tab indexes across status updates

* perf(activity): label tab-index cache temporary

Co-authored-by: Neil <neil@stably.ai>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* perf(activity): drop temporary label on tab-index cache

Co-authored-by: Neil <neil@stably.ai>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Neil <neil@stably.ai>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-09 16:30:02 -08:00
Kelvin Amoaba 66dcf33b54 fix(native-chat): Continue in Chat UI on an unsent Claude fork brings back the chat it came from (#40551)
* fix(native-chat): bring back the chat an unsaved terminal fork came from on Continue in Chat UI

* fix(agent-hooks): name a forked Claude terminal's session from its fork SessionStart

* fix(native-chat): bind a fork's origin chat to the fork's own conversation

* fix(native-chat): bind a fork to its launched pane and keep the stand-in chat's draft
2026-11-10 00:28:54 +00:00
OrcaWinandOrcaWin 668089d638 test: remove low-value terminal transport and input cases (#40538)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 16:21:52 -08:00
Brennan Benson 55db56d989 Make Settings easier to scan and organize General (#40249)
* Simplify Settings chrome and organize General into focused views

* Preserve search and skill actions across Settings views

* Correct Settings validation leftovers

* Keep skill conflict details visible in compact Settings rows

* Refresh Settings search and protected copy catalogs

* Use Settings design tokens and button variants

* Keep Settings test setup and translation catalogs current

* Keep Settings search metadata independent of display labels

* Build repository search groups only for the selected pane

* Keep pending skill installs and server menu labels accurate

* Use the supported role locator in the skill regression

* Keep absent skill installation actions on their supported path

* Restore the Settings sidebar to its existing appearance

* Restore shared navigation title keys in pane headings

* Preserve the Settings shell entry animation

* Drop unused Voice labels after the main sync

* Preserve main Voice translations and the moved skill module import
2026-11-09 16:12:36 -08:00
Jinwoo Hong 533a31b742 fix(agent-launch): restarted agents keep the launch they ran with (#38998)
* feat(agent-session): keep the permission mode a Claude session reports

Claude names its live permission mode on prompt, tool and Stop hooks. Keep the
root agent's latest value on the provider session, next to effort, so a resume
without a recorded launch can tell whether the session ran in bypass.

Ports the capture from #36359 by Nelef.

* fix(agent-launch): resume an unrecorded launch bare unless it reported bypass

Without a recorded launch, every restart path now resumes with no settings
Arguments, env or permission default; the configured Command still runs. A
session whose root agent last reported bypassPermissions keeps its bypass flag,
so a hand-typed claude --dangerously-skip-permissions keeps it while a bare
hand-typed claude never gains one (#29898).

Account-switch restart used the shared rule only for Claude; it now uses it
for every agent. Thanks to JustinCMR (#37304) for finding the account-switch
and cold-restore gaps.

* fix(terminal): keep the launch recipe of a window-started agent in main

A window spawn hands main its recipe, but main kept only the token and agent,
so restarts that main runs (workspace sleep capture, closed-worker reopen)
found no recipe and resumed bare. Keep it with the launch authority, the same
gate that admits the token.

* fix(orchestration): reopen a closed worker with the recipe it launched with

A closed worker's pane record goes away with its tab, so orchestration send
reopened it bare (#37693). The worker row now keeps the recipe Orca launched
the agent with, keeps it when a later capture of the same launch arrives
without one (main loses it on a daemon reattach), and a reopen prefers it over
a pane record that may hold another launch of the conversation.

Adapted from #37757 by Pr1p, without a new column.

* fix(terminal): keep a slept pane's earlier recipe only for the same launch

A host sleep capture without a recipe reused the pane's earlier record for the
same conversation. That is right after a daemon reattach, when Orca's launch
still runs but main lost its recipe, and wrong for an agent typed into the
shell that resumed the conversation: it never ran that launch.

* fix(agent-session): restore a paired pane with the recipe its host recorded

A client restoring a pane on a paired host sends only its recorded Arguments,
and the host filled the rest from its current settings. A saved restore now
replays the host's own record for that pane, or, with none at all, resumes
bare and keeps a bypass only when this host's hooks saw it reported. History
and other user-chosen resumes keep current settings.

* fix(terminal): replay a saved note only for the launch main still holds

A note belongs to the agent in a pane only while main holds that launch's
token: main admits it at spawn and retires it when the launch command
finishes, and a daemon reattach restores neither. Worker, host sleep and
hook/quit captures now take a note only from that attested launch, and no
longer copy an earlier record's note by agent or conversation match, which a
typed resume in the same shell also satisfies. With no attested launch the
unrecorded rule applies.

Replaces the inferred orcaLaunched / recipeLostPaneKeys flags and drops the
mock-only reopen and fixture-echo worker tests.

* fix(agent-status): take a pane's note from the launch main attests

The window carried a pane's saved note into each new record by agent and
conversation match, so an agent typed into the shell that resumed the same
conversation inherited an earlier launch's bypass. Main now sends the note of
the launch it still holds with each status, and the window records only that,
its own launch registration, or, for a restored replay of the very status a
record was written from, that record's note. /clear and compact keep the note
because main still holds the same launch.

* fix(orchestration): reopen a worker with its own recipe or none

A worker without its own note took the note of whichever pane record held the
same conversation. Its reopen now always passes a complete recipe: its own
note, or the unrecorded rule. The unrecorded bypass is also scoped to Claude,
whose hooks are the ones that report a root agent's permission mode.

* fix(agent-session): restore a paired pane from its source pane, never current settings

A saved restore on a paired host looked up the destination pane, which a Wake
opens as a new tab, and fell back to the host's current settings whenever the
client sent its partial Arguments. The client now names the source pane (to
hosts advertising agent-session.restore-source-pane.v1), and the host replays
its note for that pane or, with none, resumes bare keeping only a bypass its
own hooks saw there. Older hosts keep today's behavior.

* fix(terminal): re-arm a launch across a main restart while its agent still runs

The daemon outlives main, so it now keeps main's admitted launch (token and
note) and drops it when that launch's command finishes. On reattach main
re-arms the launch only when the same agent still runs in the foreground:
nothing can be typed into a daemon PTY while main is down, so a running agent
there is the one the unretired note launched. A shell foreground clears the
daemon's note; an unknown read, including every Windows read, declines.

Older daemons keep no note, so restore declines there as before.

* fix(terminal): the daemon retires a launch note when its command finishes

A launch can finish while main is down, so main's own retirement never sees it and a
hand-typed agent in that pane would later pass the reattach foreground check.

* fix(agent-status): a fresh Claude start never inherits the last process's permission mode

A hand-typed resume of the same conversation may run without the bypass the previous
process had, so only /clear and compact carry the mode forward.

* fix(agent-session): name a restore's source pane in the host's own keys

A mirrored pane's key carries the desktop tab prefix, so the host's exact lookup missed
its saved note.

* fix(terminal): retire a daemon launch note by its token from the one retirement owner

A delayed reattach result or a late retire could clear a newer launch's note. Retires now
name the token they retire, the reattach checks its PTY before clearing, and re-arming the
same launch keeps the daemon's completion scanner.

* fix(agent-status): only the launch owner's statement changes a pane's note

Main now states the attested note, or null for none, on every hook status. An OSC or
display update makes no statement, so after a completed turn it no longer erases an Orca
launch's note; a typed resume still drops it through main's null.

* fix(terminal): an attach leaves alone a launch main already holds

The renderer attaches a pane the CLI just launched before its agent starts, so the
attach saw the shell and retired the new launch's daemon note.

* fix(agent-status): a paired client keeps a pane's note only on its host owner's word

The host's session-tabs frame now says whether the Orca launch it admitted still runs on
the published incarnation, and the client applies that fact whichever writer wins the
status. With an owner's word the conversation no longer decides; an older host that says
nothing keeps the same-conversation rule.

* refactor(agent-status): one decision picks a pane's note for every reader

The live entry, quit capture, provider-session updates, account restart and cold
restore now ask the same owner-aware decision. An owner's none is final and, when it
turns, ends the pane's registry entry and saved note, locally and from a paired host's
frame. Cold restore and account restart take that answer for a live invocation and read
the saved record only when none is live. Inlines single-use wrappers.

* refactor(agent-status): a paired retirement test reaches the cold-restore command; trim comments

Replaces the projection and continuity tests with one transition: host frame retires the
launch, the next OSC keeps no note, and the cold-restore command has no old bypass.

* fix(agent-status): an owner's none retires the pane's matched launch registry entry

* chore: satisfy changed-code gates (type guards, SAFETY notes, fixed test clock)

* fix(agent-launch): a teams launch keeps its note; a legacy leaf id restores without throwing

* refactor(daemon): keep the session launch note on the process base so session.ts stays in budget

* fix(agent-launch): a restarted terminal main can't vouch for keeps main's earlier launch rule

* fix(agent-launch): read the pane's current terminal; a finished launch settles an undecided pane

* fix(agent-launch): undecided and held launches end with their process

A finished command, a fresh launch or a replacement process settles an undecided pane;
a newer attach or finish supersedes a foreground read still in flight; a legacy relay
reattach without an incarnation stays undecided; a held launch applies only to the
process it was recorded for.

* refactor(terminal): watch and arm a created terminal's launch in one call

Keeps terminal-create.ts within the 300-line budget after main's growth.

* refactor(terminal): keep main's launch evidence in one immutable record

Replace the undecided flag, the reattach check map and the re-arm's writes
to main's orchestration launch fields with one launchEvidence object
(unknown, gone for an incarnation, or held with its recipe), owned by
launch-evidence.ts.

- A fresh admitted launch is held; any other fresh process is gone.
- A finished command or confirmed exit is gone, sticky for its process:
  no reattach, legacy or noted, can revive it.
- A replacement retires its predecessor's evidence without deciding the
  newcomer, which may still prove its own launch through a reattach.
- A reattach note is held only after a foreground read sees its agent;
  the evidence object fences that read.
- A gone launch clears its recipe and blocks both refill sites; a
  deliberate sleep snapshot keeps its recipe past the launch it captured.
- launchToken, launchIncarnationId and launchAgent writes match main.

* fix(terminal): keep launch evidence through a first incarnation and sleep snapshots

- Learning a process's first incarnation binds its held or gone evidence
  to it, so a later attach can neither revive a finished launch nor drop
  a running one; a known X->Y replacement is fenced as before and now also
  clears the predecessor's recipe.
- A status from no Orca launch leaves a sleep snapshot of its session for
  the wake and never takes that snapshot's recipe into a live or quit
  record.

* fix(terminal): record a runtime split's fresh shell as running no launch

* chore: rerun CI on main with the typecheck fix
2026-11-09 19:06:43 -05:00
Kelvin Amoaba 258d3b375a perf(mobile): brotli-compress the page build (#40532) 2026-11-10 00:03:30 +00:00
Neil eae521a4cb fix(files): authorize the trusted floating workspace cwd for runtime file access (#39817)
A bare filename opened from the floating workspace on orca serve (or a
paired mobile client) was denied even in a trusted cwd, because the
runtime's file authorization added only the chat scratch root. Desktop
and runtime now share one floating-workspace root resolver: the
app-owned floating folder plus the configured cwd only when it is
picker-trusted. An untrusted cwd or the default ~ adds nothing, an
explicitly trusted home is allowed, and a folder above home never is.

The trusted cwd is an exact root, matched as spelled: the real target
must be inside it and the root is never followed through its own link,
including through the Unicode-equivalence fallback. The approval-time
realpath is the root's identity: loading settings and trusting another
folder only normalize existing entries' spelling and never re-resolve
them through links. The one-time legacy seed still canonicalizes once,
a trusted cwd is stored in its canonical spelling at load, ~ expands
against home's canonical path, and a non-string cwd resets to the
default at load.

Fixes #36950
2026-11-09 15:49:42 -08:00
220347cae0 fix(daemon): reclaim an empty daemon pid file instead of failing every start (#39825)
* fix(daemon): reclaim an empty pid file instead of reading it as pid 0

Number('') is 0, so parseDaemonPidFile read an empty or whitespace-only
pid file as a legacy record for pid 0. killStaleDaemon then tried the
owned-record unlink, which never matches, and the next daemon failed
publishDaemonPidFile with EEXIST on every start.

Fixes #39092

* fix(daemon): reclaim a malformed pid record only once its endpoint is dead

publishDaemonPidFile creates the record before writing it, so a live
daemon's pid file is briefly empty. Now that an empty record parses as
malformed, killStaleDaemon must not reclaim it until the endpoint probe
shows the daemon is gone.

* fix(daemon): decline replacement over a malformed pid record on an inconclusive probe

A malformed record is kept when the endpoint probe returns unknown, and
a replacement daemon cannot publish its pid file over it. Report the
owner as unresolved in that case. A missing record keeps the existing
behavior, since the publisher re-probes before replacing.

* docs(daemon): drop stale notes that an empty pid record parses as PID 0

Refs #39092

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

---------

Co-authored-by: WawasCode <khalatyanwatsche@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-11-09 15:48:43 -08:00
OrcaWinandOrcaWin a96a028e3a test: remove low-value spawn and startup variants (#40531)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 15:46:09 -08:00
Neil c0d7a90729 refactor: break runtime import cycles; check import/no-cycle at full depth (#39732)
Extract shared state/helpers into leaf modules (pure moves, re-exports kept)
so import/no-cycle can run at full depth with type-only imports ignored.
120 src + 8 mobile cycles -> 0. 10 suppressions remain on the browserManager
singleton hub, which needs DI to break.
2026-11-09 15:45:32 -08:00
Kelvin Amoaba 4cd3088380 feat(settings): one-click dictation setup with a model suggested for your language (#40462) 2026-11-09 23:39:32 +00:00
Jinjing 6df5a57077 Guide agent installation and sign-in from chat (#40208)
* wip

* add treanslation

* wip

* fix the renderer import

* fix static analysis

* wip

* wip
2026-11-09 23:33:19 +00:00
5c5cd9344a fix(agent-hooks): unwrap outer sh -c wrapper when capturing Antigravity hook process (#40153)
* fix(agent-hooks): unwrap outer sh -c wrapper when capturing Antigravity hook process

* docs(agent-hooks): add docstrings and verify PreToolUse/PostToolUse/PostInvocation shell sequence

* test(antigravity): keep outer shell wrapper alive in shell-mode hook test

* fix(agent-hooks): require shell wrapper on Darwin and add OSTYPE=darwin unwrap tests

* fix(agent-hooks): match the macOS hook wrapper on argv[0] only

An agent whose prompt quotes the wrapper (/bin/sh ... ORCA_HOOK_AGENT_PID=) would
otherwise report its parent, the pane shell, as the agent. Drops the OSTYPE test
seam and keeps the unwrap test at the capture layer only.

---------

Co-authored-by: Ivan Ha <info.ivanha@gmail.com>
Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
2026-11-09 23:28:32 +00:00
Brennan Benson 23f4fd3181 fix(usage): price Claude Fable 5.2 and Mythos 5.2 (#40506) 2026-11-09 15:28:28 -08:00