* Move local usage services into a supervised backend process
* Own usage recovery and worker retirement lifetimes
* Preserve answered usage data during background refresh
* Run independent usage scans concurrently in the backend
* Limit backend startup paths to the delegated usage service
* Show usage failures through backend recovery
* Include usage failure strings in the English catalog
* Keep usage update details beside refresh failures
* Resolve usage freshness failure from the final producer snapshot
* Retain the forced refresh completion requirement
* Keep managed backend failures out of application crash reports
* Preserve usage recovery boundaries across backend reconnects
* Match the backend RPC cancellation signal in the usage seam proof
* Avoid serializing backend requests before port delivery
* Keep receiving request validation in the boundary schemas
* test: align usage transport coverage with renderer project
* fix: preserve unknown usage state and renderer retirement
* fix(usage): revalidate tracking before scan admission
* fix(usage): retry failed backend startup on demand
* test(usage): isolate stale backend ownership checks
* fix(pr-page): let the Start workspace button grow to fit its label
The pull request header pinned that button to 180px with nowrap, so longer
translations overflowed both edges and the arrow slid under the chevron.
A minimum width keeps the stable size for short labels.
tracked in STA-14595
Co-authored-by: 정의현 <rabbitdy0101@lemong.ai>
* fix(pr-page): wrap the header when the workspace button no longer fits
A long Start or Resume label grew past a narrow pull request page, the title
collapsed, and the chevron was clipped. The title now keeps a floor so the
actions wrap under it, and the label wraps only when that row is still too
narrow.
tracked in STA-14595
Co-authored-by: 정의현 <rabbitdy0101@lemong.ai>
---------
Co-authored-by: 정의현 <rabbitdy0101@lemong.ai>
* fix(native-chat): hold an automatic continue until the chat's account has usage again
The automatic continue after a usage limit sent at the cut's reported reset
without looking at the account, so it could send into a still-spent weekly
window. Each sweep pass now attributes the chat's launch account (the host's
launchAccountHome) to Orca's polled reading taken in that same home, and holds
the send until the latest spent window's reset (+15 s). The hold is derived
each pass, never saved, only grows for one cut and account, and waits up to two
minutes for a reading taken since that reset before falling back to the reset
it has. A spent window with no known reset stops the automatic continue for that
cut; on System Default, where Orca can't tell which login a reading saw, a fresh
reading with room releases both. Rows on desktop and phone show the held time
through an optional continueAt; older clients keep the cut's time.
* fix(native-chat): attribute usage holds once per account and retire them with their scope
- C1/X7: launch home resolved once per provider and reading once per (provider, home) per pass; narrow usageReading accessor replaces getState().
- X8: forget() drops the hold; hidden-chat caches are pruned while the setting is off; readState stores nothing for an unattributed chat.
- X3/C3: launch and reading homes compared in canonical form (~, dot segments, async realpath, bounded cache).
- X4/C2: a hold belongs to its scope (canonical home + billing kind) and retires when it changes.
- X2: a launch whose provider has no reading yet asks once and waits within the two-minute window.
- X5: attribution runs before the overdue check, so a restart keeps the account's later reset.
- X6: the launch account is re-attributed right before each send; beforeRun refuses a changed attribution.
- C5: cold chats publish when their continue time moves.
- X1/C4: WSL launches keep the cut's own reset (no hold).
* fix(native-chat): gate held continues on an account scope token and stop reviving stale cuts
- C6: a hold extends only with a spent window that had begun by the cut's reset.
- X6-R2, X10, P1-1: a synchronous account scope token (selection, launch env, reading home and
provenance) is captured at attribution; send() re-resolves only when it moved, memoized per
token, and beforeRun compares live and captured tokens. Opening a chat drops only cold-cut caches.
- X11: production tick() test at N=300 and 10N=3000 counts resolver and reader calls.
- X2-R2: the bootstrap wait starts when a pass first sees the due send without a reading.
- X9: canonical homes are resolved once per account per pass; the unbounded-lifetime cache is gone.
- C5-R2: unloaded chats have no status push path, so the cold continueAt publication is removed.
* fix(native-chat): separate continue eligibility from current spending and bind sends to their attribution's sources
- X12: a cut's eligible anchor (its reset, an established hold, or a covering window) takes the
24 h overdue test; once eligible, every currently spent window holds the send.
- X13/P1-2, X6-R3: the account owner returns attributions with a synchronous source witness
(settings snapshot identity, cached login-shell capture revision, reading-source identity);
Claude billing comes from the launch's own env composition. A result whose sources moved while
it resolved is discarded; send() and beforeRun bind to the attribution's own witness and
supersede without spending an attempt.
- CI-1: the scope-token type assertion is gone with the token.
* fix(native-chat): keep a covering hold beside spent windows of unknown reset
- X12-R4 / C7: rebuilding the covering anchor skips spent windows whose reset, and so start, is
unknown; the eligible branch still refuses on them.
- E1-R4: the preparation-change and suspended-attribution race tests run on a Claude chat
through the real host send, mutation and accepted settlement.
* refactor(native-chat): move the usage-limit continue status into its own wire module
The merge with main put agent-session-wire.ts one line over the 300-line limit.
* fix(native-chat): read the shell capture revision lazily so module mocks without it still load
Tests that main added mock login-shell-environment without the revision accessor, so binding it at module load failed.
* fix(native-chat): release a usage hold on fresh room for any account without stranding the cut
- QA-1: room in a fresh attributed reading newer than the last spent evidence (spentSeenAt)
releases the hold and clears an unknown reset for every account; the System Default-only
branch and identityKnown are gone.
- QA-1b: the release pulls heldUntil down to that reading instead of clearing it, and an
unknown-reset hold anchors on its last evidence, so a release over a day after the cut sends.
* fix(native-chat): release an expired usage hold from its room reading and ask for readings while a reset is unknown
- R6-1 / QA-1b-R6: a release sets heldUntil to the room reading itself, so an expired finite
hold followed by an unknown reset no longer strands the cut.
- R6-2: the usage poller idles while Orca is unfocused with no viewer, so an unknown reset asks
for a non-forced reading at most every 10 minutes through the existing refresh.
* fix(native-chat): bound unknown-reset readings per account and honor the failure backoff
- R7-1 / X-R7-1: the rate-limit service owns the automatic-read cadence: a read waits while the
provider's last reading or admitted automatic read is within the asked interval, so held chats
on one account cause at most one unknown-reset read per 10 minutes.
- R7-2: automatic reads wait out the poller's failure backoff (shared failureRetryDue) and start
its clock; forced refreshes are unchanged.
* fix(rate-limits): scope automatic usage-read admission to the selected account
- R8-1 / X-R8-1: an admitted automatic read counts toward the cadence only for the account whose
reading source the service held then, so a switch never lets one account's read delay another's.
- Prunes the flaky-test-pattern baseline: service-refresh-orchestration no longer reads the wall clock.
* fix(native-chat): keep a usage-reading request retryable until the service starts it, and show the last known reset while one is unknown
* fix(native-chat): show no automatic continue while a chat waits on an unknown reset, since fresh room still releases it
* fix(native-chat): publish no continue time for a cancelled or stopped cut while its account's reset is unknown
* fix(browser): stop agent clicks from opening the system file picker
An agent click on a file input opened the macOS Open panel, which brought
Orca's window forward over the app the user was in. Page actions now catch
the picker the way upload does and tell the agent to use upload.
* fix(browser): enable Page, cancel the picker, and clean up outside host scope
* fix(browser): limit picker blocking to input delivery and bound its setup
* perf(browser): skip picker blocking for actions without user activation
* fix(browser): bound picker interception cleanup on a hung page
* fix(browser): bound the picker interception setup as a whole
* fix(emulator): let iPhone Duo fold in release builds
Release signing gave serve-sim's in-simulator helpers the hardened runtime,
which drops the DYLD_ROOT_PATH that simctl spawn hands them, so the Duo HID
and accessibility helpers aborted at launch. Sign just those two with only
allow-dyld-environment-variables.
serve-sim's uncaught errors print its minified source, which contains the
"No serve-sim server running" text, so every crash was reported as no active
emulator. Report the thrown error line instead.
Fixes#40509
* fix(emulator): keep multi-line serve-sim error messages
* refactor(emulator): simplify serve-sim failure message parsing
* fix(native-chat): refuse a stale startup-dialog card choice and add a card for the multi-server MCP dialog
* fix(native-chat): drop casts from the startup-dialog guard
* fix(native-chat): refuse a startup card choice until the screen model has applied all received output
* fix(native-chat): refuse a clipped MCP server list and guard restored startup cards
* fix(native-chat): allow one startup card choice per screen so a second client's keys can't hit the next dialog
* Avoid sorting the folder catalog for a single host lookup
* Model the folder point read in remaining runtime fixtures
* Explain the partial emulator routing fixture boundary
Pad Linear CLI and project-list columns using terminal display width (wide CJK/Hangul cells as 2 columns, combining marks and ZWJ sequences aligned to Orca's Unicode11 xterm provider) while preserving terminal-safe line sanitization.
Refs #11883
Co-authored-by: BaeTab <bhwoo48@gmail.com>
Keep typed &, <, and > literal in prose text nodes when encoding them as HTML entities cannot change how the Markdown parses, while leaving entity-like sequences, HTML/autolink/blockquote-ambiguous tokens, and code spans intact.
Refs #16469
Refs #20177
Co-authored-by: Frederic Barthelemy <git@fbartho.com>
Structured image sends replace inline composer chips with `[Image #N]` tokens
for the provider prompt, which left sent `[Image #N]` markers visible in user
message bubbles, copied text, rail/outline previews, and row height estimates.
Strip in-range `[Image #1..imageCount]` markers across user message display,
copy text, row height estimation, and rail/outline previews while preserving
literal markers past `imageCount`, in quoted file references, or inside inline
backticks and fenced code blocks.
Fixes#32727
Co-authored-by: lurunzi <lurunzi@gmail.com>
* build(mobile): upgrade to Expo SDK 58 and React Native 0.88
Expo 58 drops Zod from @expo/cli, which clears the last Zod 3 advisory
(GHSA-mrhx-c7xc-m3w5) in mobile along with its local patch and override.
- Expo 55 -> 58, React Native 0.83 -> 0.88, React 19.3, gesture-handler 3,
webview 14, reanimated 4.7, worklets 0.13 (SDK 58 bundled versions,
pinned below today's batch to respect minimumReleaseAge).
- Port the react-native and react-native-webview patches unchanged; drop
expo-constants, expo-notifications, @expo/cli, expo-router, zod and
query-string patches plus the zod/query-string/xcode>uuid overrides,
which upstream fixed or no longer need.
- iOS minimum rises to 16.4 (Expo 58 / RN 0.88 requirement).
- Migrate to RN 0.88 strict types: instance ref types, NamedStyles,
AppState.currentState, list header/footer nulls.
- Replace removed runtime APIs: InteractionManager -> idle callback with a
macrotask fallback; StyleSheet.absoluteFillObject -> absoluteFill;
FileHandle.readBytes -> readBytesSync (it became async).
- Resolve react-native/asset-registry for shared assets in Metro and alias
the old registry path for react-native-svg in the desktop mobile-web bundle.
- Reduce the iOS scene plugin to the reconnect override; Expo 58's template
now ships the scene delegate itself.
* fix(mobile): bridge react-native-svg web imports and libsodium runtime for RN 0.88
- Share react-native-svg web shims between the mobile-web build and its render
checks: map the old asset-registry path to react-native-web's registry and stub
the Android-only touch-sound TurboModule.
- Patch react-native-libsodium 1.7.0 to read the JSI runtime from the bridge proxy;
RN 0.88 removed RCTCxxBridge.runtime.
* fix(mobile): use Expo 58's legacy promise resolver for audio permissions
* fix(mobile): skip null handles in the RPC recording timer shims for RN 0.88 types
* style(mobile): format MobilePRSidebar after rebase
* fix(mobile): name RN 0.88 text input refs for declarations; allow queued back in stack render check
- Type text input refs with an exported interface so declaration emit can name hook results
(RN 0.88 aliases TextInputInstance to an unexported class).
- Expo Router 58 drains back() after a commit; check the interrupted push's exit from the
frame it starts, bounded to three frames of lag.
* chore(mobile): justify the text input handle interface for React Doctor
* chore(mobile): use a nameable intersection alias for text input refs
* fix(mobile): use sync expo-file-system writes, copies and moves on Expo 58
Expo 58 made File.write/copy/move and FileHandle.writeBytes return promises.
Our callers never awaited them, so failures escaped their try/catch and the
store's tmp-then-move and PDF writes could race their close or rename.
* build(mobile): raise the page bundle budget to 10 MiB for Expo 58
Expo 58 adds about 310 KB to the page: expo-router (+258 KB, now carrying
React Navigation, net about +110 KB) and Reanimated 4.7 (+152 KB). Main had
85 KB of headroom left. 10 MiB still stays within the 10 MiB per-asset contract.
* fix(mobile): drop the window-metrics seed RN 0.88 removed from Android
RN 0.88 no longer holds window metrics: DeviceInfoModule reads the activity's
WindowMetrics on demand and setWindowDisplayMetrics is gone, so MainActivity
no longer compiled. Layout scale still comes from the screen metrics we reseed.
---------
Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
A chat Stop wrote Escape directly to the runtime PTY, bypassing xterm onData so agents that emit no interrupt hook stayed Working in the sidebar. Send Stop's Escape via sendRawVerified and observe plain-escape against the pre-Escape status baseline only after write settlement.
Fixes#31786
Co-authored-by: Zetao Qi <256975935+QZTnb@users.noreply.github.com>
Creating a child worktree while a runtime or fleet listing was in flight could delete its fresh lineage edge if the mutation landed after the scan's overtaken check (for example during metadata pruning or removal-checkout probes). Gate pruneLineageForMissingRepoWorktrees on the scan-start generation and pass { scanGeneration } from both runtime callers.
Fixes#16654
Co-authored-by: Skyler Shaw <skyler@jump.run>
Claude and Codex chat children kept the launching pane's ORCA_* identity
(pane key, tab, worktree, workspace, terminal handle), so hooks and the
CLI attributed the chat to the host pane. Launch composition now applies
the shared STRUCTURED_CHILD_ENV_TO_DELETE list once for every agent, which
also adds ORCA_WORKSPACE_ID and ORCA_TERMINAL_HANDLE to it; the seal still
keeps a worker's own handle.
Refs #26417
Co-authored-by: petersindex <287557875+petersindex@users.noreply.github.com>
Reuse the indexed original-pane target on VaultSessionRow so terminal Session History rows display their open tab's customTitle when getKnownExecutionHostIdForWorktree matches the session host, without defaulting unhydrated or unknown worktrees to local.
Fixes#33661
Co-authored-by: David Garcia <davidgarciab@gmail.com>
macOS PTYs split unframed writes into 1,022-byte reads, so UNFRAMED_AGENT_INPUT_MAX_BYTES = 1024 left a gap where single-line chat inputs could split across multiple unframed paste reads in Claude Code and other agent TUIs. Lower UNFRAMED_AGENT_INPUT_MAX_BYTES to 512 UTF-8 bytes so long single-line inputs are bracket-framed.
Fixes#32071
The orchestration skill guide and reference examples hardcoded --agent codex, leading coordinators on hosts without Codex installed to fail at agent_readiness. Replace hardcoded worker-start agent ids with <agent>, document how to pick an agent id across shared vs remote/WSL/--on execution hosts, and regenerate bundled skill guides.
Fixes#30495
Disable commit/tag GPG signing via a cached wrapper GIT_CONFIG_GLOBAL when
the developer's global gitconfig enables signing, clear inherited GIT_CONFIG_GLOBAL
in GitBinaryTestFixture, strip inherited TERM_PROGRAM* in Vitest setup, and
run ssh-posix-command-wrapper shell checks against an empty HOME/ZDOTDIR/XDG_CONFIG_HOME.
Fixes#27210
Co-authored-by: outof-place <contact@outofplace.space>
Callers such as getRepoUpstream and the tracked-upstream branch fallback called getGitHubApiRepositoryForRemote without checking the cached remote listing, causing repos without an upstream remote to run failing git remote get-url upstream execs on cold lookups. Gate non-origin remotes on shouldProbeGitRemote at the shared entry point while keeping origin unconditional.
Refs #22684
Co-authored-by: h5k <31630310+h5kk@users.noreply.github.com>
Escape or an item that skips refocus unmounts the focused menu onto <body>;
refocus the menu pane then, but leave focus where an outside click put it.
Fixes#21015
Co-authored-by: ckdwns9121 <40492343+ckdwns9121@users.noreply.github.com>
Decorated Claude task titles such as '◐ Alternativas ao Gemini Live' or '. Gemini rate limits' matched the bare gemini token, causing normalizeTerminalTitle to rewrite them to '✦ Gemini CLI'. Behind a spinner or '. '/'* ' prefix, require a Gemini label frame in any wrapper segment while keeping native Gemini glyphs decisive, and reuse the shared detector in terminal-title-agent-type.
Refs #29266
Co-authored-by: Mateus <mateuslannes100@gmail.com>
* feat(native-chat): run GitHub Copilot in Chat over its ACP server
Copilot chats launch `copilot --acp` with Copilot's own sign-in (or gh's),
so enterprise hosts and managed policy carry over. A Copilot dialect turns
its tool results into plain output and exit codes, and withholds the
commands that would switch Copilot to approving everything behind the
chat's permission mode.
The CLI version reader now accepts a version that ends a sentence, as
Copilot prints it.
Co-authored-by: Morten Trydal <trydis@hotmail.com>
* fix(native-chat): show Auto when a session lists no models instead of hiding the model pill
* fix(native-chat): don't name Copilot chats with a Copilot run that stays in its history
---------
Co-authored-by: Morten Trydal <trydis@hotmail.com>
* perf(orchestration): an unreadable item holds back only its own conversation, and remote-owned queries use their indexes
* fix(orchestration): a held conversation stays skipped for its batch, and pulls past the hold-back cap wait locally