* fix(terminal): give the window and main's copy the daemon's ConPTY resize rule
Every PTY a Windows machine owns is ConPTY, WSL shells included, and ConPTY
repaints its own grid after a resize. The window applied xterm's ConPTY
model only to native (non-WSL) panes, and main's copy for reveals and phones
never did, so growing either pulled history into ConPTY's grid. Decide
windowsPty from the PTY's owner backend everywhere, keeping the native-only
cursor, CJK and keyboard workarounds behind isLocalNativeWindowsConpty.
* fix(terminal): keep main's copy of an SSH relay PTY off the ConPTY model before its record exists
Main's copy is built on the first byte, and a restored or adopted relay PTY
can stream before its record carries a connection id.
* Chat renames are saved as the chat's name, so Session History shows them after the tab closes
Renaming a native chat tab only changed that window's tab. Session History, phones and other windows read the host's saved name, so the rename vanished from History once the tab closed or Orca restarted.
A rename now goes to the host that owns the chat (agentSession.rename) and is saved as the chat's one name, the field History, tabs, sidebars and phones already read. The record remembers that the user chose it, so automatic naming never replaces it. A window's pre-upgrade tab rename is uploaded once and only fills a name Orca chose. Hosts without the new capability keep the old tab-only rename. Every native agent's History row now shows the chat's name once it has one.
* Keep saved chat names consistent across readers and reconnects
* Carry qualified chat names into cached readers
* Reuse the history recorder context across platforms
* Use recorded chat ownership for legacy name transfer
* Transfer legacy chat names only from known catalog ownership
* Correct recorder path matching and History subscription order
* Require complete evidence for bridged parity exclusions
* Preserve sparse array lengths in complete recording comparisons
* Initialize History observation before loading workspace context
* Integrate measured History recordings and scoped parity evidence
* fix chat naming retries and certify both replay modes
* fix ambiguous chat rename labels after navigation
* preserve chat rename intent across tab updates
* type dashboard snapshot fixtures without assertions
* fix: align chat name observation with store contracts
* test: update chat name consumer fixtures
* test: distinguish sender naming metadata from status
* Preserve saved Activity chat names across tab focus
* Clarify Activity tab projection identity
* Remove package-manager lockfile churn from main merge
* fix(runtime): validate tab property edits before saving chat names
* fix: refresh History ownership after conversation clear
* fix: commit History request identity before refresh effects
* Fix History scan scope typing and integration test placement
* test: cover saved chat name reader contracts
* test: make chat naming fixtures deterministic
Claude Enterprise seats (null 5h/weekly windows, limit in spend/extra_usage) now show their spend cap as a monthly usage bar in the status bar chip, tooltip and account switcher instead of an empty meter.
Fixes#31061
Supersedes #31065
Co-authored-by: Frank Bernhardt <275327+frank-bee@users.noreply.github.com>
* feat(agents): store each agent's permission itself instead of typing flags into Arguments
Terminals and new chats read one stored choice per agent (Use the agent's own
settings, Ask for approval, Accept edits, Approve for me, Full access). Orca adds
the flag at launch; Arguments hold only the user's own text. A one-time move
lifts Orca's flags out of saved Arguments. Older clients still see and write
the flag as part of Arguments; the host translates.
* fix(agents): say the all-agents switch resets agents set separately; keep primitives unstyled
* test(agents): the one-time move returns every launch-profile field
* Fix permission carrier ownership and surface-specific defaults
* Preserve uncertain permission operands and name the option inventory
* Check env entries without indexing typed agent maps
* Combine Chat permission capability imports
* Use folder execution-host platform for permission environment
* Preserve launch map replacement and acknowledge permission saves
* Keep permission feedback fallbacks statically discoverable
* Provide preload platform to Agents settings render tests
* Preserve Gemini approval arguments under Full access
* fix(settings): retain complete environment edits through save outcomes
* fix(settings): narrow local failure scope and preserve host messages
* fix(settings): retire argument drafts after acknowledged saves
* fix(settings): keep Goose environment editable after reset
* fix(settings): show resolved arguments for legacy hosts
* Preserve pending environment resets and bound launch settings work
* Use agent permission choices for new chats
* Let Claude resolve chat permissions from its own settings
* Keep optional settings fallback in repository metadata reads
* Consolidate permission report imports
* Update permission choice contracts for own settings
* Read repository visibility defaults through the raw settings fixtures
* Match existing translated Agents settings labels
* Update readback and legacy host test expectations
* Align Chat behavior tests with host permission capability
* Fix permission compatibility and host-owned descriptions
* Prepare whole Environment edits and retire unchanged drafts
* Handle null explicitly in permission report decoder
* Keep Environment settings transitions in an acyclic module
* Update raw settings reader test fixtures
* Place test fixture safety notes on assertion starts
* test: pin permission settings work and recovery contracts
* test: type permission settings work fixtures
* test: cover migrated permission inputs and captured CLI grammar
* Publish permission reports and reuse host capability state
* Combine mobile option state React imports
* Honor mobile status feed capability for permission reports
* test: preserve typed permissions in WSL Claude restarts
* Correct permission report child and fixture type contracts
* Delegate older-host chats to explicitly selected own settings
* Avoid rebuilding live ACP option catalogs
* test(chat): place cross-boundary permission contracts in integration project
* Preserve existing chat capability gates and complete report test fixtures
* fix(chat): preserve newer Claude startup permission reports
* test(chat): clarify startup report fixture provenance
* Show reported permission modes in chat menus
* Keep reported permissions available after chat mode picks
* Remove obsolete guard from concrete permission selection
* Report the installed approval policy for ACP chat menus
* test: keep accepted mobile mutation fixture on current fence
* test: cover installed ACP approval report for own chats
* test: align capability scaling contract with concrete permission menus
* Ship required permission help in English runtime catalog
* Adapt permission persistence test to shared menu
Claude account-switch restarts now pass the folder the restarted shell opens in (tab start folder, else workspace), so #33527's `cd <start folder> &&` resume prefix applies and a session started in a subfolder resumes there. Codex account restarts benefit the same way.
Refs #31545
Supersedes #32033
Co-authored-by: ASH <7201776+asunghong@users.noreply.github.com>
Post-merge cleanup after the agent-integration fixes: remove the unreachable Windows hook-script stdin drain epilogue; Windows statusline exits instead of draining outside an Orca pane; Codex CLI fork uses the \\?\-aware rollout path; WSL browser-network relay falls back to orcad's pinned Node (shared launcher revision stamp); stranded sleep records only drop for their own worktree; renames (hidden probe cwd, local Windows ConPTY helper).
* Keep the Pi fixture exit observer
* Record failed owned opening before the first message
* Abort a matching provider open when its child exits
* Cover provider exit during an unanswered host open
* Cover explicit failure facts on a host-stopped child
* Capture message choices per accepted send and preserve picker state
* Apply accepted Claude message choices at prompt handover
* Apply captured message choices at provider dispatch
* Bind native chat choices to accepted message dispatch
* Reset Codex turn choices for each captured message
* Resolve Codex message defaults from native facts
* Align message choice and Pi default fixtures with provider dispatch
* Align option fixtures with saved message choices
* Match Codex message choices to the active turn origin
* fix: let pending commands reach handover refusal
* Abort pre-prompt message choice writes with host-owned wait
* Verify message choices through provider input boundaries
* Keep legacy mobile test hosts explicit about message choices
* Align Stop close causes and request-note fixtures
* test: align ACP Stop note fixtures with settled behavior
* Verify close intent reaches the native adapter
* Record the Stop request before waiting for interruption
* Keep Stop cleanup independent of request-note persistence
* Keep startup waits cancellable and preserve operation order
* Derive Codex startup exits from host phase
* Open Codex protocol in background-task test fixtures
* Keep ACP startup ownership until handshake completes
* Run ACP opening catalog fixtures with Node SQLite
* Verify saved ACP picks without live option writes
* Keep ACP catalog bookkeeping from failing an options read
* Restore signed-out restart and fail Pi startup faults
* Run Pi opening catalog fixtures with Node SQLite
* Preserve message choices across cold clients and kept cards
* Remove the unused provider option restore ledger
* Clarify launch choices and legacy option hydration
* Remove remaining restore-ledger forwarding and assertions
* Remove unused ACP and Pi restore bookkeeping
* Report late Codex exits and keep card Cancel notes scoped
* Remove the Pi close wrapper left by unused cause plumbing
* Update Stop tests for the simplified close contract and Node journals
* Update remaining close and interrupt assertions after cause removal
* Keep live choices and delivery order while agents start
* Drop retired startup revision from Codex opening
* Keep live-option cancellation until message choices and clarify catalog reads
* Hold ACP option replies in live-write cancellation regressions
* Remove retired Pi startup revision and match saved-pick behavior
* Check running choices and retained rewind messages after delivery integration
* Use observed root exit in Codex close reports
* Apply startup picks and let parked messages release operations [skip ci]
* Remove unused Codex opening report field [skip ci]
* Keep ACP restoration facts local to the provider [skip ci]
* Apply Pi startup picks after readiness and remove unused open facts [skip ci]
* Cover goal changes during the held Codex message wait [skip ci]
* Save a waiting startup pick after Stop ends its opening [skip ci]
* Save choices when startup ends or a replacement is still opening
* Check saved choices separately from Claude startup reports
* Release scripted Codex startup before awaiting queued picks
* Check the saved picker selection in per-message choice fixtures
* Exercise current choices and eager client capabilities in runtime fixtures
* Keep accepted Stop requests in runtime settlement assertions
* Reuse runtime fixture reads and type the fake connection directly
* Type the Codex child-proof fixture connection directly
* Align startup fixtures and preserve observed Claude exits
* Honor queued send authorization in Claude runtime fixtures
* Open Codex protocol sessions before Stop fixture dispatch
* Wait for the opened Codex child before runtime notifications
* Keep repeated permission picks usable and align Codex fixtures
* Validate pending picks against the live option state
* Order startup picks before later messages and retain flow regressions
* Keep reviewed lifecycle contracts while pruning duplicate tests
* Save picks after a proven exit without requiring a child
* Type the startup reply fixture against the Claude control contract
* Keep Codex startup flow contracts and remove overlapping adapter tests
* Restore the committed dependency lockfile after test tooling
* Keep startup recovery flows and remove duplicate Pi handshake cases
* Cover both Pi startup choices in the delivery flow
* Match the Pi prompt entry recorded by the scripted wire
* Honor the before-input callback in the startup reply fixture
* Keep message choice flows and remove overlapping selector tests
* Retain Stop flows and remove repeated reducer and adapter cases
* Keep Stop note writes independent of full session context
* Keep startup option menus independent and show the saved choice
* Exercise startup picks across real menus and the runtime
* Match startup picker fixture to saved message choices
* Keep saved effort visible when picking a model during startup
* Include the running-turn scope in repeated Stop fixture
* Use the current attach contract in import fixtures
* Keep the Codex journal translator within its line limit
* Match ACP startup fixtures to saved picks and late Stop behavior
* Check startup effort after saved picker choices are acknowledged
* Complete Stop target types and keep the effort regression concise
* Use requested picker values in the effort regression acknowledgement
* Exercise Stop receipt replay across a resumed provider child
* Require owned provider spawn and one host-awaited open (from #28055)
* Restore the live checks the startup cleanup's deleted tests pinned
One assertion each, in the surviving suites: a stale-generation exit is
ignored, a failed create lets its sink go, a readback before open is saved,
an idle stop that fails is retried, a no-pick Pi start teaches its default,
an older client's pre-spawn failure and packed answer, an undrivable chat
stays readable, the resting slash menu stays on its own host, the main agent
reads apart from subagents, restore publishes status, naming runs off the
host's status feed, and a throwing logger never reaches the operation.
Also corrects the reliability gate note that claimed the send-idempotency
suite replaced the refusal-retry tests.
* Read a rewind in doubt outside the chat's serialize and apply it in the commit
The started settle and the attach's ready-child path read the provider's
history first, then apply what it proves in a short commit that re-checks
the rewind it read.
* Accept messages while the agent starts: run the start outside the chat's serialize
The chat's serialize was both where a send was admitted and where its agent
started, so every slow step of a start (closing-child join, lease
reconcile, recovery probes, resolvers, history read, spawn, sink drain,
provider dispatch) held every later send.
A start now registers in one short step before its first wait: its abort
controller (which Stop, close and quit already reach outside the lock),
its startup clock (the 10-minute ceiling now counts from here) and quit's
drain. Every wait after runs outside the lock, raced with that signal, and
every write is a commit that first re-checks the start is still the
session's. A start that loses the check is late: its spawn is closed
through the post-acquisition failure path and nothing is handed to it.
- The delivery loop's prepare returns a start handle; the loop awaits the
start outside, then re-prepares. Handover writes the pending row and
begins the dispatch abort handle in one commit, calls the provider
outside after re-checking the child, and resolves in a second commit.
- Ready operations claim a start instead of running one in their step.
- A client attach runs the same steps under one serialize, as before.
- An exit reported between spawn and publish is held for the publish
commit, which ends the child it indexes.
- An unproven close still fails only what was queued when its start was
asked for.
* Test that a send is accepted at every wait an agent start makes
One whole-flow test holds the start at each wait in turn (closing-child
join, reconcile probe, recovery re-probe, resolver, spawn, sink drain,
open, started recovery, pending row, provider call): a second send is
accepted at once, a Stop is recorded without waiting and nothing reaches
the provider, and what was sent goes to the published child once, in
order. Also quit before spawn, concurrent sends, a lease left recovering,
and an idle sweep racing a send.
* Bound each startup step on its own and drop the startup silence rule
A start no longer ends after 60 s without output: output is not protocol
progress. Each protocol step now has its own bound where its handshake
lives, and one 10-minute ceiling from registration stays as the outer bound.
- Codex: initialize 15 s and thread start/resume on the connection's 30 s
default again, instead of the startup ceiling.
- ACP: initialize 60 s, authenticate 120 s, session new/load/resume/fork
300 s; turns stay unbounded and option writes keep their caller's bound.
- Claude: the initialize answer has a 60 s bound; past it the open fails
with the ordinary startup-failure words and the host ends the child.
- The onOutput plumbing that only fed the silence rule is removed.
* Count Pi ready once it reports its state
Pi's start no longer waits for its model listing and slash commands.
The open returns after get_state and the unknown-provider check; the
listing then arrives as an options report (with the catalog listing the
start resolved) and the commands as a later publish. An empty model list
no longer fails the start as signed out: a signed-out Pi runs the unknown
provider, which still fails it, and a prompt it cannot run is refused
with the sign-in words by the existing prompt path.
get_state keeps the connection's 30 s request bound instead of the
startup ceiling.
* Test that model and effort picked while a chat is created ride its first message
A slow host's create reply arrives after the user picked a model and effort. The picker's view
layers the launch's held picks over its seed and the host's saved selection, and every send
carries what the picker shows, so the first message carries the picks whether the host's status
names its selection or not, and while the last pick is still on its way to the host.
* Start a phone's new empty chat on its first message
The phone's new chat is an agent.launch with no prompt, which always created the chat with its
agent started, while desktop chats start on the first message. The phone now advertises the
create-without-start capability, and a launch with no prompt from a caller advertising it creates
the chat at rest, keyed in the ledger by its create intent as a client's create is. Launches with
a prompt, the CLI (which advertises nothing), orchestration workers and ensure still start at once;
an older host ignores the capability and stays eager.
* Take main's lockfile; the branch changes no dependencies
* Restore main's exact text in files the merge only reformatted
The pre-commit formatter rewrote 37 of main's files staged by the merge, though this branch never changed them, pushing two past the line limit. Committed without the hook because the hook would reformat main's text again; CI lints the result.
* Fit the startup tests to the owned-spawn, host-awaited-open contract
Test doubles gain the mandatory open and an acquisition generation, the
removed started event gives way to the rig's proveStart, and two literal
types are tightened for CI's typecheck. A Stop during a held start writes
no host note on this branch: the taken-back send draws its own
stopped-before-start row, which the startup-attempt test now asserts.
* Fit the remaining CI checks to the startup limits and current releases
- Run agent-launch-at-rest.test.ts in the SQLite Node runtime project.
- Pin the send-options cross-version case to v1.4.228, the first published release with agent-session.send-options.v1; v1.4.226 was never pushed.
- Load the baseline's isStructuredTab from src/shared (moved in v1.4.228), falling back to the renderer path for older baselines.
- End the never-proven start with a short startup ceiling: the silence limit it relied on is gone, and the ceiling counts from registration.
* Read the option stamp from the chat's one host-execution selection
* fix: preserve startup authority and accepted agent choices
* Retain dispatch authority and reconcile accepted options
* fix(native-chat): preserve accepted choices and cancellation authority
* Restore established client selection flow
* Preserve provider output observation and typed startup fixtures
* fix: preserve initial Claude launch choices and effort readback
* test: complete Claude catalog session fixture
* Preserve incoming main files after merge formatting
* Preserve compact handover through startup merge
* Type instant startup fixtures before their open is supplied
* Keep browser sign-in under its existing expiry owner
* Finish the main merge: retired-model display, start rewind cut, new tests
A model the Claude CLI retired is reported again, so the picker shows what the child runs and the
next send moves the chat off it. The start reads a rewind in doubt against the handle it answered
with, the record its commit then applies to. Main's tests follow the start's open: the admission
fixture holds a real turn, and a sign-in close during setup fails the open.
* Type the start's rewind record as the store returns it
* Type the Sleep test's held open as the provider open it replaces
* Sleep counts a chat stopped once the start it aborted leaves it at rest
A start runs outside the chat's lane, so Sleep's step can run before the start it aborted has
settled; it then re-reads the chat once that start is done, instead of reporting it unverified.
* Keep Sleep's start-abort bookkeeping beside the rest of Sleep's stop
* Keep the listed background Stop lifetime cases
The two #29905 cases lived in the turns test this branch removed. They pin that a listed Stop never ends a helper lifetime it did not capture: a same-id restart during acceptance, or a refused helper that appears mid Stop-all, which must not close the agent.
* Reconcile test registries and queued provider work accessor
* Update CI scope fixtures after removed connection test
* Bound native chat Stop protocol steps and omit empty startup feedback
* Supply current session fence in empty-start Stop test
* Align goal cancellation test with accepted-message feedback
* test(native-chat): cover distinct repeated Stop through Codex adapter
* WIP: own agent start attempts through readiness
* WIP: exercise complete start retries and final settlement
* test: pin startup failure settlement ownership
* fix: keep startup failure settlement with its requester
* fix: keep startup journal faults final
* Keep startup host wiring within the file limit
* Keep the adapter contract within the file limit
* Align startup retry callers with current host contracts
* Exercise startup exhaustion and requester ownership in existing flows
* Make requester failure row ordering explicit in the fixture
* chore: remove unrelated renderer changes
* fix: honor cancellation during final startup settlement
* test: keep startup failure readers within their projects
* fix: retain each physical startup child once
* test: use valid startup fences and publication boundaries
* test: align startup parity and retained child fixtures
* test: bound startup corpus within saved handle capacity
* test: cover startup classification with recorded protocol rejections
* test(native-chat): mark the fake-timer backoff bridge as a deliberate timer use
* test(native-chat): put the timer-rule exception on its own line
* fix(native-chat): one ownership index with link roles, and a chat refuses to start while a terminal writes its conversation
Each chat link now carries its role (head or earlier) and key; Session History names
the chat continuing a conversation first, duplicate adoption checks only head links in
both the pre-commit check and the store transaction, and terminal resumes stay refused
exactly as before. The terminal-writer check now also runs inside acquireOwner before
the spawn, refusing with the typed pre-spawn reason conversationOpenInTerminal.
* fix(native-chat): hold a terminal start Orca issues until its terminal reports it
An in-memory registry of managed terminal starts per conversation, registered in the
same step as the resume admission (terminal.send with a resume command, createTerminal
with a command), bound to the PTY execution that runs it, and ended only when that
terminal's hooks report the conversation or the execution is gone. A chat's agent
start refuses while an entry may hold its conversation.
* fix(terminal): an automatic pane restore never resumes a conversation an open chat continues
Resume recipes built from a pane's saved facts (cold restore, deferred and late reattach,
sleeping wake, host mobile materialization) carry resumeOrigin 'saved'. The execution host
decides before any command is issued: while an open chat continues the conversation, or a
chat may be writing it, the pane starts its plain shell with the started-fresh notice and
its saved claim is forgotten; with unreadable records only a saved restore is refused and
its record kept. An admitted resume registers its managed start in the same step, so the
chat's agent start refuses until the terminal reports it or exits. Clearing the last saved
record now reaches disk.
* Fix saved terminal resume ownership and effective launch results
* Preserve conversation case and clear refused cold restore identity
* fix: publish effective terminal launch results on attachment
* fix: preserve terminal launch callback and candidate ownership
* fix: keep existing terminal attachments observational
* fix: consolidate terminal launch imports
* test: document snapshot runtime fixture boundary
* fix: preserve terminal launch identity types
* fix: accept reattach payload policy sessions
* fix: preserve terminal result validation contracts
* refactor: separate terminal create contract
* test: document partial terminal runtime fixtures
* test: align sleeping resume store fixture
* Fix terminal create type contracts
* fix: return the terminal main started to its waiting view
* fix: register reattached terminals before publishing their handles
* Check unavailable-resume test fixture types
* Complete sidebar resume test store fixture
* test: bound saved resume ownership and refusal work
* Settle refused saved resume claims from actual launch results
* Fix saved resume test type contracts
* test(e2e): capture exact terminal parking diagnostics
* test: verify parked terminal with fresh host inventory
* Consolidate agent session imports in remote terminal transport
* Clarify terminal conversation refusal guidance
* Admit note-only saved conversations without hiding live writers
* Retain terminal writer proofs through final admission
* Keep the permission pill inside the Arguments box
* Share the Settings permission menu and commit Arguments on field exit
* Honor changed permission choices and acknowledged host picks in reset notices
* Show acknowledged permission resets with scoped Undo
* Consume removed permission recipes in the Arguments draft
* Keep reset notices separate from the inline permission field
* Use Textarea variant for composite arguments field
* Fix permission test query typing and sync English runtime catalog
* Flow arguments beneath the permission chip
* Keep composite argument typography in Textarea variant
* Share native scrolling between permission chip and arguments
* Place all-agents permission menu beside its label
* Preserve permission menu width while settings load
* Refuse unsupported SSH project setup before local API dispatch
* fix(projects): keep the desktop's SSH refusal copy and drop a re-export
The desktop's own project-setup IPC is not an Orca server, so it keeps
saying the SSH connection is not connected; the renderer now refuses SSH
setup before reaching it. Callers import the shared refusal message
directly instead of through the controller. Adds a headless paired e2e
that sets up a project on the server's SSH host from a web client.
Refs #33124
* fix(projects): give the server refusal only for a paired server's SSH host
A desktop's own SSH host keeps its 'not connected' copy; the server
refusal shows on a web client, or for a target only a paired server lists.
Refs #33124
* test(e2e): read the added SSH target from the RPC result
* test(e2e): pass a typed SSH execution host id
* test(e2e): give the paired SSH project-setup timeout bump its reason
---------
Co-authored-by: Mohith S <smohith58@gmail.com>
The idle terminal-mode reset (ESC[0 q) is no longer written into the middle of an escape sequence split across output chunks (which made xterm print fragments like `41;41;41m`, e.g. Codex's composer sparkle on Windows): a per-pane tracker holds the reset until the next write that ends cleanly.
Fixes#20596
Supersedes #23733
On Windows, a cached foreground name that flaps to the tool shell (pwsh.exe) during Codex tool calls no longer makes Orca treat the agent as exited (clearing its working row and possibly writing the mouse-reporting reset): a fresh uncached foreground read must agree before the exit settles. Unknown-shell panes still detect real exits.
Fixes#29996
Supersedes #30606
Co-authored-by: Stone.W <218376701+Stoneeu@users.noreply.github.com>
A slept agent whose tab disappeared now resumes in a fresh tab (with --resume, through the existing duplicate/host guards) when its workspace opens, and main's stranded workspace-sleep record is then dropped (only if no tab still lists that pane), instead of the record sitting forever while the workspace opens a bare shell.
Fixes#22657
* fix(terminal): keep restored history when ConPTY repaints after a resize
The Windows daemon's emulator grew rows the way a Unix terminal does,
pulling scrollback back into the screen. ConPTY then repaints the grid
it owns from the top and overwrote those rows, so a relaunched window's
first fit lost about a screen of restored history and printed the new
shell's prompt onto the restored prompt's row. Give ConPTY-backed daemon
sessions (WSL shells included) xterm's windowsPty resize model, as the
window already does for native Windows panes.
* test(terminal): model ConPTY's repaint at the height it was resized to
ConPTY's screen holds only what the shell wrote at its current height, so a
shrink drops the rows above the cursor and each resize repaints that screen.
Assert every restored and shell row appears once, in order, across shrink,
shrink-then-grow and grow-past-original heights.
* test(terminal): show the Unix grow model loses restored history under ConPTY
A pane's owning agent takes the pane back from a nested/background child on its next hook when the hook matches the owner's recorded session (agent type and session id), instead of staying hijacked until the child finishes; stale owners and nested same-type children with new sessions stay rejected. No recorded session (older hosts/relays) keeps main's behavior.
Fixes#30589
Refs #13341
* Open links beside their source and reuse matching browser pages
- Preserve source-group placement across terminal, chat, file, and runtime links
- Add explicit “Open in this group” actions with safe refusal handling
- Match browser pages by host, session, resource, and exact page identity
* Preserve file link ownership when opening beside source
* Isolate browser link sessions by workspace profile
* Wait for browser tabs to render before activating links
* Respect explicit group requests when opening detected files
* Preserve legacy link ownership when opening browser tabs
* Clean up unactivated browser tabs after failed link opens
* Reveal routed browser links without stealing focus
* Preserve browser profile reuse and foreground ownership during link open
* Prefer visible browser panes and reuse exact link destinations
Reuse matching pages within the same workspace, execution host and browser
profile. Otherwise open in the focused or most recently used visible browser,
or create a split beside the source when no browser is visible. Keep explicit
group placement and background/focus ownership protections.
Incorporate visible-browser selection and popup routing from #22686 into
#32907, including selector regression coverage.
Co-authored-by: Luca Critelli <lucacri@gmail.com>
* Route browser links by workspace without reading global focus
* Validate SSH browser ownership before opening links
* fix branch file size limit
* fix(ci): track extracted browser link ratchet entries
* fix(test): follow source-aware browser link opening
---------
Co-authored-by: Luca Critelli <lucacri@gmail.com>
Opening a workspace while its local creation is still pending no longer seeds an idle terminal that steals focus from (or drops) the agent launch: the creating event carries the new workspace id, activation during creation shows the existing "Creating worktree…" panel, and the workspace takes over when creation finishes. A terminal the user explicitly opens is kept and the agent gets its own tab.
Fixes#25807
Supersedes #25812
Co-authored-by: Eotel <49769982+Eotel@users.noreply.github.com>
An idle saved Claude account whose ~8h access token lapsed (Orca never refreshes Claude logins; the CLI does on its next run) keeps its last-good usage for up to 24h and reads "Updates when Claude runs" instead of "signed out". Logins that can't recover (no refresh token, expired refresh token, or a revoked 401) still ask to sign in again, and the status bar keeps its warning icon when shown usage is over 30 minutes old. Kept snapshots drop windows whose reset has passed.
Fixes#30289
Supersedes #31105
Co-authored-by: luijoc <96428056+luijoc@users.noreply.github.com>
Resumed Claude/Codex agents come back in the folder they were started in: resume records save the agent's starting cwd from hooks (kept within a session and across Claude /clear and compact), persist it, and resume as `cd <folder> && <agent> --resume <id>` when it differs from the workspace root. A deleted folder now fails loudly at the cd instead of silently resuming in the root.
Fixes#16960
Refs #15485
* fix(worktrees): one host's git status no longer rewrites a same-path twin's branch (#32918)
* fix(worktrees): match a twin through its runtime alias and persist its review clear on the same copy
* fix(worktrees): keep the id-only patch for a lone copy; background refreshes refuse an unplaced twin
* fix(worktrees): a twin's identity patch skips the id-keyed review clear instead of reaching its sibling
* fix(worktrees): count runtime provenance when finding twins; Source Control refresh refuses an unplaced twin
* fix(worktrees): a twin's branch switch clears its own push target and review link on its host
* fix(worktrees): a twin's review clear keeps its stale-refetch guard and relink check, scoped to its own copy
* fix(worktrees): a twin tombstone names its full owner, and detected rows are stamped before sanitizing
* fix(worktrees): each twin copy keeps its own review-clear tombstone
* fix(worktrees): a rename carries each twin copy's review-clear tombstone
* fix(worktrees): a copy's tombstone from its twin days still drives its clear retry
* chore(worktrees): name why the existing review-link cast is safe
* fix(worktrees): one resolver names the copy for every git-identity read and write
* fix(worktrees): a Create PR run refuses when its copy no longer resolves; local null stays local
* fix(worktrees): an unselected twin stays unplaced; a legacy row's guard survives its first stamp
* fix(worktrees): a Create PR run keeps the copy it pinned at start; a legacy row's relink drops its stamped guard
* fix(worktrees): key review clears by the full stamp the next listing gives the row
* fix(worktrees): fill only missing stamp parts when keying review clears
* fix(worktrees): stamp review-clear keys from repo registrations, not the focused host
* fix(worktrees): a local row keeps its review-clear guard when discovery stamps it local
* fix(worktrees): stamp review-clear keys from the sole repo registration first
* fix(worktrees): a runtime-hosted copy's owner key ignores backfilled provenance
* fix(worktrees): Create PR and post-generation refresh read the pinned copy's push target
* fix(worktrees): a lone copy's push target still answers when the host index misses
* fix(worktrees): the push-target fallback accepts only an unstamped lone copy for a named host
* fix(worktrees): only SSH copies borrow a registration's provenance for review-clear keys
A woken sleeping agent keeps its launch config (flags like permission mode, model, custom args) so a later Orca restart restores it with the same flags; consuming the sleeping record no longer deletes the pane's launch config (retirement and launch-token/session matching still govern it).
Supersedes #31756
Co-authored-by: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com>
After Wake the window paints the restored history and then blanks its viewport, so the new
shell's prompt starts on a clean screen. The daemon's own copy of the screen, seeded with the
same history, skipped that step. A later reattach (a reload, a second window, the phone)
therefore showed the new prompt beside the dead shell's last one: `p7/sub$ orca@awin:~/projects/p7$`
(awin verify-11). The seed now ends with the same viewport blanking the window writes, built by
one shared function, after the process-boundary ground, which still never moves the cursor.
Co-authored-by: Claude <noreply@anthropic.com>
* feat(ssh): list saved port forwards that couldn't start, with why, and let you remove them (#32484)
A saved forward whose local port is taken, or that keeps failing, stayed
saved but invisible, retried in the background with no way to remove it.
The port-forward lists now show each saved forward that isn't open, with
the last start error, and Remove deletes it by its mapping.
* fix(ssh): a forward whose ssh exits after starting backs off like a failed start
* fix(ssh): re-register the new forward channels, close a forward a restore reopened before removing it, and update IPC fixtures
* fix(ssh): a flapping forward keeps its backoff streak until it stays up
* fix(ssh): translate the saved-forward row, say Stopped for a forward that died, toast a failed remove, and reset backoff on manual edits
* fix(ssh): keep saved forwards listed and removable while the host is offline; label the remove button; test the healthy-uptime reset
* fix(ssh): mirror saved forwards from main with a stale-read guard, including hosts that never connect
* fix(ssh): scroll the offline ports panel when saved forwards overflow it
* test(e2e): give the saved-forward restart case's timeout its reason
Ctrl+Enter reaches Claude Code as CSI-u (`\x1b[13;5u`) on local Windows ConPTY panes, matching macOS/Linux, so custom ctrl+enter keybindings work.
Fixes#29711
Leave a user's node or python program alone after a Claude account switch; unchecked terminals get an accurate toast.
Fixes#30327
Co-authored-by: Adif Sgaid <69080239+adifsgaid@users.noreply.github.com>
* perf(lint): keep JS plugins out of default oxlint and adopt ast-grep
Any jsPlugin makes Oxlint hand every file's AST to Node, so the seven custom
plugins cost the default `oxlint` run several times its native time.
- Move app-store-performance, quadratic-buffer-concat, renderer-scrollbar-style
and ime-enter-guard (scope- or dataflow-aware) to config/oxlint-js-plugins.json,
run by `pnpm lint:js-plugins`, CI, lint-staged and the changed-lines gate.
- Port sort-comparator-performance, mobile-pairing and native-chat-design-tokens
to ast-grep rules with rule tests, and delete the plugins.
- Add @ast-grep/cli, config/sgconfig.yml, `pnpm lint:ast-grep` / `test:ast-grep`,
a CI step, and an ast-grep pass in check-changed-code-quality.
- Add flaky-test rules (wall-clock reads, real-time waits, polling loops,
unquarantined skips, unexplained timeout bumps), baselined by a count ratchet.
* Enforce flaky-test ratchet on changed files; refresh baseline
* docs(agents): keep custom-rule details out of AGENTS.md
* Resolve ast-grep from the repo so gate scans of other roots work
* feat(devex): component fixtures with headless screenshots for fast UI checks
Colocated *.fixture.tsx files export named fixtures (render + optional store
seed, setup, interact, width). A dev-only Vite entry (vite.fixtures.config.ts,
extending vite.web.config.ts) renders one fixture in isolation with the real
I18nProvider, TooltipProvider, theme class, default-seeded store, and the web
client's preload bridge (installWebPreloadApi) as window.api.
`pnpm fixtures:shot <id|glob> [--theme dark|light|both]` starts or reuses a
detached server (Vite + one headless Chromium) and writes PNGs to
.cache/fixtures/. A warm page re-renders in place (~100ms/shot) and reloads
only after source changes. A stdio MCP server (registered in .mcp.json)
exposes list_fixtures and screenshot_fixture.
Fixtures load only through import.meta.glob in the fixture entry, which is
not a production build input; oxlint rejects static imports of *.fixture.
* Keep fixture config and agent config inside reviewed root entries
* Baseline the fixture page's default-settings seed in the focus-read ratchet
* docs(agents): shorten fixtures pointer
* Allowlist the dev-only fixture explorer's labels in localization coverage