Commit Graph
7179 Commits
Author SHA1 Message Date
Yu Sun 2cbcf03b0f fix: qualify ssh fallback worktree paths (#7764) 2026-07-24 00:24:58 -07:00
6d39e49480 fix(ssh): accept GitHub restricted-shell SSH probes (#6988) (#7659)
* fix(ssh): accept GitHub restricted-shell SSH probes (#6988)

* fix: match first stderr line for GitHub restricted-shell probe (bug-bash takeover)

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
Co-authored-by: Orca <help@stably.ai>
2026-07-24 00:24:53 -07:00
Matteo Musacchio c1d2c4be08 Fix PowerShell worktree terminal cwd (#7435) 2026-07-24 00:24:48 -07:00
github-actions[bot] cda97cec41 Update README downloads badge 2026-07-24 07:10:19 +00:00
Brennan Benson efe996a007 ci(release-cut): add explicit version override to the cut dispatch (#10329)
* ci(release-cut): add explicit version override to the cut dispatch

Kind-based computation derives the next version from the latest *published*
stable. When a shipped stable is deleted/rolled back, the release list
regresses to the prior stable, so a `kind` cut recomputes a number at or
below the deleted one — stranding every client that already installed it,
since electron-updater only moves forward. The existing package.json floor
only recovers this when the deleted version's bump commit is on the ref
being cut, which a hotfix cut from an older RC ref does not carry.

Add an optional `version` workflow_dispatch input that lets a human assert
the exact target (e.g. leapfrog a deleted 1.4.154 to 1.4.155), bypassing
kind-based computation. The updater-safety gate (must exceed the latest
published stable) and the existing tag-collision recovery still apply.
Empty by default, and forced empty for scheduled cuts, so normal automation
is unchanged.

* ci(release-cut): let explicit version override the package-floor recovery

Per review: the package.json floor block can recover_unpublished_tag and
exit 0 before the explicit-version branch runs, hijacking an explicit
request to recover a floor tag instead — the exact rollback scenario the
override targets. Skip floor-tag recovery when EXPLICIT_VERSION is set;
latest_stable is still raised to the floor for the safety gate, and the
requested tag's collision recovery runs later.
2026-07-24 00:09:07 -07:00
BingZ 2cf41ab864 fix(mobile): keep terminal caret visible without focus (#10101) 2026-07-23 23:55:35 -07:00
Wooseong Kim 4274dbc48a fix(linear): union filter options across every selected team (#10042) 2026-07-23 23:51:54 -07:00
Fazal KadivarandCursor 34caad787c fix(browser): unstick Ctrl+Tab switcher when opened from a focused browser guest (#9966)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 23:48:07 -07:00
余辉 fa09d6fd8e fix(tasks): hide repos without remote identity (#9898) 2026-07-23 23:46:01 -07:00
Rod Boev 108a2ad41b fix(cli): relativize absolute --path for file open and file diff before the runtime RPC (#9429) (#9824) 2026-07-23 23:43:15 -07:00
Shahar Mor 877bbdebf8 fix(agents): stop forking a duplicate Pi tab for a live background session (#9729) 2026-07-23 23:42:35 -07:00
92696558c3 fix(settings): gate project path setup on host connection (#9410)
Co-authored-by: linshengtao <linshengtao@bytedance.com>
Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
2026-07-23 23:38:43 -07:00
Rod Boev 817197fc31 fix(terminal): close tabless PTYs through the live pane path (#9288) 2026-07-23 23:33:08 -07:00
microtaroandClaude Fable 5 001a5c6846 fix: pane divider drag-to-resize never moves under WSLg (mouse down, pen motion) (#9153)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 23:31:35 -07:00
c03e8f6f64 fix: enumerate IPv6 addresses for mobile pairing on IPv6-only hosts (#9130) (#9131)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: PannenetsF <fanyunqian.1@bytedance.com>
2026-07-23 23:31:10 -07:00
Trevin ChowandOrcaWin bd45d705bf fix(tab-bar): open absolute local paths from worktree tab create entry (#10222)
* fix(tab-bar): open absolute local paths from worktree tab create entry

Local worktrees can paste absolute file paths into tab create; remote and
SSH workspaces stay blocked. Harden classifier ordering, ownership gating,
and render-time fail-closed behavior from review.

* fix(tab-bar): restore typecheck after worktree path refactor

Add the missing editor file-operation import, finish the global file
drop relative-path helper migration, and align the runtime env test mock.

* fix(tab-bar): fail closed for absolute local paths

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-07-23 23:26:39 -07:00
katspaughandClaude Sonnet 5 462020d372 fix: link to repo root instead of 404ing /stargazers page (#8756)
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 23:21:29 -07:00
moseoh 832aa69ce8 fix(tasks): resolve PR work items upstream-first under 'auto' like issues (#8727) 2026-07-23 23:20:52 -07:00
Stanislav Markin 91884b6d5f fix(sidebar): let project and group headers drag by their icon (#8576) 2026-07-23 23:19:43 -07:00
BingZ 4c7bbed2fb fix(windows): detect Cursor Agent Node wrapper (#8266) 2026-07-23 23:18:50 -07:00
Rod Boev c63ab965d8 fix(terminal): open WSL file links on Windows (#8215) 2026-07-23 23:18:31 -07:00
gatsby74andBrennan Benson 65f245f074 fix(editor): focus Explorer-opened Markdown for find (#8083)
Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
2026-07-23 23:18:03 -07:00
SeoYeonKim 933cee633e fix(editor): open files in the focused pane when it is a browser (#6891) (#8014) 2026-07-23 23:17:10 -07:00
Mark XianandClaude Opus 4.8 afa549f1d2 fix(gitlab): open the New-MR page on the fork project for fork-pushed branches (#7654)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 23:10:54 -07:00
Mark XianandClaude Opus 4.8 9373f5d37a fix(relay): expand Windows ~\ paths in session.resolveHome (#7650)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 23:10:38 -07:00
Jinjing c88cf8413f docs: finish Android APK 0.0.32 link rollup
Point localized READMEs and in-app Android download CTAs at
mobile-android-v0.0.32 (English README and orca-site were already updated).
2026-07-23 22:20:43 -07:00
Jinjing b36ae94e8d docs: add folder workspace use case guidance to AGENTS.md
Folder workspaces are a first-class workspace type that all changes must consider
alongside git worktrees. Document this requirement for developers.
2026-07-23 22:20:43 -07:00
github-actions[bot] 20ce29ae88 release: v1.4.153-rc.3 2026-07-24 03:48:06 +00:00
Jinjing eab721e1f8 Route folder workspaces in worktree operations (#10269)
* fix: route folder workspaces in worktree operations (#10251)

Folder workspaces are not Git worktrees and never appear in the repo/worktree
catalogs, so they were falling through to unresolved cross-host routing and
failing closed on all owner-dependent operations. Extract folder workspace
ownership logic to a dedicated module and add dedicated routing for folder
workspace identifiers before checking Git worktree catalogs.

* persist folder workspace metadata on the FolderWorkspace record

Folder workspaces lack worktreeMeta rows; metadata updates (activity bumps, unread status, terminal focus) must call updateFolderWorkspace. Fixes routing so local folder workspaces resolve to 'local' even when unrelated runtimes exist (#10251).

* Fix folder workspace mutations routing through owners

Folder workspace updates and deletions were routing through the currently
focused runtime instead of the owning runtime. Add coordinators for
concurrent-update race prevention and activity-persistence coalescing.
Handle runtime-owned folders in editor file operations and terminal activity
tracking.
2026-07-23 20:46:14 -07:00
Antonio LourencoandOrcaWin fde063618b fix(remote): create paired agent sessions without host focus (#10193)
* fix(remote): create paired agent sessions without host focus

* test(remote): assert structured resume request

* test(remote): preserve provider-separated resume coverage

* test(remote): assert paired agent focus authority

* fix(remote): separate agent host creation from viewer focus

* test(remote): harden agent-session authority validation

* test(remote): validate retired pane identity

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-07-23 20:20:00 -07:00
Jinjing 381e81e7bd fix(worktree): don't path-sweep sibling sessions when deleting a folder workspace (#10252) (#10268)
* fix(worktree): don't path-sweep sibling sessions when deleting a folder workspace (#10252)

Deleting one folder-workspace instance could kill terminal/agent sessions in
OTHER workspaces sharing the same checkout path — sibling instances, and even
worktrees of a different repo rooted under that directory. Both pi and Claude
Code agent sessions died at once with no recovery.

The `cwdOwned` path fallback in killAllProcessesForWorktree() derives its match
path via splitWorktreeIdForFilesystem(), which strips the `::workspace:<uuid>`
suffix and collapses a folder instance's path to the shared checkout dir. Every
untagged session under that dir then path-matched and got swept (worst case: a
home directory registered as a folder repo).

Disable the path fallback for folder-workspace instances — their filesystem
path can't identify a single instance. The exact `${worktreeId}@@` prefix and
authoritative `session.worktreeId` matches (both carrying the instance uuid)
still tear down the deleted instance's own sessions; normal git worktrees
(unique paths) keep the fallback. The runtime and registry sweeps already
matched by exact worktreeId.

Adds isFolderWorkspaceInstanceId() and regression tests. See
docs/delete-workspace-cwd-owned-sibling-kill.md.

* rm design doc
2026-07-23 19:43:34 -07:00
Neil da19a9beda fix(terminal): stop the reveal fit from reflow-garbling inline TUIs on minimize→restore (#10158)
* fix(terminal): stop the reveal fit from reflow-garbling inline TUIs

grok (and other inline-viewport TUIs like Codex) render garbled after the
floating terminal is minimized and brought back up. On reveal the resume path
fit xterm synchronously right after re-attaching WebGL, whose cell metrics
differ from the DOM renderer's — so it could propose a one-column-off grid,
reflow xterm, then snap back a frame later (a net-zero resize "wiggle"). xterm's
main-buffer wrap→unwrap is not a perfect inverse, and an inline TUI that
diff-paints its pinned region redraws over the corrupted buffer.

Replace the unconditional synchronous reveal fit (fitAllPanes) with a gated fit
(PaneManager.fitAllPanesStable → fitRevealedPane):
- fit synchronously only when the fit element's pixels actually changed while
  hidden (a real resize the app must reflow for anyway, kept ahead of the async
  PTY size reassert so it can't forward a stale grid);
- if the pixels are unchanged but the grid diverged while hidden (snapshot /
  SSH-reattach direct terminal.resize, or an appearance/DPI change), repair it on
  a steady grid (requestStablePaneFit) so a sustained mismatch refits while a
  transient cell-metric wobble does not reflow;
- otherwise leave the pane alone.

The common minimize→restore is now a hard no-op with zero reflow. Also applied to
the window-wake reveal path.

* refactor(terminal): tighten reveal-fit comments + rename to fitAllRevealedPanes

Quality pass: make fitRevealedPane the single canonical explanation of the
reveal wobble and reduce the duplicated comments at the call sites to short
pointers; rename PaneManager.fitAllPanesStable -> fitAllRevealedPanes ("stable"
only described one of its three branches); symmetric early-returns in
fitRevealedPane. No behavior change.
2026-07-23 19:40:52 -07:00
NeilandOrca a05a7bb2f4 fix(status-bar): guard undefined provider window in usedPercent reduce (crashes d2c1da69, bb74236c) (#10271)
Co-authored-by: Orca <help@stably.ai>
2026-07-23 19:26:10 -07:00
Neil efaaf51136 Update AGENTS.md 2026-07-23 19:24:28 -07:00
0bb755151c fix(workspace-board): sync Linear on context-menu Move to Status (#10176)
* fix(workspace-board): sync Linear on context-menu Move to Status

The board's right-click "Move to Status" only wrote the local
workspaceStatus and silently dropped the Linear sync that drag-and-drop
performs. Thread an onAssignWorkspaceStatus callback from the drawer
through the kanban card chain into WorktreeContextMenu so the menu
funnels through the same local-first + Linear-sync path
(moveWorktreesToStatus) as drag-and-drop. Outside the board (sidebar
list) the menu keeps its local-only behavior.

* test(workspace-board): guard context-menu Move to Status routing

Extract the context-menu status-assign routing into a pure
planWorkspaceStatusAssignment helper (behavior-preserving) and unit-test
it, so the board Linear-sync vs sidebar local-only branch — the exact
path #10175 regressed on — cannot silently flip back unnoticed. Covers
board-sync-forwards-all-ids, local-only-writes-only-changed, and the
same-status no-op case.

Addresses code-review finding: the added drawer tests exercised the
sync wiring via a mocked LaneGrid but never the menu's routing branch.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: ElNelyo <ElNelyo@users.noreply.github.com>
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Co-authored-by: Orca <help@stably.ai>
2026-07-23 19:23:46 -07:00
1b01385872 fix(worktree): reconcile symlinked creates by Git identity (#10266)
* fix(worktree): match created worktrees through symlink roots

On immutable Linux, /home is often a symlink to /var/home. git worktree
list reports the realpath while Orca still holds the /home request path,
so creation failed with "Worktree created but not found in listing".

After local worktree add, fall back to realpath when string comparison
misses. Keep WSL listings on string comparison only (host realpath is not
authoritative there).

Closes #10170

* test(worktree): harden symlink reconciliation authority

* fix(worktree): reconcile creation by Git branch identity

* test(worktree): reproduce symlink-root listing with real Git

* test(worktree): cover cross-platform reconciliation

* fix(worktree): keep reconciliation main-only

---------

Co-authored-by: Wooseong Kim <innocarpe@gmail.com>
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-07-23 19:12:54 -07:00
Brennan Benson e4202093c0 fix(terminal): re-verify cached macOS login-preflight rejections (#9973)
* fix(terminal): re-verify cached macOS login-preflight rejections

A conclusive PAM rejection was cached for the process lifetime, so one false
verdict (the probe runs over pipes, not a PTY) disabled the login(1) TCC
attribution wrapper for a daemon that survives app quits and updates for
weeks — reintroducing the every-invocation AppData prompts #7003 fixed.
Rejections now re-verify after 30 minutes; accepted verdicts still cache
for the process lifetime.

Refs #9756

* fix(daemon): replace hosts with stale login preflight cache

Protocol 26 shipped the process-lifetime PAM rejection cache. Preserve its live sessions as a legacy generation, but route fresh terminals through protocol 27 so updating actually loads the expiring-cache fix.

Refs #9756

* fix(terminal): validate rejected login probes under a PTY
2026-07-23 19:12:13 -07:00
Mark Xian e3adb20917 fix(agents): include OMP terminals in cold session restoration (#8991)
Preserve OMP session identity and exact resume paths across cold restoration, AI Vault, mobile, WSL/SSH, and host-authority routes. Add mixed-version fallback and completed-session recovery coverage.
2026-07-23 19:05:22 -07:00
Neil 9181e2b6c1 perf(renderer): batch dashboard orchestration selection (#10149) 2026-07-23 19:01:25 -07:00
Neil a2b1185672 perf(mobile): trust healthy session tab streams (#10134) 2026-07-23 19:01:04 -07:00
Neil 943f9a077b perf(daemon): cache droppable stream membership (#10121) 2026-07-23 19:00:43 -07:00
Neil c8a251279a perf(pty): make delivery pressure tracking constant time (#10113) 2026-07-23 19:00:25 -07:00
Neil d95eae5ead perf(workspace): cancel local worktree scans (#10107) 2026-07-23 19:00:00 -07:00
NeilandOrca eec9014198 fix(terminal): hide SSH error toast under the reconnect banner (#10246)
* fix(terminal): hide SSH error toast under the reconnect banner

The z-50 TerminalErrorToast was stacking over the non-blocking SSH reconnect
banner with the raw ssh:connect failure. Suppress the toast while the banner
owns recovery and clear matching toast text so it cannot flash after reconnect.

* fix(terminal): strip only SSH-owned lines from aggregated terminal error

onPtyError newline-joins multiple PTY errors into one string, so the prior
startsWith() classification misfired on aggregated errors: an unrelated error
before the SSH failure left the stale ssh:connect text to flash after reconnect,
and an SSH-first error discarded any unrelated error. Classify per line and drop
only reconnect-owned lines, keeping the rest. Closes CodeRabbit's aggregation edge.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-23 18:59:24 -07:00
Neil 645ed9a3be fix(ssh): hold premature transport 'connected' until the relay is ready (#10157)
An SSH connect whose relay deploy fails permanently (e.g. a dev build
missing the platform relay package) drove an unbounded reconnect loop.
doConnect creates the relay session ('idle'), then connectionManager.
connect() drives the raw transport to 'connected' before the relay
establishes. That premature 'connected' was forwarded to the renderer,
which treats it as "host fully up": applySshConnectionStateChange bumps
tab.generation for stranded remote panes -> remounts TerminalPane -> the
pane connect gate re-invokes window.api.ssh.connect -> restarts the whole
cycle forever (and spams connected-gated reads that fail with "Remote
connection dropped").

Hold the premature 'connected' at 'deploying-relay' in onStateChange until
the relay session is 'ready'. doConnect still broadcasts the authoritative
'connected' directly after establish() succeeds. Gate on connectInFlight so
the hold is scoped to a live connect and never wedges a stray transport-blip
'connected' on a session left 'idle' by a relay version mismatch.
2026-07-23 18:59:03 -07:00
Brennan Benson 4e27e8e339 test(main): deflake worktree-watch non-ENOENT readdir test with atomic EACCES injection (#10261) 2026-07-23 18:58:26 -07:00
Jinwoo HongandOrcaWin fd72a89260 fix: bound Relay desktop setup handshakes (#10260)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-07-23 18:46:38 -07:00
NeilandOrca 52cef48fd7 fix(tab-bar): render tab close shortcut as text, not key caps (#10248)
Co-authored-by: Orca <help@stably.ai>
2026-07-23 18:40:27 -07:00
NeilandOrca aab112933e Revert "fix(memory): bound OOM-prone accumulators (#10179)" (#10255)
Co-authored-by: Orca <help@stably.ai>
2026-07-23 18:35:31 -07:00
Brennan Benson 6eb70d8370 fix(main): stop unhandled rejections from silently killing the app during startup restore (#9970)
* fix(main): log unhandled rejections durably and stop them killing the app (#9441)

Main had no unhandledRejection handler — Node's default killed the process
with a clean exit code and no macOS crash report, which is exactly the
silent startup-restore exit in #9441. Rejections now record a durable crash
breadcrumb (flushed to the trace sink) and the app stays alive; uncaught
exceptions still terminate but record the same breadcrumb first so field
exits stop being undiagnosable.

* fix(main): harden process error guard diagnostics

* fix(main): cap fatal-error records to stop a rejection storm stalling main

One broken resource can reject hundreds of concurrent restore chains, and
each durable record does a synchronous trace flush. Cap records at 20 per
60s window and carry the suppressed count into the next recorded event.

* fix(main): never rate-limit the fatal uncaught-exception breadcrumb

A rejection storm that exhausted the 60s record window would suppress the
one main_uncaught_exception record taken right before the re-throw kills
the process, recreating the undiagnosable death from issue #9441. Scope
the fixed window to main_unhandled_rejection only; the uncaught path
records at most once per install (handler removes itself, EPIPE/EIO never
record), so it cannot storm.

* fix(main): reset fatal-error window on backward clock jumps
2026-07-23 18:31:02 -07:00