30 Commits
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
f23b3308a5
|
fix(mobile): route external mouse click and drag to the terminal (#11473)
* fix(mobile): route external mouse click and drag to the terminal The terminal WebView suppresses mousedown/click at capture so xterm's own mouse handling stays inert (its onData bytes are dropped by the mobile bridge). That left hardware mouse clicks and drags with no path at all: touch taps reached mouse-aware TUIs and drove selection, while a Bluetooth mouse or trackpad click did nothing (#8818; wheel half landed in #11247). Add a pointer-event router on the terminal surface (pointerType 'mouse', left button only) that mirrors touch semantics: - plain click: same pipeline as a touch tap (links/file paths first, then tracking-mode press+release reports, else keyboard focus), and a click on an active selection dismisses it like touch does - drag with mouse tracking: press at the anchor, per-cell motion reports (drag/any modes), release on pointerup or pointercancel - drag without tracking: character-anchored selection reusing the touch handle-drag plumbing (edge scroll, handles, copy pill) Widen the RN gesture-input grammar to pass left-drag motion reports (SGR button 32, default-encoding byte 64) through the existing validation and rate limiting. Mock server: echo the subscribe viewport and serialize scrollback so the session screen leaves the resubscribe loop, serve the session-tabs subscribe stream, and add a MOCK_TUI=1 mouse-tracking scenario plus a [SEND] byte log - the rig used to reproduce and verify this fix on an Android emulator. Fixes #8818 * fix(mobile): capture the mouse pointer and clear stale gestures on pointerdown A drag leaving the terminal surface dropped pointermove/pointerup without pointer capture, stranding the gesture; a pointerup lost outside the WebView could leave a tracked press latched until the next gesture. * fix(mobile): end mouse gestures whose pointerup never reached the surface Capture the mouse pointer on pointerdown so a drag that leaves the surface keeps delivering pointermove/pointerup; when capture is unavailable and the release is lost anyway, synthesize the release from the next buttons==0 pointermove or the next pointerdown, so a tracking TUI is never left with the left button latched down. * fix(mock-server): clear the terminal stream interval on resubscribe and unsubscribe * fix(mobile): synthesize the lost-pointerup release at the pointer's current cell * test(mobile): split terminal mouse click and drag coverage * test(mobile): satisfy changed-line quality checks * fix(mobile): cancel stale mock terminal callbacks * refactor(mobile): extract mouse report cell mapping |
|
|
|
f4e46383df
|
feat(mobile): add session.tabs.list handler to mock server (#9293)
* feat(mobile): add session.tabs.list handler to mock server
The mock WebSocket server had no handler for session.tabs.list, so the
session screen of a paired dev client hung on 'Loading tabs' forever —
the terminal pane, live input, and command input could never be
exercised against the mock. Respond with a single ready terminal tab
wired to the existing term-1 fixture so the whole session surface works
offline.
* fix(mobile): complete the session.tabs.list mock contract
The new mock response omitted four non-optional fields of
RuntimeMobileSessionTabsResult: publicationEpoch and activeGroupId on the
result, and parentTabId and leafId on the terminal tab. Nothing caught it —
the object literal had no type annotation, and MobileSessionTabsStreamHealth
is generic over both result and tab. A shape-incomplete mock yields
untrustworthy repros for exactly the bugs it gets used for (session tabs,
split panes, pane-to-tab attribution).
Fill the fields with host-realistic values: a per-process publisher epoch, a
layout UUID leaf id, and the `${parentTabId}::${leafId}` surface id
mobileTerminalSurfaceId actually emits. Pin the shape with an explicit return
type so a future required field fails typecheck instead of silently drifting.
Move the fixture into its own module: inlining it pushed
mock-server-rpc-handlers.ts to 317 lines against a 300-line max-lines cap,
which broke `pnpm lint` on the parent commit. It registers through the file's
existing delegation chain, after the native-chat scenario so MOCK_NATIVE_CHAT=1
keeps ownership of the method.
Co-authored-by: Hanjoon Choe <hanjoonchoe@gmail.com>
* test(mobile): pin session tabs mock fidelity
Normalize the selector-backed worktree ID like the real runtime and cover the complete terminal surface response so future contract drift fails the mobile suite.
* fix(mobile): share terminal.list worktree resolution with session tabs
Main added `terminalListWorktreeId`, which the rebased session-tabs fixture
duplicated with a different no-selector fallback — `terminal.list` resolved to
the active fake worktree while `session.tabs.list` returned a literal 'mock',
so a session repro saw two different worktree ids for one screen.
* test(mobile): cover the bare session-tabs worktree selector
Answers the review note that only the `id:`-prefixed path was exercised.
* fix(mobile): make the mock publication epoch unique per process
Date.now() can repeat across a sub-millisecond restart, so the epoch did not
actually guarantee the fresh-publisher identity its comment claimed.
---------
Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
|
|
|
|
28b395ced2
|
fix(mobile): harden native chat send budgets, streams, and stop (#10814)
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com> |
|
|
|
4a71a0ecb2
|
feat(mobile): add safe Codex rate-limit resets (#9394)
* feat(mobile): add safe Codex rate-limit resets * fix(mobile): address reset credit review feedback * review: purge removed-account reset attempts, shared capability constant, rebase test mocks * review: preserve host compatibility and reset durability * fix(mobile): recover reset capability after cutover * fix(mobile): validate runtime capability payloads * fix(mobile): enforce capability payload contract * fix(mobile): route mock terminals to selected worktree * test(mobile): pin malformed probe retry behavior --------- Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> |
|
|
|
aab112933e
|
Revert "fix(memory): bound OOM-prone accumulators (#10179)" (#10255)
Co-authored-by: Orca <help@stably.ai> |
|
|
|
8f40ddf328
|
fix(memory): bound OOM-prone accumulators (#10179) | |
|
|
e58de71f5e
|
feat(codex): real-home routing + self-contained multi-account homes (#9501)
* feat(codex): backfill managed-home sessions into the real Codex home once per host Orca-launched Codex sessions currently land only in the Orca-managed runtime home, so the user's own `codex resume` picker and app history never see them (#4444, #8612). Backfill the managed sessions tree into the real ~/.codex/sessions/YYYY/MM/DD layout once per host: - hardlink first (one physical rollout log), copy as the cross-volume fallback; existing target files are always skipped, nothing in either home is deleted or moved - idempotent; per-file failures leave the completion marker unset so the next startup retries cheaply - JSONL audit log of every link/copy/failure under <userData>/codex-session-backfill/ - honors the custom Codex session source home override, mirroring the existing system->managed bridge WSL managed homes are distro-local and need an in-distro variant; that is a follow-up. * feat(codex): flag-gated system-default real-home routing scaffolding Staged internal flag (default OFF, no settings UI): route the SYSTEM-DEFAULT Codex account at the user's real ~/.codex instead of Orca's managed runtime home. Flag OFF is byte-identical to today; managed (multi-account) selections are unchanged in either state. Routing (flag ON + host system default = no managed account): - CodexRuntimeHomeService.prepareForCodexLaunch / prepareForRateLimitFetch return null so the PTY/env layer injects no managed CODEX_HOME and the rate-limit fetcher + auth-presence gate fall back to ~/.codex (the background poller stops spawning Codex against the managed home — the #5370 auth war). - buildPtyHostEnv strips only a nested-Orca-inherited Orca-owned override (CODEX_HOME matching the private ORCA_CODEX_HOME marker), preserving a user-set CODEX_HOME. Shell-ready re-exports already no-op without the marker. - The headless commit-message Codex path strips the same inherited override. Hook install for the real-home lane (append-last into ~/.codex/hooks.json, trust via the app-server client) lands with the trust plumbing; the managed hook install is skipped for this lane meanwhile. Credit @jellychoco (#8606) for the native-home routing direction. Depends on the codex trust-rpc-grant plumbing for the real-home hook installer. * fix(codex): strip the daemon-inherited Orca CODEX_HOME override for real-home routing The daemon spawns PTYs from its own inherited environment and honors only spawnOptions.envToDelete, so mutating the sparse env object was not enough to strip an Orca-owned CODEX_HOME the daemon already carries. Add the strip to envToDelete for both daemon host-spawn paths, preserving a user-set CODEX_HOME. Verified live via CDP against a sandboxed dev instance (flag ON): an Orca-spawned pane reports empty CODEX_HOME/ORCA_CODEX_HOME, so Codex resolves its own ~/.codex. Adds daemon-path unit coverage (strip Orca-owned, preserve user-owned, no-op when flag OFF). * fix(codex): harden one-time session backfill * test(codex): cover staged cross-volume install * feat(codex): app-server trust-grant client, capability cache, and grant ledger Short-lived codex app-server JSON-RPC client (hooks/list + config/batchWrite, the same pair the Codex TUI 'Trust all' flow calls), run in a bundled ELECTRON_RUN_AS_NODE entry so synchronous launch prep can block on it with a hard deadline and guaranteed child reap. Capability cache modeled on GitCapabilityCache, scoped per execution host (native vs each WSL distro), with a narrow unknown-method/missing-subcommand unsupported predicate. The grant ledger records verified grants so steady-state launches skip the RPC. * fix(codex): grant managed hook trust via codex app-server RPCs in install/refresh Host and WSL installs now grant trust for Orca's managed status hooks through codex's own hooks/list -> config/batchWrite -> re-list verify, scoped to exactly the managed entries; the previous computeTrustedHash lane is the unchanged fallback for incapable/erroring CLIs. getStatus and the removal paths recognize ledger-recorded codex hashes so drift between codex's real algorithm and the replica no longer misreports or strands trust. SSH remote install is untouched by design. * test(codex): cover app-server trust grant client, cache, ledger, and lanes * test(codex): cover commit-message real-home override strip/preserve Adds the two cases for the headless commit-message Codex env under real-home routing: a nested-Orca-inherited Orca-owned CODEX_HOME is stripped, and a user-owned CODEX_HOME is preserved. * test(codex): WSL grant-lane coverage — in-distro invocation and fallback parity * feat(codex): real-home hook installer trusted via the codex app-server grant client With the real-home flag ON and the system-default selection, install Orca's status hook into the user's real ~/.codex before any pane spawns: - entry APPENDED LAST per managed event: codex hook trust keys are positional (source:event:group:handler), so appending keeps every user entry's position and trust record intact; user entries and unknown top-level hooks.json fields are preserved verbatim - trust is granted exclusively through the codex app-server client (hooks/list + config/batchWrite, verified by re-list); Orca never writes [hooks.state] into the user's real config.toml itself - if the grant lane is unavailable (old binary, unsupported RPC, verify failure), the appended entry is rolled back byte-exactly and the host keeps the managed-home lane end to end (PTY env, rate limits, commit messages) via a lane gate on the runtime-home service - one-time pristine backup of the user's hooks.json under Orca's userData; a rolling .bak sits next to the file (existing atomic writer) - hook opt-out sweeps Orca entries from the real home and drops Orca-owned trust records; flag-off downgrade re-arms the existing legacy system-home sweep, which removes the entry and its trust keys cleanly - the legacy system-home sweep is suppressed only while the real-home lane owns ~/.codex/hooks.json, so managed installs cannot delete the entry * fix(codex): resolve the trust-grant entry without requiring electron The grant bridge is reachable from plain-Node CLI entries, where the plain-node entry guard rejects any chunk containing require("electron"). Resolve the bundled session entry from __dirname (root chunk and chunks/ layouts) with an app.asar -> app.asar.unpacked rewrite for packaged runs, instead of electron's app path APIs. * fix(codex): keep session backfill off main thread Use asynchronous, sequential filesystem operations for the one-time rollout backfill, and avoid repeated target-directory probes. Treat inaccessible managed session roots as retryable failures instead of writing a false completion marker. * fix(codex): harden app-server trust grant fallback * fix(codex): install cross-volume session backfill copies atomically On a real Codex home whose filesystem supports no hardlinks (exFAT/FAT, some network mounts), the staged cross-volume copy was installed with a non-atomic copyFile(..., COPYFILE_EXCL) straight into the final rollout-*.jsonl name. An install interrupted mid-copy (app quit, crash, ENOSPC during the deferred run) could strand a truncated rollout that the next run then skips as already-present, defeating the staging design's own guarantee that a failed copy never leaves a partial session behind. Install the fully-staged copy with an atomic rename instead, guarded by an existence re-check so it keeps the never-overwrite contract (and the rename source is the same immutable managed rollout, so any clobber would be byte-identical). Cover the no-hardlink-support target and an interrupted install that must leave no partial in the user's sessions tree. * fix(codex): resolve grant entry from __dirname so plain-node CLI entries stay electron-free The build guard rejects any electron require reachable from plain-node entries; the bridge now maps app.asar to app.asar.unpacked by string replacement instead of consulting electron app paths. CLI typecheck project lists the new trust-grant module graph. * fix(codex): harden trust grant reconciliation * fix(codex): restore trust config permissions on rollback * fix(codex): harden real-home routing cleanup and retries * fix(codex): preserve unicode trust RPC responses * fix(codex): preserve remote env and complete real-home cleanup * fix(codex): preserve real-home lane invariants * test(terminal): isolate replacement idle reset assertion * fix(codex): preserve real-home dotfile links * fix(codex): preserve verified trust grants across launch prep * fix(codex): preserve dangling config symlinks on rollback * fix(codex): don't revoke a just-granted WSL home on a false 'missing' probe The async wsl.exe canonical-path settlement could report the runtime home 'missing' immediately after a verified RPC grant (a false negative — codex had just written and re-listed trust there), which drove the reconciliation 'remove' branch to delete all six granted [hooks.state] tables, leaving a bare [hooks.state] the launching pane read as 'hooks need review'. A 'missing' settlement now revokes only when no successful install ran this generation; a genuinely moved home still resolves to a different path and reinstalls. * test(codex): model codex config/batchWrite faithfully on Windows The grant-lane stub simulated codex by calling Orca's upsertHookTrustEntries, which writes both separator variants for a Windows key (a fallback-lane compat shim real codex never does) — fabricating duplicate tables and whitespace the RPC path never produces, so the byte-stable and no-duplicate assertions failed on win32. Replace it with a single-variant, blank-line-separated writer that matches the real 0.144.x binary's output. * feat(codex): collapse duplicate session listings across Codex roots Backfilled/bridged rollouts are hardlinked into both the real ~/.codex and Orca's managed runtime home, so AI Vault listed each session once per root (#7521). Dedup candidates by rollout file name pre-parse and parsed sessions by session id post-parse, keeping the canonical root: host real home first (unprefixed resume), then the managed runtime home, then other homes. Applies to local, WSL, and SSH-remote scans. * feat(codex): background sqlite index heal for backfilled sessions Codex's own state-DB metadata backfill is one-shot, so rollouts hardlinked in by Orca's session backfill never become visible to Codex's DB-driven surfaces. Extract the app-server stdio JSONL transport into codex-app-server-session (shared with the trust-grant client) and add a bounded, resumable background pass that drives Codex's lazy indexing via thread/read per backfilled session: recent-first, batched onto one short-lived server per batch with small concurrency, ledger + marker so steady-state startups are a no-op, stop-aware on quit, and capability-aware on CLIs without the app-server surface. * fix(codex): preserve session identity during dedup heal * fix(codex): preserve user trust during real-home cleanup * fix(codex): harden real-home heal boundaries * fix(codex): fail closed on unsafe backfill install * fix: harden real-home hook cleanup * fix(ai-vault): preserve execution boundaries and reap children * fix(codex): narrow app-server unsupported detection * fix(codex): bound user hook trust rebase retries per host The rebase lane ran a codex app-server session on every launch prep while a host was stuck (CLI without app-server support, or keys hooks/list cannot match). Gate the transaction on the shared capability cache and add the same 5-minute transient cooldown the grant lane uses, so sweep and legacy-cleanup retries cost plain fs reads instead of a codex session per pane spawn. * fix(codex): enforce real-home resume and heal boundaries * fix(codex): establish real-home lane before cleanup * fix(codex): stop index heal before delayed spawn * fix(codex): protect symlinked rolling backups * fix(ai-vault): preserve resume env deletion through drag * fix(codex): strip inherited Codex homes on mobile real-home resume The mobile resume surface types a bare real-home codex resume into a freshly created pane, but never asked for CODEX_HOME/ORCA_CODEX_HOME deletion at pane spawn, so an agentDefaultEnv-pinned or daemon-inherited Codex home rerouted the resume away from the user's real ~/.codex while the same session resumed correctly on desktop. Share the deletion helper from the AI Vault resume builders and forward it through the mobile launch and session.tabs.createTerminal call. * fix(codex): gate session migration on real-home lane * fix(codex): stop session backfill after opt-out * fix(codex): keep session heal failures retryable * fix(codex): keep session migration state recoverable * fix(codex): retry republished missing session heals * fix(codex): preserve hook symlink trust path * fix(codex): disambiguate POSIX trust paths * fix(codex): align hook trust source paths * fix(codex): harden trust grant lifecycle * fix(codex): restore envToDelete on client invocation type after base reconcile * test(codex): type child.stdout as PassThrough for oversized-output write * Assemble RC: reconcile app-server transport API across PRs Unify on the object RPC surface from the index-heal transport (#8921) while preserving the default-home env strip (#8828) and the narrowed missing-app-server capability signal (#8847): adapt the user-hook-trust-rebase consumer + tests, port envToDelete stripping into the shared session, and route stderr classification through the canonical capability-signal module. * RC: enable system-default real-home routing by default (flag ON) Flip codexSystemDefaultRealHomeEnabled to default ON for this RC's staged rollout (a user can still opt out by setting it false, which stays byte-identical to managed-home behavior). This is the only intended behavior difference between the RC branch and the individual PRs. Updates the two tests that assumed the prior OFF default. * fix(codex): snapshot hooks.json bytes+parse in one read to close real-home clobber race The install/sweep/legacy-cleanup paths parsed hooks.json, then did a separate later read to capture the previous bytes for the pre-write generation guard. A concurrent save (second Orca instance or the user editing the file) could land between the parse and that second read and be silently overwritten. readHooksJsonWithRaw returns the raw bytes and parse from a single read so the guard compares against exactly what it parsed. Adds a regression test that mutates hooks.json mid-RPC and asserts the sweep aborts without clobbering. * fix(codex): sanitize managed account config trust * fix(codex): guard OAuth add for custom providers * fix(codex): persist outgoing managed tokens before real-home lane takeover (PR-C) prepareForCodexLaunch returns null early for the real-home / system-default lane before syncForCurrentSelection runs. If a managed account is still recorded as synced when the selection has dropped to the system default (nulled without a sync pass, or auto-deselect on missing managed auth), a Codex-refreshed token stranded in the shared runtime home is never persisted to its canonical per-account home -> token loss. Read the outgoing managed account's refreshed token back before the real home takes over. The real-home lane implies host === null, so running the managed->system-default transition restores only Orca's runtime mirror from ~/.codex and never writes the real ~/.codex. It is a no-op once the selection has already been reconciled, so the normal select path does not double-write. * fix(codex): preserve refreshes across all default transitions * feat(codex): show system-default/real-home account identity in switcher (PR-B) The account switcher modeled the system-default Codex account as activeAccountId:null with no identity fields, so the null row rendered blank ("System default" / generic subtitle) even though its effective login is whatever ~/.codex/auth.json currently is. Add a CodexSystemDefaultIdentity descriptor {hasAuth, authKind, email, providerAccountId, workspaceLabel} to CodexRateLimitAccountsState, resolved live and READ-ONLY from ~/.codex by the accounts service and returned from listAccounts()/getSnapshot(). The settings switcher now renders the null (system-default) row as that real identity: the OAuth email when signed in, "Custom provider — no usage tracked." for env-key/custom-provider logins (auth.json with OPENAI_API_KEY, or an OPENAI_API_KEY env with no auth.json), and the generic fallback when signed out. Identity is host-scoped (per-distro WSL keeps the generic label). Orca never writes ~/.codex; managed-account switches only touch Orca-owned homes, so the system-default identity stays a stable, displayed source of truth. Usage already routes to the real home via getSystemCodexHomePath, so the switcher now attributes it to a real face. Tests (sandboxed temp homes only): OAuth email/provider resolution, api-key auth.json and env-key (no auth.json) as custom-provider, signed-out, and select/deselect of a managed account never mutating ~/.codex/auth.json. * fix(codex): parse multiline provider pins in OAuth guard * fix(codex): harden managed trust sanitization * fix(codex): harden system-default identity rendering * feat(codex): give each managed account a self-contained CODEX_HOME; retire shared mirror (PR-E) With the real-home flag ON, a host managed account now launches directly against its own codex-accounts/<id>/home instead of the shared runtime mirror + auth.json hot-swap: - codex-home-paths: syncSystemCodexResourcesIntoManagedHome links system resources into any managed home (ownership-marker discipline; never symlinks into / mutates ~/.codex). - runtime-home-service: prepareForCodexLaunch / prepareForRateLimitFetch / syncForCurrentSelection route the per-account home directly and skip the shared-home hot-swap + token read-back; each home keeps its own auth in place (fixes GAP-5 concurrent auth race). Session discovery scans every per-account home. - hook-service / hook-trust-promotion: install/getStatus/refresh accept a runtimeHomePath so hooks + RPC-granted trust land in the per-account home. - service: config mirror into a self-contained home uses the trust- preserving merge so granted hook/project trust survives account switches. - codex-session-root-dedup: rank codex-accounts/<id>/home as canonical managed alongside the shared runtime home. Flag-OFF and the system-default real-home (null) lane are unchanged; the nested-Orca CODEX_HOME===ORCA_CODEX_HOME daemon strip (#5370) is preserved. Sandboxed tests only; ~/.codex is never mutated. * fix(codex): validate per-account home ownership * fix(codex): keep managed rollouts discoverable across real-home opt-out WI-4 lossless migration/rollback validation for pre-E shared-mirror managed accounts. Session discovery gated the per-account home scan on the real-home flag, so opting back out (flag OFF) hid every rollout an account accumulated while the flag was ON — the data stayed on disk but vanished from the AI Vault until the flag flipped back on. Scan a managed host home whenever it holds a sessions/ tree, independent of the flag; a never-enabled install keeps its homes credential-only so opt-out stays byte-identical to today. Forward migration was already lossless (the shared mirror is always scanned) and the opt-out credential read-back already refuses to overwrite a fresher per-account token; add tests locking all three invariants. Sandboxed tests only; ~/.codex is never touched. * fix(codex): migrate stranded shared auth on E takeover * test(e2e): isolate Electron from developer Codex home * test(codex): add real-account validation harness * fix(codex): finish C and E matcher composition * fix(codex): bound validation harness shutdown * test(codex): isolate hook lifecycle user data * test(codex): cover realistic account-home migration * fix(codex): keep standalone home tripwire active * test(codex): fingerprint system auth in validation reports * fix(codex): bind managed homes to account ownership * fix(codex): normalize Windows trust source identity * fix(codex): make Windows trust upgrade transactional * test(codex): use TypeScript pipeline for validation scripts * test(codex): run validation modules through native node * test(codex): allow slow Windows tripwire startup * fix(codex): survive lingering Windows codex login processes in add-account On Windows, codex login can keep running (with descendants) after it has written auth.json, holding OS handles on the per-account managed home (log/codex-login.log). That made doAddAccount's post-login cleanup fail with ENOTEMPTY (rmSync) and left an orphaned codex-accounts/<id>/home. - runCodexLogin now watches for auth.json on Windows and force-kills the login process tree (taskkill /t) if it lingers past a short grace period; the forced exit is treated as a successful login. The 120s timeout path also kills the whole tree instead of only the direct child. macOS/Linux behavior is unchanged. - safeRemoveManagedHome now removes homes with rmSync maxRetries / retryDelay (mirroring the local-worktree-filesystem Windows policy) and no longer lets a cleanup failure mask the original add error. - run-codex-real-account-validation.mjs accepts --temp-parent / ORCA_CODEX_VALIDATION_TEMP_PARENT so the disposable root can live outside %USERPROFILE% on Windows, and fails with an actionable message before creating anything when the temp parent is inside the primary home. The real-home guard is unchanged. * fix(codex): preserve managed-account MCP .credentials.json on per-account-home migration (#8440) Codex file-mode MCP OAuth tokens live in $CODEX_HOME/.credentials.json, keyed by MCP server URL with no account identity of their own. The legacy shared-mirror -> per-account-home migration only carried auth.json, so an existing managed account with authed MCP servers had its tokens stranded on upgrade and silently needed re-auth. Carry the shared mirror's .credentials.json into the same identity-proven per-account home alongside auth.json: only into the single uniquely-matched active account (no cross-account leak), only when the destination has none yet (never clobber a newer file the account authed in its own home), atomic 0600, absent-source no-op. New MCP auth already lands in the per-account home since that home is CODEX_HOME. * fix(codex): preserve Windows reauthentication login flow * test(codex): build real-account validation harness cross-platform on Windows The harness built its app with execFileSync('npx', ['electron-vite', ...]), but npx resolves to a .cmd shim on Windows that execFileSync cannot launch (ENOENT), so the harness could not build its own app there and required --skip-build with a prebuilt out/main/index.js. Extract resolveElectronViteBuildCommand(repoRoot): it runs the repository-local electron-vite JS entry (node_modules/electron-vite/bin/electron-vite.js) with the current Node binary (process.execPath), which resolves identically on macOS, Linux, and Windows with no shell. It throws a clear error if the local entry is missing (install deps or pass --skip-build). --skip-build behavior is unchanged. Add regression coverage asserting the build command uses process.execPath and the repo-local JS entry (not npx), and that a missing entry fails clearly. * fix(codex): version the MCP creds migration independently of the auth marker The auth carry and the MCP .credentials.json carry (#8440) shared one existence-only v1 marker, so any build that stamped the auth-only marker first would strand the MCP store forever. The MCP carry now concludes via its own per-account-mcp-creds-migration-v1.json marker and runs even when the auth marker is already present; ordering is code-enforced instead of landing-discipline-enforced. Also isolate per-account read failures: one stale or deleted account home no longer aborts the whole migration. The broken account stays in the unique-identity ambiguity gate via its stored fields but is never read or written, so the active account still migrates. * fix(codex): fail corrupt managed auth.json without echoing credential bytes A raw JSON.parse SyntaxError from loadOAuthCredentials could carry auth file fragments into logs and the add/reauth error surface. Throw a sanitized error instead; filesystem errors still propagate unchanged. * fix(mobile): give the pairing runtime a disposable home for the E2E boot guard The main-process guard now refuses to start with ORCA_E2E_USER_DATA_DIR set but the real user home, and this was the one caller not updated — the temporary pairing runtime crashed before emitting its pairing URL. * test(codex): canonicalize harness containment guards and retry cleanup Resolve symlinks before the disposable-root containment checks so a symlinked temp parent cannot smuggle the throwaway home inside the primary home, and give the final cleanup rm Windows retry/force so a briefly lingering codex handle cannot strand the credential-bearing root. * test(codex): add lane-aware containment mode to the real-account harness The Windows gate-D run proved strict zero-event whole-profile containment is structurally unreachable with the real-home flag ON: system-default spawn sites deliberately delete CODEX_HOME so native codex resolves the real ~/.codex, and on Windows the binary ignores the USERPROFILE sandbox. Its own volatile runtime churn (root sqlite/WAL/SHM, tmp/, log/) is the shipped Phase-1 design, not a candidate defect. --lane-aware-containment records those designed events without aborting while every other real-home write — auth.json, config.toml, .credentials.json, hooks.json, sessions/, anything unknown — remains a hard violation and still aborts the run. Default behavior is unchanged (strict); the absolute zero-event claim stays carried by macOS runs, where HOME does sandbox native codex. * test(codex): allow the real-account harness to pin the real-home flag off --system-default-real-home off seeds and env-pins the flag OFF so every codex spawn gets an explicit managed CODEX_HOME and native codex never resolves the OS profile. This is the only Windows configuration where the strict zero-event whole-profile tripwire is reachable, and it matches the stable-rollout default; flag-ON runs keep lane-aware classification. * test(codex): correct the flag-off harness comment to kill-switch rationale The rollout ships all codex-home changes at once (no phased rollout), so flag OFF is the emergency kill-switch lane, not the stable default. * test(e2e): canonicalize the isolated E2E home path The disposable HOME lives under os.tmpdir(), whose spelling is an alias on CI (macOS /var symlink, Windows 8.3 RUNNER~1). Git canonicalizes worktree paths, so worktrees created under the aliased home never matched the app's listing — golden core flows and the packaged crash-survival harness failed with 'worktree created but not found in listing'. Resolve the home to its canonical spelling at creation in both the e2e helper and the packaged-app driver. * fix(codex): address CodeRabbit review on the landing PR - carry envToDelete through the mobile agent-resume startup plan so a real-home Codex resume cannot inherit an ambient CODEX_HOME - strip Orca-owned Codex overrides in the commit-message WSL fallback, matching the host fallback - strip ELECTRON_RUN_AS_NODE in the computer-e2e driver like every other home-isolation caller - drop the unused hooksEnabled parameter from isRealHomeCodexHookLaneUsable * feat(codex): ship real-home routing unconditionally, remove the rollout flag The codexSystemDefaultRealHomeEnabled setting is gone from types and constants and the helper no longer consults settings — the system-default real-home lane and per-account homes ship for everyone in one release. This also un-strands profiles that rc-era builds stamped with false (the setting had no UI, so every stored false was a seeded artifact that would have silently kept those users on the legacy mirror forever). The ORCA_CODEX_SYSTEM_DEFAULT_REAL_HOME env override survives strictly as a test-rig control: the containment harness pins the legacy lane for strict zero-event Windows runs, e2e home isolation pins lanes inside disposable homes, and the legacy-lane test suites now route their per-test lane selection through it. --------- Co-authored-by: OrcaWin <alpha-eng@stably.ai> |
|
|
|
5fcf777617
|
feat(mobile): Quick Commands (terminal + agent-prompt presets) (#9298)
* feat(mobile): add Quick Commands (terminal + agent-prompt presets)
Brings the desktop Terminal Quick Commands feature to mobile: saved
agent-prompt or terminal-command presets that launch a new terminal tab.
Entry point sits in the session tab strip next to the "+" new-terminal
button (with a divider) — quick commands spawn a tab, so they live with
tab creation, mirroring desktop's tab-bar split button.
- Launcher button + Quick Commands bottom sheet (search, This project /
Global groups, run/edit/delete rows, add row).
- Add/Edit sheet mirroring desktop TerminalQuickCommandDialog: Label,
Action toggle (Terminal Command | Agent Prompt), Agent select, Prompt /
Command Text, Advanced (Append Enter, Scope Global/Project), validation
and save-failure feedback.
- Launch reuses handleCreateTerminal (extended with enter + toast copy):
agent prompts launch the agent then deliver the prompt; terminal
commands run the (Enter-appended) command text.
- Expose terminalQuickCommands over the remote/mobile RPC surface
(getClientSettings/updateClientSettings allowlists, RuntimeStore type,
and the strict SettingsUpdate zod schema).
- Mirror the agent-prompt support predicate mobile-side (stdin-after-start
agents are unsupported) with a parity test guarding drift from desktop.
- Mock server: sample quick commands + settings.update handler for QA.
* fix(mobile): harden quick command execution
* fix(mobile): harden quick command persistence and launch
* test(mobile): preserve unexpected quick command errors
* fix(mobile): harden quick command launch performance
* fix(runtime): reject malformed quick command updates
* refactor(mobile): reuse shared quick-command logic instead of mirroring
The mobile quick-commands mirror was built on a false premise — that
runtime-importing src/shared/terminal-quick-commands breaks the RN bundle
/ Vitest. It doesn't: tui-agent-config → orca-cli-command-name is a pure
leaf with no module-load Node APIs (verified via probe + bundle-graph).
- Mobile now reuses the canonical desktop helpers (action/agent/scope/
matchesRepo/support/flatten) directly from src/shared; only genuinely
mobile-specific pieces (agent-branded labels, native row truncation,
the launch plan) stay local.
- Multiline runnable terminal commands now flatten via the shared
flattenTerminalQuickCommand (";"-join) — unity with desktop, so a
command saved on one runs identically on the other.
- Drop the MOBILE_TUI_AGENT_PROMPT_COMMAND_UNSUPPORTED mirror + its parity
test; use the shared supportsTerminalAgentQuickCommand predicate.
- Export the shared MAX_QUICK_COMMAND_* length caps for reuse.
* fix(mobile): protect quick command data boundaries
* fix(mobile): enforce quick command limits
* fix(mobile): make quick command updates atomic
* fix(mobile): keep quick command filters recoverable
* fix(mobile): use filled play icon for quick commands
* Revert "fix(mobile): use filled play icon for quick commands"
This reverts commit 169bf053b060deabda489b92a8bba56c4a0a1ad6.
* fix(mobile): gate quick commands on host capability
|
|
|
|
c408a3d852
|
feat(mobile): show usage reset countdown on accounts screen (#7954)
* feat(mobile): show usage reset countdown on accounts screen
Surface the rate-limit reset time ("5h resets in 3h 54m · 7d resets in
6d 7h") under the usage bars on the mobile accounts screen, matching the
desktop status-bar tooltip copy. The resetsAt timestamps already arrive
in the accounts.subscribe snapshot; this only adds the presentation.
Claude-Session: https://claude.ai/code/session_01FvjvCsc9QoyQALqvxkvDqQ
* docs(mobile): JSDoc for new usage reset selectors
Claude-Session: https://claude.ai/code/session_01FvjvCsc9QoyQALqvxkvDqQ
* refactor(mobile): per-bar reset countdown instead of combined line
Drop the redundant "5h/7d" prefixes — each countdown now renders under
its own bar ("Resets in 3h 54m"), matching the desktop tooltip copy
exactly.
Claude-Session: https://claude.ai/code/session_01FvjvCsc9QoyQALqvxkvDqQ
* Extract shared reset-countdown formatter for desktop and mobile
- Move duration/countdown formatting out of tooltip.tsx into
src/shared/rate-limit-reset-format.ts so mobile's account-usage-state
can reuse it instead of a duplicated copy (with tests).
- Re-export formatResetCountdown from tooltip.tsx to avoid touching
existing import paths.
- Resend the pairing deep link once more in start-emulator.mjs since
the first can arrive before the Expo app's JS router is ready.
---------
Co-authored-by: kaynan <kaynan.camargo@terceiro-sky.com.br>
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
|
|
|
|
99ae2dc90f
|
Show full workspace file tree on mobile (#7289)
Co-authored-by: Orca <help@stably.ai> |
|
|
|
25896f2cdb
|
fix(mobile): keep Android release versionCode committed (#7271)
Co-authored-by: Orca <help@stably.ai> |
|
|
|
f4790e9fac
|
Fix blank mobile terminal on Android devices with outdated WebViews or blocked CDN (#7186)
* fix(mobile): bundle terminal engine and show load errors instead of a blank pane The mobile terminal WebView loaded xterm.js from cdn.jsdelivr.net at runtime; old WebViews (< Chrome 85) fail to parse the modern bundle and blocked-CDN networks fail to fetch it, and the resulting error was silently dropped, leaving the pane permanently blank (#7030). Bundle the engine into the app via exact-pinned npm deps + a postinstall esbuild step (chrome74 target, guarded WeakRef/structuredClone/ replaceChildren shims) emitting a gitignored generated module, inline it into the terminal document, and surface fatal engine failures as a visible overlay with diagnostics and a Reload wired into the existing resubscribe path. Non-fatal errors log without covering a live terminal. Co-authored-by: Orca <help@stably.ai> * fix(mobile): add a native watchdog so a dead terminal document can't stay silently blank CodeRabbit round: if the webview document dies before the glue can post anything (or the RN message bridge never comes up), no error message and no native handler fires. Arm a 15s foreground-gated watchdog per document generation that paints the fatal overlay when web-ready never arrives; first fatal diagnostics win over later cascades. Extract the watchdog and the public contract types to keep TerminalWebView under the line cap, and document the SVG xmlns percent-encoding transform. Co-authored-by: Orca <help@stably.ai> * test(mobile): unmount TerminalWebView renderers so watchdog timers can't leak across tests Co-authored-by: Orca <help@stably.ai> --------- Co-authored-by: Orca <help@stably.ai> |
|
|
|
f9e18910ae
|
chore(lint): adopt unicorn/prefer-import-meta-properties (error) (#6847)
Migrate fileURLToPath(import.meta.url) / dirname(...) boilerplate to the
native import.meta.dirname / import.meta.filename, then enable the rule
at error so new code stays on the native form.
The oxlint autofix rewrites the expression but leaves the now-unused
node:url / node:path imports behind (which the already-enabled
no-unused-vars=error would then flag), so this commit also removes those
34 orphaned imports — trimming the named import where other names are
still used, deleting the line where it was the sole import.
Scope is build scripts + Node-env tests only (config/scripts, tools/
benchmarks, *.test.{ts,mjs}, vitest configs); zero shipped runtime code.
The native properties are exact equivalents (Node >= 20.11; repo is on
24), so behavior is unchanged.
Verified: oxlint 0 errors tree-wide (root + mobile), oxfmt clean,
typecheck (node+cli+web) + mobile tsc pass, root vitest 22825 passed /
0 failed, mobile vitest 1018 passed. Exercised the rewritten scripts
directly: build:relay (6 targets), ensure-native-runtime,
verify-macos-entitlements all run correctly with import.meta.dirname.
|
|
|
|
8a39450b18
|
refs/heads/handle-mobile-pull-request-issues (#6598)
* feat(mobile): add commit failure recovery panel with AI fix action - Surfaces a "Commit failed" panel with a one-tap AI fix button when a git commit fails in the source control view or PR creation flow - Detects commit failures specifically during the committing progress step and captures staged entries and commit message for context - Extracts commit failure summary and prompt logic into `src/shared/source-control-commit-failure.ts` and PR checks prompt into `src/shared/pr-checks-fix-prompt.ts` so both desktop and mobile share the same implementations - Adds auto-find of an available Metro port starting from 8081 and extracts expo CLI bootstrap into `mobile-expo-cli.mjs` shared by `start-emulator` and a new `start-expo.mjs` wrapper * Share source-control AI prompts and simplify mobile PR actions - Extract conflict, check-fixing, and commit-failure prompt builders to shared modules for reuse by both desktop and mobile. - Configure Metro in the mobile package to watch and bundle modules from the repository-root shared directory. - Remove the desktop-style merge method picker from the mobile PR actions panel, opting to use repository defaults automatically. - Refactor mobile hosted review creation and git preparation logic into dedicated helper files. |
|
|
|
c16aa89ea7
|
Improve mobile emulator pairing startup (#6527)
* Implement automated git preparation workflow for mobile PR creation Introduce a structured hosted review intent preparation workflow to handle staging, AI commit message generation, committing, and pushing changes automatically before displaying the pull request composer on mobile. - Map creation block reasons to descriptive user-facing validation errors (e.g., dirty working tree, default branch, detached head) to match desktop. - Decouple hosted-review business logic into a dedicated service helper. - Update source control runner hooks to handle the new preparation flow. * Refactor mobile PR creation to run intent and open URL directly Remove MobilePrComposeSheet and the local compose form, moving instead to a direct PR creation workflow that matches the desktop experience. - Add runMobileHostedReviewCreateIntent to handle the full prepare, push, and create sequence. - Replace useMobileOpenPrSheetRunner with useMobileCreatePrRunner to trigger the creation workflow and directly open the created PR URL. - Simplify state management by removing showPrSheet, prPrefill, and associated local compose sheets. * Propagate git status and commit state on PR creation failure Update `MobileHostedReviewCreateIntentOutcome` and the local change commit helper to include optional `committed` and `status` fields in their failure results. This ensures that if PR preparation fails, callers still receive the current repository status and know if their local changes have already been committed. * Add tests for mobile hosted review creation flow Introduce unit tests for runMobileHostedReviewCreateIntent to verify different scenarios of creating a hosted review on mobile, including: - Successful flow including staging, committing, pushing, and creating - Eligibility block handling (e.g., authentication requirements) - Error reporting when creation fails after an automatic commit * Block mobile PR creation on unresolved conflicts and refresh status Prevent creating a hosted review on mobile when there are unresolved merge conflicts. Also, return the latest git status on failures and reload it in the UI to keep the source control screen in sync. * Prefer fetched PR head SHA over cached status SHA for PR checks On mobile, a create command can commit before opening the review, meaning the fetched PR's head SHA is fresher than the route's cached status SHA. Prioritizing the fetched PR head SHA ensures we fetch checks for the most up-to-date commit. * Fix mobile PR creation errors and validate branch presence - Reject branch matches when the status branch is null or missing to prevent PR creation when the branch is lost. - Display actual PR creation errors in the sidebar instead of silently ignoring them on failure. - Trim leading and trailing whitespace from the base branch reference before persisting the worktree link. * Improve mobile emulator pairing startup |
|
|
|
55c0c74951
|
Fix mobile file previews (#6315)
Co-authored-by: Orca <help@stably.ai> |
|
|
|
5d8617bc71
|
Fix mobile workspace parity (#6207)
Co-authored-by: Orca <help@stably.ai> |
|
|
|
7b8adaf5f9
|
Improve Android mobile release dispatch (#6087)
Co-authored-by: Orca <help@stably.ai> |
|
|
|
8503110761
|
Improve mobile emulator start script (#6063)
* Enhance mobile emulator script with --port option and robust IP lookup Introduce support for configuring the Metro bundler port via --port, and allow overriding the CLI command name using the ORCA_CLI environment variable. Additionally, improve LAN IP detection and verification so that Metro URLs are correctly resolved and tested for reachability. Finally, fix the worktree argument passed during the emulator attach step. * Improve mobile emulator script shutdown |
|
|
|
32e6ab7655
|
Fix mobile workspace list parity (#6001)
Co-authored-by: Orca <help@stably.ai> |
|
|
|
8752996ef3
|
Allow switching to mobile website view in MobileBrowserPane (#5941)
* rm validation report * Remove mobile browser view switch validation document |
|
|
|
a856dee5d9
|
Exclude Windows from release evidence and update mock agent fields (#5949)
- Remove Windows from the release evidence platform matrix check because Windows release evidence is temporarily paused due to CI runner PTY readiness. - Add scenarioTitle as taskTitle and a display name to mock agent objects to satisfy updated runtime row shapes in mobile lag scripts. |
|
|
|
16347ab799
|
Handle clean local merges when hosting provider reports conflicts (#5942)
When the hosting provider (GitHub) reports conflicts but a local merge simulation is clean, we now mark the conflict summary as locally clean. This state is surfaced in both the desktop and mobile sidebars with a clear explanation and a copyable set of commands to trigger a remote mergeability recalculation via an empty commit and push. |
|
|
|
c9bd61376f
|
feat(mobile): combine PR sidebar and checks parity (#5641)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Orca <help@stably.ai> Co-authored-by: gsxdsm <gsxdsm@users.noreply.github.com> |
|
|
|
21a01c7d6b
|
Mobile: worktree-list sidebar for tablet/foldable layouts (#5505)
* Add worktree-list sidebar for mobile tablet/foldable layouts On wide canvases (tablet/foldable, >=700pt) the per-host worktree list now renders as a persistent left sidebar with the routed screens (terminal, source control, review, accounts, tasks) shown in a detail pane to its right — mirroring the desktop's sidebar + center layout. Phones keep the existing single-pane stack navigation unchanged. - Reuse the existing worktree-list screen as the sidebar via an `embedded` mode (props for hostId/action, mount-driven fetch since a sidebar is never the focused route, hide-sidebar control in place of the back button, and open-into-detail-pane navigation that replaces rather than stacks). - The default host route renders an empty WorkspaceDetailPlaceholder on wide layouts (the list lives in the sidebar) and the full screen on phones, so exactly one instance mounts either way. - Hide button collapses the sidebar to give the detail pane full width; an elevated reveal tab brings it back. - Detail-pane screen transitions use `animation: 'none'` while the split is active so workspaces swap instantly instead of sliding and flashing the screen beneath. - Drag the sidebar's right edge to resize (clamped 280-560pt, detail pane kept >=320pt, tap-transparent so list rows still work); width persists via AsyncStorage. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Address PR review feedback (#5505) - Clamp the restored/persisted sidebar width against the current window and re-clamp when the window shrinks, so a width saved on a larger device can't starve the detail pane below MIN_DETAIL_WIDTH. Extract a shared clampSidebarToWindow helper reused by load, window-resize, and drag. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Polish mobile tablet sidebar Co-authored-by: Orca <help@stably.ai> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com> Co-authored-by: Orca <help@stably.ai> |
|
|
|
0bb62b9d29
|
Add braces to mobile control flow (#4351) | |
|
|
2f7da8109e
|
Open mobile source control diffs in editor tabs (#2202)
Co-authored-by: Orca <help@stably.ai> |
|
|
|
afe90a616f
|
Add mobile source control actions (#2193)
Co-authored-by: Orca <help@stably.ai> |
|
|
|
a22717bb35
|
Refactor runtime app architecture (#1878)
Co-authored-by: Orca <help@stably.ai> |
|
|
|
fc578f5ea9
|
feat(mobile): Expo companion app [beta] (#1245)
Co-authored-by: Orca <help@stably.ai> |