* Show dispatch task preview and refresh generated titles when orchestrati
- Worker panes now display the task block from the dispatch preamble
instead of the raw prompt until orchestration metadata resolves
- Once orchestration displayName/taskTitle arrives, replace the
previously generated tab title instead of leaving the stale one
* fix: harden dispatch title preview and replace paths
Bound preamble scans, match orchestration labels to live task IDs, and
skip expensive title derivation when auto-title will not write.
* fix: accept orchestration labels when live task id is unparseable
Agent-status prompts are often truncated and omit the task-id line.
Only reject sticky labels when both ids are present and disagree.
* Fix WSL zsh ZDOTDIR restore using runtime-sourced path instead of baked
Windows-generated shell-ready wrappers are sourced via /mnt/c on WSL, where
the generation-time path baked into .zshenv doesn't exist. Capture the
runtime ZDOTDIR before it's unset and prefer it (when it still points to a
valid wrapper dir) over the baked literal when restoring ZDOTDIR, so user
.zshrc/.zshenv files load correctly under WSL.
* Fix zsh ZDOTDIR self-restore to guard against unset variables
Add ":-" default expansion when referencing _orca_wrapper_zdotdir_self so
the wrapper doesn't abort under `set -u` when the variable is unset, and
extend the shell-ready test to assert login-shell behavior (IS_LOGIN)
and improve failure diagnostics on zsh spawn.
* fix: dedupe fork-copied usage history across Claude, Codex, and OpenCode scanners
Coding-agent CLIs copy transcript/rollout history into new files on
resume/fork, and the usage scanners deduped per-file only (or not at
all), so copied history was re-counted once per descendant file
(issue #8006: 38.6B tokens / $72,981 reported vs ~2.3B real).
- claude-usage: cross-file turn ownership keyed on message.id:requestId;
per-file ownedDedupeKeys persisted; deterministic sorted-path claim
order; schema v3 -> v4 so inflated caches rebuild.
- codex-usage: cross-file token_count event ownership keyed on the raw
record identity (sessionId + timestamp + token tuples); fixes both the
copied-prefix re-count and the total-only branch that re-counted the
entire cumulative session per descendant rollout; legacy
.orca-session-copies skip-bytes bridge unchanged; schema v3 -> v4.
- opencode-usage: each sessionId is counted from exactly one database;
the canonical opencode.db claims ahead of stale sibling copies
(opencode-backup.db etc.) so backups no longer double totals, while
backup-only sessions are still counted; schema v1 -> v2.
Regression tests cover fork-copied files counted once (including the
Codex total-only variant), duplicated OpenCode databases, and dedupe
stability across cached incremental rescans.
Co-authored-by: Orca <help@stably.ai>
* Fix cross-tool usage double-counting for fork/resume-copied history
- Widen Claude dedupe keys with message-id and uuid fallbacks so forks
missing requestId still dedupe correctly, and drop Codex's sessionId
from event keys since fork/resume rewrites session_meta.id while
copying identical token_count records.
- Track hasDeferredClaims per cached file/database across Claude, Codex,
and OpenCode scanners so that when an owning file is deleted, only
files that deferred a claim need reparsing to reclaim those turns
instead of rescanning the entire corpus.
- Let OpenCode's live opencode.db reclaim sessions from a stale backup
claim once it reappears, avoiding a frozen stale snapshot.
- Bump schema versions to invalidate caches built with the old,
narrower ownership keys (#8006, #8013 follow-up).
---------
Co-authored-by: Orca <help@stably.ai>
* Fix untracked line-stat cache thrash and add source-control scale benchmark (#8013)
The untracked line-stat cache capped at 2,048 entries while a git status
scan can carry up to DEFAULT_GIT_STATUS_LIMIT (10,000) untracked entries.
A sequential scan over more files than the cap FIFO-evicted every entry
before the next poll revisited it (~0% hit rate), so every 3s status poll
re-read every untracked file's full contents. Measured with 64KB files:
warm rescan cost per file was 17x higher just past the cap.
- Size the cache to 2x the status entry limit and make eviction LRU
(delete-before-set on hit and refresh) so a hot worktree's entries
survive another worktree's scan.
- Add tests/e2e/source-control-large-file-count.spec.ts: a 5-scenario
Playwright benchmark (pnpm run test:e2e:source-control-scale) that
reproduces #8013 deterministically — event-loop stall, DOM node count,
JS heap, and OS-level renderer working set at 5k/9.5k/11k changed files,
plus a clean-repo control and a cache-effectiveness gate. Scenarios
asserting bounded row mounting go green with the SourceControl
virtualization fix (#7619).
Co-authored-by: Orca <help@stably.ai>
* Address review: historical cache comment + fixture cleanup on partial setup failure
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Orca <help@stably.ai>
* Fix diff viewer scroll flicker by marking programmatic scrolls explicitl
- Wall-clock "recent direct input" heuristics misclassified scroll events
during main-thread jank, causing stale anchor restores to fight active
wheel scrolling and produce visible flicker.
- Replace timing-based classification with explicit programmatic scroll
marks: every self-initiated scroll write (virtualizer corrections,
anchor restores, scrollToIndex) is marked so listeners can distinguish
it from genuine user input, including clamped landings from shrunken
scroll ranges.
- Gate anchor restore on a structural restoreSignal (row add/remove/
collapse, remount, layout flips) instead of every measurement tick, so
restores only run when something actually changed.
- Extract restore/listener logic into dedicated modules
(virtualized-scroll-anchor-listener.ts, virtualized-scroll-anchor-restore.ts,
programmatic-scroll-marks.ts) for testability.
- Leave WorktreeList on the legacy wall-clock suppression for now, with a
TODO to migrate once the new approach is validated for the sidebar.
* Fix diff viewer scroll flicker from stale marks and dropped restores
- Skip marking no-op writes since they emit no scroll event and could
claim a later user scroll within the mark-matching epsilon
- Distinguish browser clamp (viewport can't reach target) from real
user takeover using in-range origin and direct-input checks
- Sync scrollOffsetRef/anchor bookkeeping on our own programmatic
writes so divergence checks don't misread them as user scrolling
- Arm pending restore before skip guards so a restore owed during
active input retries once input settles instead of being dropped
- Guard the rAF-deferred restore against a user scroll that
disarmed it between scheduling and execution
* Fix leaked pending-restore flag when scroll anchor is unresolvable
Clearing pendingRestoreRef on both early-return paths prevents a stale
armed restore from firing on a later measurement tick with an unchanged
restoreSignal, which could re-trigger scroll writes and flicker.
* Add screenshot of current diff view scroll flicker state
- Captures the visual bug before the fix, for reference in the PR
* rm tem file
Add attribute filters (status, priority, assignee, labels) to the Linear
issues list, applied in GraphQL before pagination so hasMore matches the
filtered set. Thread filters through IPC/RPC/store cache with invalidation
on issue mutations, and mirror GitHub-style filter chrome on TaskPage.
The Source Control panel mounted every non-collapsed file row, so large
changesets (big refactors, lockfiles, branch compare with hundreds of
entries) created hundreds to thousands of DOM rows and re-rendered them
all on every 3s git-status refresh (`STA-351`, `STA-1280`).
Window each per-section list (uncommitted tree/list, committed-on-branch
tree/list) with @tanstack/react-virtual against the panel's shared
scroller, extracted into source-control-virtual-file-list.tsx. Sections
under 50 rows keep the exact pre-virtualization DOM so small changesets
see zero change; larger sections mount only viewport + overscan rows.
Fixed-height estimates with element measurement keep identical refreshes
from moving the scroll position, and stable row keys carry item identity
across status polls.
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Keep offline multi-chunk decoding safe for warm workers: refresh streams
after every decode attempt, continue sibling chunks after a failure, reset
session state on stop without dropping the stopped signal, and drop
in-flight feeds while stop is in progress so residual audio cannot
contaminate the next dictation. Extract model path/hotwords config to
stay under max-lines.
Here is a summary of how the sandbox behaves on your macOS system:
### ⚙️ How it Works
When `--sandbox` is enabled (either via the launch flag or the `enableTerminalSandbox` setting in your `settings.json`), terminal commands run inside a lightweight containment boundary:
- **macOS Native Isolation**: It utilizes macOS's native `sandbox-exec` utility to restrict system calls, network sockets, and directory access.
- **Secure File Boundaries**: File system writes are locked down to designated safe zones (such as your designated workspace or scratch directory). Access to critical system paths, private user data, and external network resources is restricted.
---
### 🛡️ Active Permissions for this Session
In this current session, the permission model is configured as follows:
| Action / Resource | Permission Status | Details / Paths |
| :--- | :--- | :--- |
| **Command Execution** | ✅ **Allowed** | Terminal command execution is enabled. |
| **File Reads (Allowed)** | ✅ **Allowed** | `/scratch`, `/browser_recordings`, `/html_artifacts`, `/knowledge`, `/worktrees`, `/skills`, `/builtin` |
| **File Writes (Allowed)**| ✅ **Allowed** | `/scratch`, `/browser_recordings`, `/html_artifacts`, `/knowledge`, `/worktrees` |
| **Sensitive Files** | ⚠️ **Ask** | `.env`, `.npmrc`, `.vscode`, `.git-credentials`, etc. |
| **Root/App Settings** | 🚫 **Denied** | Direct modifications to `/config` and main `.gemini` configurations |
---
### 🔧 Configuration and Management
* **Persistent Settings**:
To enable sandboxing by default for all future sessions, configure the `enableTerminalSandbox` setting in your `~/.gemini/antigravity-cli/settings.json`:
```json
{
"enableTerminalSandbox": true
}
```
* **Dynamic Adjustments**:
Within an active CLI (`agy`) session, you can run the `/permissions` slash command to view or modify your autonomy and sandboxing levels on the fly.
> [!NOTE]
> Running in sandbox mode provides an excellent balance of autonomy and security, allowing me to execute build commands, run test scripts, and manage project files safely without risk to your primary host environment.
Please let me know if you would like me to set up a new project workspace or run any specific tasks within this session!
- Move the preview button before the single-diff tooltip in the header
- Extend canOpenPreviewToSide to allow single diffs (not commit diffs)
when the modified file still exists on disk, since the preview
renders the working-tree file rather than diff content
- Add tests covering HTML edit tabs, unstaged diffs, deleted files,
commit diffs, and non-HTML diffs
* Support WSL Codex settings promotion and harden config write-back
- Enable settings promotion for WSL runtimes using per-distro baselines.
- Create parent directories if missing to prevent promotion ENOENTs.
- Keep restrictive permissions (0600) and follow symlinks on promote.
- Respect CRLF line endings when inserting keys into CRLF config files.
- Skip redundant baseline file writes when settings are unchanged.
- Include the release scan report for the 1.4.131-rc2 prep.
* Refactor sleeping agent wake flow and fetch rate limits via backend
- Background-mount only targeted terminal tabs during passive wake to
prevent spawning unnecessary PTYs for unvisited tabs.
- Latch edge-triggered wake requests that arrive mid-hibernation and
track active claims to prevent double-resuming a provider session.
- Query the ChatGPT wham usage backend API directly with fetch for
rate limits, avoiding launching Codex or WSL login shells.
- Asynchronously probe and serialize WSL auth files with timeouts to
prevent synchronous I/O from stalling Electron's main process.
- Fix config promotion edge cases such as missing parent directories,
dangling symlinks, and atomic write permission widening.
* Support WSL dotfile-symlink write-back and lengthen redeem timeout
- Preserve symlinked Codex config on WSL by writing through the
existing file instead of atomic-rename, since \\wsl$ symlink
metadata isn't reliably detected and rename would clobber the link.
- Tighten new ~/.codex directory creation to 0700 (holds auth.json).
- Give explicit reset-credit redemption a 30s backend timeout instead
of the 10s background-poll default, since it's user-triggered.
- Read sleeping-agent session state from the worktree's actual
execution-host partition instead of always the local one, so the
headless-wake check works correctly for SSH-hosted worktrees.
- Isolate serve-sim watcher tests from the real $TMPDIR/serve-sim
state file to avoid leaking unrelated events.
- Removes the `behavior`/`sidebarRevealBehavior` plumbing throughout
activation and reveal call sites now that every reveal jumps
immediately, eliminating the need to special-case newly created
worktrees.
- Reworks worktree-sidebar-reveal.ts to center the target row within
the viewport and temporarily pad list boundaries so first/last rows
can still center instead of clamping to the edge.
- Drops the reduced-motion e2e workaround since reveals no longer
animate.
- Fail queued removals that reveal concrete git risk (dirty files or
unpushed commits) discovered after an unverifiable force approval.
- Clear a failed row's queued-for-deletion sidebar overlay as soon as the
row fails instead of when the whole batch settles (new onRowFailed).
- Skip the auto-scan on dialog reopen while a removal batch is running;
the removal's scan invalidation would discard it immediately.
Co-authored-by: Orca <help@stably.ai>
* Prevent continuous git status scanning in large repositories
On repos where `git status --untracked-files=all` takes tens of seconds,
the background status poll restarted a fresh scan 3s after the previous
one finished, keeping a git process at high CPU almost continuously
while the workspace sat idle (#7983).
The coalesced poll runner now paces reruns by the previous run's
duration, split by trigger class:
- Evidence-free timer ticks wait 5x the last refresh duration (capped
at 5 minutes), bounding idle polling to ~1/6 duty cycle.
- Change signals (file-watch events, repo metadata pushes, finished
terminal commands, window reveal after hidden) wait only 1x, so real
changes in a slow repo still surface promptly; a change signal can
pull an already-scheduled tick run earlier, and the strongest pending
trigger wins for trailing reruns.
- Backoff-deferred scans are skipped while the window is hidden; the
becoming-visible run catches up on the short lane.
Fast repos keep the exact 3s cadence (the multiplier never drops the
gap below the existing floor), and user-triggered refreshes are
unaffected (they bypass the poll runner). The stale-conflict poll gets
the same pacing, which also spaces slow remote SSH probe chains.
Fixes#7983
* Skip hidden-window stale-conflict probes like the status poll
---------
Co-authored-by: Brennan Benson <brennanbenson@Brennans-MacBook-Pro.local>
The longer-hyphen recovery path (#5222) reconstructed runs by writing a
value that differed from the native field text. After #7933 stores raw
field text and normalizes only on send/PTY, that recovery is unreachable
and any write-back would reintroduce dictation kill. Map each smart dash
to exactly "--" with a single-arg normalizer.
PR #5071 (36277801e) accidentally dropped the LinearAgentSkillSetupPrompt
modal from WorktreeCard, orphaning the component. Restore the exact
wiring: render on the active worktree when it has a linked Linear issue.
Also surface the decoupled orca-linear agent skill on the Linear task
provider settings card: install state via useInstalledAgentSkillNames,
copyable install/update command resolved for the agent runtime, and a
remote-setup note when a runtime environment is active. The legacy-aware
update-command selection moves into a shared lib module so the sidebar
prompt and the new CTA stay in sync.
Co-authored-by: Brennan Benson <brennanbenson@Brennans-MacBook-Pro.local>
* Consolidate mobile source control into a single tabbed hub
Unify the changes list, pull request details, and commit history into
a single multi-segment panel. This improves navigation and state sharing
across different lenses of a worktree's source control.
- Add a segmented control to switch between Changes, PR, and History
- Introduce a persistent branch status card with an integrated PR chip
- Redirect standalone PR and history routes to the new unified hub
- Extract reusable UI and logic for the history list and PR summary
* Keep mobile source control tabs mounted to preserve view state
* Keep PR and History segments mounted (using display: 'none' when hidden) to preserve fetch, scroll, and expand states during tab switches.
* Decouple the History list from blocking on Git status loading.
* Support deep linking directly into the history tab of the main panel instead of using a standalone route.
* Enable retrying failed loads by reviving the transport loop if parked.
* Fix PR chip accessibility label and comment check.
* Optimize and integrate mobile PR view within source control hub
- Lazy-load heavy PR comments and descriptions (Phase 2) only when the
PR tab is active, using fast metadata (Phase 1) for the branch chip.
- Unmount the PR body when inactive to avoid unnecessary comment tree
re-renders and preserve WebView resources during commit text editing.
- Implement soft-refresh on HEAD advancement to keep the ready UI
visible while re-fetching checks post-commit.
- Display the "Aborting..." label only when a merge or rebase abort
is actively in flight.
- Memoize the git history list and skip branch identity RPCs when
gating the dock icon.
* Improve mobile git views and concurrent rendering safety
- Pass the `origin` parameter through history and PR redirect routes.
- Move source control panel ref updates to `useEffect` to prevent side
effects during concurrent renders.
- Resolve commit file changes to empty if disconnected to avoid a stuck
loading spinner.
- Standardize PR sidebar header button styling and accessibility labels.
* Resolve PR repo probe without active branch to avoid forever spinner
Previously, checking if a repository is a GitHub remote required an
active branch. In a detached HEAD or mid-rebase state (where the branch
is null), the probe never resolved, leaving the PR panel on a forever
spinner.
Decouple the repository probe from the branch presence so the panel
can correctly display the "Current branch unavailable" state. Also,
hide the PR status chip when no branch is active to avoid a spinner
on the chip.
* fix: propagate hook-only agent status to Remote Orca Server clients
On a headless Remote Orca Server, agent-status hooks (OSC 9999) updated the
retained row map but never republished PTY-backed session snapshots — only
terminal *title* changes did. Paired desktop/web/mobile clients therefore
kept a stale agent state (e.g. opencode working/idle) until relaunch, and
even title-driven updates carried an empty prompt and no agent identity
because the snapshot builder only used the title heuristic (#7970).
- retainAgentRowSnapshot reports client-visible changes (state, prompt,
agent type, tool, interactive prompt, interrupted) so handlePtyData can
republish snapshots on hook-only transitions without fanning out a
rebuild per repeated same-state hook ping.
- buildPtyMobileAgentStatus prefers the fresh retained hook payload over
the title-only fallback, so clients see the real state/prompt/agentType
and interactive prompts. The non-agent-title suppression (#1437 stuck
spinners) still wins unless the hook shows a live tool/question signal,
and it now also covers leaf-backed panes with no PTY record.
Co-authored-by: Orca <help@stably.ai>
* fix: refetch remote projects when the client-events stream replays
worktreesChanged/reposChanged emitted during a transport gap are lost, not
queued. A quick drop can replay without flipping the environment
unreachable, so the reachability-transition refetch never runs and a
server-created worktree stays invisible until relaunch (#7970). Request a
debounced project refresh on the replay tag, mirroring the SSH-state
refetch that already rides it.
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Orca <help@stably.ai>
* fix(preflight): resolve WSL/SSH agent paths past shell aliases
LeanCTX and similar tools wrap claude/codex as interactive shell aliases.
command -v then returns alias text, which fails absolute-path detection and
hides installed agents (#7816).
Prefer bash type -P, then zsh type -p, then command -v for dash/sh fallback
in WSL agent discovery, WSL isCommandOnPath, and remote relay probes.
* fix(preflight): harden alias-safe PATH lookup chain
Require non-empty results between type -P, type -p, and command -v so bash
type -p empty success cannot skip later lookups.
* fix(preflight): resolve agent executables directly from PATH
---------
Co-authored-by: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com>
* Improve workspace cleanup list
Co-authored-by: Orca <help@stably.ai>
* Address workspace cleanup review feedback
Co-authored-by: Orca <help@stably.ai>
* Fix workspace cleanup perf findings
Co-authored-by: Orca <help@stably.ai>
* Avoid stale cleanup progress cache
Co-authored-by: Orca <help@stably.ai>
* Complete workspace cleanup perf fixes
Co-authored-by: Orca <help@stably.ai>
* Fix worktree list option forwarding
Co-authored-by: Orca <help@stably.ai>
* Address workspace cleanup review nits
Co-authored-by: Orca <help@stably.ai>
* Fix workspace cleanup removal review findings
- Fail a queued removal that now needs a force the user never approved
(confirm-time approvedCandidates snapshot compared in preflight)
- Reword the 120s removal timeout to say removal continues in background
- Wire suppressPreservedBranchToast into cleanup removals
- Stop statting a repo after the first activity metadata timeout
- Document the WSL 9P best-effort stat gap; drop unused locale key
Co-authored-by: Orca <help@stably.ai>
* Split workspace-cleanup slice test to satisfy max-lines
Rebasing onto latest main pushed the combined store-slice test over the
800-line cap. Extract shared fixtures into a test harness and split the
suite into scan-progress and removal-preflight files instead of adding a
forbidden max-lines suppression.
---------
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Brennan Benson <brennanbenson@Brennans-MacBook-Pro.local>
The rpc-client has always emitted a detailed connection lifecycle log
(dials, timeouts, close codes, handshake steps, retries) via onLog, but
only the pairing screen wired it up — for long-lived host connections
everything went to console.log, invisible to users. Debugging reports
like #7824/#6928 meant asking reporters for facts the app already knew.
- connection-log-buffer: bounded (200/host) module-level ring buffer with
referentially-stable snapshots for useSyncExternalStore; survives
client swaps and provider remounts.
- client-context: wire onLog for every shared host client.
- connection-log screen: live per-host log (reuses the pairing
ConnectionLog component), host picker, and a Copy Diagnostics button
that bundles app/platform versions, endpoint (flagged if Tailscale),
state, attempt count, last-connected, and the event log into one
shareable blob.
- troubleshoot: 'View connection log' entry point.
Co-authored-by: Orca <help@stably.ai>
* Harden layout validation, watcher lifecycle, and connection robustness
- Throw instead of silently skipping when the packaged daemon-entry is
missing, preventing layout regressions from passing build checks.
- Terminate idle parcel-watcher processes to reclaim native handles and
avoid crash-prone native node module teardowns on shutdown.
- Bind the persisted WS fallback port first to prevent orphaning active
mobile pairings when the preferred port becomes free again.
- Cap concurrent disk reads for restored dirty tab verification at three
to prevent startup connection bottlenecks on remote SSH workspaces.
* Queue file IDs instead of snapshots in restored conflict scans
This avoids using stale file snapshots (e.g., outdated disk signatures)
if a tab is saved, closed, or re-baselined while waiting in the queue
behind the concurrency limit. The live state is now fetched from the
store and validated immediately before initiating the disk read.
A wedged Tailscale tunnel (known iOS failure mode) produces no AppState
or network-type transition, so no revival nudge ever fires and the
reconnect loop parked permanently at its give-up cap — users had to
toggle Tailscale off/on just to force a transition (#7824).
- rpc-client: past the give-up cap, drop to a 90s trickle dial instead
of parking so the session self-heals once the tunnel recovers.
- host screen: nudge the shared client on focus so opening the host
retries immediately instead of waiting out a backoff/trickle timer.
- connection-health: warning/unreachable verdicts on 100.64/10 or
*.ts.net endpoints now carry a 'check Tailscale' hint, shown on the
home host list and the in-session status line after ~3 failed
attempts.
- troubleshoot: 'Cannot reach <tailnet-ip>' now says to check
Tailscale, adds a dedicated Tailscale section, and stops telling
Tailscale users to disable their VPN (that advice killed their only
route to the host); sections extracted to
troubleshoot-common-issues.tsx to stay under the max-lines cap.
Co-authored-by: Orca <help@stably.ai>