Commit Graph
1206 Commits
Author SHA1 Message Date
brennanb2025andOrca 3abc7df25e chore: archive auto-review context for fix-session-hydration-data-loss
Co-authored-by: Orca <help@stably.ai>
2026-05-06 16:26:43 -07:00
brennanb2025andOrca 67fd80bb4a WIP: Changes before auto-review fixes iteration 3
Co-authored-by: Orca <help@stably.ai>
2026-05-06 16:24:57 -07:00
brennanb2025andOrca 149b6a192b WIP: Changes before auto-review fixes iteration 2
Co-authored-by: Orca <help@stably.ai>
2026-05-06 16:20:26 -07:00
brennanb2025andOrca c084b47c64 WIP: Changes before auto-review fixes
Co-authored-by: Orca <help@stably.ai>
2026-05-06 16:11:25 -07:00
brennanb2025andOrca e65380c30c WIP: Changes before auto-review fixes iteration 1
Co-authored-by: Orca <help@stably.ai>
2026-05-06 15:33:25 -07:00
brennanb2025andOrca 0777cc2c76 fix: prevent UI data loss and blank window on startup hydration failure
Addresses two gaps in the #1158 error path that mirrored the session
writer bug the PR fixes:

- Guard defaults-hydration in App.tsx catch with a uiHydrated flag so a
  late-stage startup failure can't overwrite already-loaded ui.json
  values (sidebar width, sort, filters) with hardcoded defaults.
- Wrap reconnectPersistedTerminals() in the catch with a try/catch and
  force workspaceSessionReady=true via setState on failure, so a crash
  in the recovery step can't leave the user staring at a blank window.

Also adds async-path coverage for the 1-hour backup rotation gate —
existing tests only exercised the sync flush path.

Co-authored-by: Orca <help@stably.ai>
2026-04-27 01:17:23 -07:00
brennanb2025andOrca 4b4542a68b WIP: Changes before auto-review fixes iteration 1
Co-authored-by: Orca <help@stably.ai>
2026-04-27 01:12:11 -07:00
brennanb2025andOrca d4564a14f6 WIP: Changes before auto-review fixes
Co-authored-by: Orca <help@stably.ai>
2026-04-27 00:46:35 -07:00
brennanb2025andOrca 11a7a29788 fix(session): gate writer on hydration success + roll backups (#1158)
Protects orca-data.json from two silent-data-loss failure modes:

- Fix A: add a `hydrationSucceeded` flag. The debounced + shutdown
  session writers now short-circuit until hydration completed without
  throwing, so a crash in fetchRepos / fetchAllWorktrees / session.get /
  hydrateWorkspaceSession can no longer serialize an empty in-memory
  store over the user's persisted tabs. The App.tsx catch handler no
  longer calls hydrateWorkspaceSession with empty defaults; it leaves
  the in-memory state untouched and only flips workspaceSessionReady
  (via reconnectPersistedTerminals) so the UI can mount.

- Fix B: rotate 5 rolling backups (.bak.0 – .bak.4) of orca-data.json
  before each overwrite, gated to at most one rotation per hour so the
  debounced tick doesn't churn disk. The current file is copied (not
  renamed) to .bak.0 so the primary file never temporarily disappears.

Defers to follow-ups: broadening the worktree-id filter guard (fix C)
and the fail-loud hydration error UI (fix D).

Co-authored-by: Orca <help@stably.ai>
2026-04-26 23:36:52 -07:00
Ramzi 8e44541c4c Add task provider icon setting (#1128) 2026-04-26 16:01:16 -07:00
Brennan Benson 1b02fcd505 fix(sidebar): constrain worktree list within add-repo dialog bounds (#1140) 2026-04-26 15:33:17 -07:00
github-actions[bot] ffb6688fd2 release: 1.3.21-rc.1 [rc-slot:2026-04-26-15] v1.3.21-rc.1 2026-04-26 22:07:45 +00:00
Jinwoo Hong 294256843c Improve terminal restore resilience (#1073) 2026-04-26 14:25:11 -07:00
github-actions[bot] a4da565430 release: v1.3.21-rc.0 v1.3.21-rc.0 2026-04-26 21:16:40 +00:00
Jinwoo HongandOrca 451d7cab42 fix(ssh): await root registration before remote worktree creation (#1120)
Co-authored-by: Orca <help@stably.ai>
2026-04-26 14:14:30 -07:00
JinjingandOrca 0431dd51f5 feat: improve SSH file search with configurable limits and rg fallback (#1130)
* feat: improve SSH file search with configurable limits and rg fallback

- fix: address lint issues (string template, ternary, max-lines via extraction)

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

* fix: typecheck and improve rg listing correctness

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-04-26 13:38:34 -07:00
fe6eecba0c feat(sidebar): improve PR checks and comments (#1134)
* feat(sidebar): improve PR checks and comments

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

* fix(sidebar): classify bot comments via GitHub user.type instead of login heuristic

Third-party review bots like qodo-ai-reviewer, coderabbitai, and sonarcloud
don't follow the [bot] suffix or "bot"/"automation" substring convention, so
the regex-based detector misclassified them as human. Plumb REST
`user.type === 'Bot'` and GraphQL `author.__typename === 'Bot'` through to the
renderer as an authoritative isBot flag; fall back to the login heuristic only
when the data source can't report it.

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

* fix(sidebar): allowlist AI review services that sign in as User accounts

qodo-ai-reviewer, coderabbitai, codium-ai and similar third-party review
services register as regular GitHub user accounts, so REST `user.type` is
"User" and their logins contain no "bot"/"automation" tokens. The previous
fix relied on the GitHub-reported type, which fails for these. Add an
explicit substring allowlist of known automation services so they still
land in the Bots tab.

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

---------

Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
2026-04-26 13:28:09 -07:00
Jinwoo HongandOrca 7720ed136c feat(tasks): server-side scope filtering, pagination, and draft bug fix (#1135)
Co-authored-by: Orca <help@stably.ai>
2026-04-26 12:30:22 -07:00
github-actions[bot] 738a08b712 release: v1.3.20 v1.3.20 2026-04-26 18:19:03 +00:00
NeilandOrca dd9bf888e9 fix(terminal): make Claude Code OSC 8 hyperlinks clickable (#1132)
Co-authored-by: Orca <help@stably.ai>
2026-04-26 11:18:02 -07:00
NeilandOrca a351b7a1cc fix(menu): auto-hide menu bar on Windows and Linux (#1133)
Keeping the menu bar always visible on Windows/Linux added a dedicated
row of vertical space on every launch, which users didn't want. Restore
the native convention (File Explorer, Firefox, etc.): menu bar is
hidden by default and revealed with Alt. The previous PR's template
restructure (File → Settings/Exit, Help → About/Check for Updates,
no redundant "Orca" entry) still applies when the menu is shown.

Co-authored-by: Orca <help@stably.ai>
2026-04-26 11:16:59 -07:00
github-actions[bot] 49d64294a3 release: 1.3.19-rc.13 [rc-slot:2026-04-26-03] v1.3.19-rc.13 2026-04-26 10:13:11 +00:00
github-actions[bot] eb0c952830 release: v1.3.19-rc.12 v1.3.19-rc.12 2026-04-26 07:49:02 +00:00
Neil bedb0d44c0 fix(persistence): unlink tmp file when write/rename fails (#1121) 2026-04-25 23:54:53 -07:00
github-actions[bot] 3a0149982f release: v1.3.19-rc.11 v1.3.19-rc.11 2026-04-26 06:23:26 +00:00
NeilandOrca ae9ddeab5c feat(cursor): first-class Cursor CLI agent status via hooks.json (#1108)
* feat(cursor): first-class Cursor CLI agent status via ~/.cursor/hooks.json

Give cursor-agent the same hook-driven status pipeline Claude/Codex/Gemini/
OpenCode already use so working/done/permission transitions show the proper
sidebar spinner instead of falling back to title heuristics — cursor-agent
only sets its OSC title to the literal string "Cursor Agent" during a turn,
so title-based detection cannot see working→done transitions on its own.

- New CursorHookService installs a managed shell script and registers it
  under ~/.cursor/hooks.json for beforeSubmitPrompt, preToolUse, postToolUse,
  postToolUseFailure, beforeShellExecution, beforeMCPExecution, stop, and
  afterAgentResponse (the subset that marks turn boundaries and surfaces
  in-flight tool context).
- AgentHookServer gains a /hook/cursor route and a normalizeCursorEvent
  mapping the camelCase cursor events to working/done/waiting, with tool
  previews for preToolUse/shell/MCP and lastAssistantMessage from
  afterAgentResponse. stop with status != "completed" surfaces as
  interrupted (matches Claude's is_interrupt behavior).
- cursorHookService joins the startup install loop alongside Claude/Codex/
  Gemini, and the IPC status handler is exposed via preload.
- 'cursor' added to WellKnownAgentType and to the renderer's
  WELL_KNOWN_LABELS so the dashboard prints "Cursor" rather than the raw
  'cursor' id.

Verified end-to-end against a real cursor-agent 2026.04.17-787b533 binary:
a mock hook receiver pointed at by ~/.cursor/hooks.json observes
beforeSubmitPrompt → stop for a live turn.

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

* feat(cursor): wire hook events into sidebar spinner + unread pipeline

The initial hook wiring landed behind AGENT_DASHBOARD_ENABLED, which is
still false. That meant cursor-agent panes lit up no spinner and no
unread indicator — cursor's native OSC title stays literally "Cursor
Agent" across a turn, so title-based detection cannot transition.

Plumb cursor's hook stream into the existing, shipped title-tracker
pipeline (the one Claude/Codex/Pi drive working/idle/unread off) by
synthesizing OSC title sequences in the main-process hook listener:

  - `working`  → `\x1b]0;⠋ Cursor Agent\x07`   (braille prefix → working)
  - `waiting`  → `\x1b]0;Cursor - action required\x07\x07`
  - `done`     → `\x1b]0;Cursor ready\x07\x07`

The two trailing BELs on done/waiting are load-bearing: the unread badge
keys off BEL (0x07 outside any OSC), and cursor-agent emits none on its
own. The first BEL is consumed as the OSC terminator; the second fires
the bell detector.

Also treats the bare native "Cursor Agent" title as a no-op in
`detectAgentStatusFromTitle` so cursor's own per-turn re-emissions cannot
stomp our synthesized working state back to idle. `isClaudeAgent`
excludes cursor-bearing braille titles so the Claude prompt-cache timer
doesn't fire for cursor panes.

Scope: the hook server + cursor install run unconditionally now, but
Claude/Codex/Gemini installs stay gated behind AGENT_DASHBOARD_ENABLED,
so only cursor events flow through the pipeline. No dashboard surface
is turned on.

Verified end-to-end in Electron (dev build): launched cursor-agent via
the Cursor menu item, submitted three prompts (including a tool-use
turn reading package.json). Observed tab title flip to "Cursor ready"
on done, and the tab + worktree both transitioned to unread
(unreadTerminalTabs[tabId]=true, worktree.isUnread=true). Parallel
Claude Code pane untouched.

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

* fix(cursor): animate spinner frames + filter bare native title so the spinner doesn't go solid mid-turn

cursor-agent re-emits its bare "Cursor Agent" OSC title on every internal
redraw, which was stomping the single synthesized "⠋ Cursor Agent" frame
in runtimePaneTitlesByTabId within milliseconds and flipping the sidebar
dot back to solid. Two-part fix:

- Main: drive an 80ms Pi-style braille spinner from the cursor hook
  channel, keyed by paneKey, torn down on pty exit via a new
  registerPaneKeyTeardownListener hook in ipc/pty.
- Renderer: drop bare "Cursor Agent" titles in pty-transport so cursor's
  native re-emissions cannot overwrite the synthesized working/idle
  titles.

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-04-25 23:14:31 -07:00
Brennan Benson 2154f032c2 test(tabs): guard first tab visibility when sidebar is collapsed (#1117) 2026-04-25 23:01:35 -07:00
github-actions[bot] a37fb32efb release: v1.3.19-rc.10 v1.3.19-rc.10 2026-04-26 05:30:10 +00:00
Jinjing e6ea8b466f fix: focus address bar for new browser tabs (#1119) 2026-04-25 22:28:42 -07:00
NeilandOrca d4399b4c92 feat(terminal): add programming-ligatures support (#1118)
Co-authored-by: Orca <help@stably.ai>
2026-04-25 22:26:33 -07:00
NeilandOrca 6e2c6e3585 feat: reduce drag grab area height from 8px to 6px (#1116)
Co-authored-by: Orca <help@stably.ai>
2026-04-25 21:56:08 -07:00
JinjingandOrca 7c8f990128 fix(tabs): always consume tab-switch chords to prevent xterm escape leaks (#1114)
Ctrl+PageUp/PageDown and Cmd+Shift+]/[ now always preventDefault and stop
propagation, even when the switch is a no-op (e.g. single terminal). xterm
otherwise translates these into escape sequences that leak into the shell
and flip the tab's bell indicator. Also skip redundant setActiveTab writes
in handleSwitchTerminalTab when the target is already active.

Co-authored-by: Orca <help@stably.ai>
2026-04-25 21:54:06 -07:00
NeilandOrca 6d3d366d45 feat(menu): show File/Edit/View/Window menu bar on Windows & Linux (#1111)
Co-authored-by: Orca <help@stably.ai>
2026-04-25 21:53:32 -07:00
NeilandOrca f8a0e07513 fix(terminal): submit startup commands on Windows without requiring manual Enter (#1115)
Co-authored-by: Orca <help@stably.ai>
2026-04-25 21:52:49 -07:00
NeilandOrca e61ffbcbe3 fix(tabs): prevent Cmd+B collapse from occluding first tab (#1112)
Co-authored-by: Orca <help@stably.ai>
2026-04-25 21:51:18 -07:00
NeilandOrca 6d585e821e ci: cache electron + electron-builder tool downloads on release (#1110)
electron-builder fetches the Electron binary and its platform tools
(notarytool, winCodeSign, nsis, squirrel, AppImage) on every run.
Cache those per-platform so repeat releases skip the re-download.
Saves ~30-90s per job, including the macOS long pole.

Key includes pnpm-lock.yaml so a bump to electron/electron-builder
invalidates stale cached binaries; restore-keys falls back to the
latest per-platform cache in between lockfile changes.

Co-authored-by: Orca <help@stably.ai>
2026-04-25 21:30:52 -07:00
Jinwoo Hong 7b25a02d1c feat(tasks): improve editability affordances (#1107) 2026-04-25 20:42:31 -07:00
Jinwoo Hong 6729825bc0 feat(ssh): persist and auto-restore SSH sessions across app restarts (#1026) 2026-04-25 20:15:02 -07:00
Yax PatelandJinwoo-H 2551758c88 feat/markdown preview (#849)
Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
2026-04-25 19:27:47 -07:00
github-actions[bot] b65a3d7cb8 release: v1.3.19-rc.8 v1.3.19-rc.8 2026-04-26 02:19:36 +00:00
Brennan Benson a5e5ce2900 feat(tabs): slimmer tabs with window-drag strip on top (#1059) 2026-04-25 19:06:39 -07:00
Brennan Benson 7c75e9a853 feat(terminal): show bell indicator until user interacts (#1068) 2026-04-25 19:05:53 -07:00
Matt Van HornandMatt Van Horn ff70ac0814 fix(diff): collapse redundant line-number gutters in inline diff view (#1091)
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-04-25 19:04:03 -07:00
NeilandOrca eeffbf0a73 ci: cache pnpm store on release + centralize node version in .nvmrc (#1106)
Co-authored-by: Orca <help@stably.ai>
2026-04-25 19:03:05 -07:00
Neil b9646acbe4 fix(pi): surface Pi working spinner on worktree card (#1083 follow-up) (#1105)
Pi's titlebar extension emits OSC 0 titles every 80ms during agent work
(`⠋ π - cwd`, `⠙ π - cwd`, …) and a trailing idle title on `agent_end`
(`π - cwd`). Node-pty on the main side batches output every 8ms, so the
renderer frequently receives multiple title updates in a single `pty:data`
chunk.

The pty-transport's data handler used `extractLastOscTitle`, which returns
only the final OSC title in a chunk. For fast agents (e.g. Pi with a small
local model) the whole working→idle cycle often lands in one IPC payload —
the intermediate working frames were silently dropped, and the worktree
card's `detectAgentStatusFromTitle` only ever saw the idle title.

Empirically on macOS: polling `runtimePaneTitlesByTabId` 20×/0.25s during
a multi-second Pi working window showed the stored title stuck at "Pi"
throughout, while a raw `ipcRenderer.on('pty:data')` listener captured
the working frames flowing through IPC correctly. After the fix, the same
polling captures "⠋ Pi" alongside "Pi".

- Add `extractAllOscTitles` in the shared agent-detection module and feed
  every OSC title in the chunk through `applyObservedTerminalTitle` in
  order, so the working→idle transition reaches the store and the agent
  tracker.
- Keep `extractLastOscTitle` exported for the main-process stats tracker
  and orca-runtime, which only care about the most recent title.
- Pin the regression with three focused tests: per-chunk spinner frames,
  dispatcher-routed end-to-end, and the exact coalesced-chunk scenario
  that used to swallow the working state.
2026-04-25 19:01:43 -07:00
555ab95d5a feat(shortcuts): add Ctrl+PageDown/Up to cycle terminal tabs only (#1094)
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
2026-04-25 18:45:21 -07:00
NeilandOrca c871f46ed3 fix(updater): let RC users upgrade to newer RC *and* stable releases (#1104)
PR #1053 fixed RC→RC by switching prerelease users to electron-updater's
native github provider with allowPrerelease=true. That silently broke
RC→stable: GitHubProvider.getLatestVersion() filters the atom feed by
channel, so when the running build's channel is "rc" any stable release
(channel=null) gets skipped — trapping the user on the RC channel.

Fix: keep the generic provider and resolve the newest tag ourselves by
parsing GitHub's /releases.atom (any channel, semver-newest strictly >
current version). For prerelease users we re-pin the feed to
/releases/download/<tag>/ before each check, which handles BOTH the
RC→newer-RC case from #1053 and the RC→stable case it broke. Stable
users keep the default /releases/latest/download/ feed untouched, and
the Shift-click RC opt-in path (enableIncludePrerelease) is unchanged.

Co-authored-by: Orca <help@stably.ai>
2026-04-25 17:49:35 -07:00
NeilandOrca 3f8ebb258d ci: remove pr-size-labeler backfill workflow (#1103)
The action refuses to run unless GITHUB_EVENT_NAME=="pull_request",
so workflow_dispatch no-ops. Backfill was completed out-of-band via
a local script calling the REST labels endpoint; this one-off
workflow is no longer useful and is being deleted.

Co-authored-by: Orca <help@stably.ai>
2026-04-25 17:40:26 -07:00
NeilandOrca 64c77d735a ci: add one-off workflow to backfill size labels on open PRs (#1102)
A manually-dispatched workflow that fans out across all open PRs and
runs the size labeler against each. This is a one-time verification
of the labeler against the existing PR set; the workflow will be
removed in a follow-up after it runs.

Co-authored-by: Orca <help@stably.ai>
2026-04-25 17:30:44 -07:00
NeilandOrca b96dc93d72 ci: auto-label PRs by size via cbrgm/pr-size-labeler-action (#1101)
Adds a GitHub Actions workflow and config that labels every PR with
size/xs..size/xl based on files changed and lines added, so reviewers
can see at a glance how big a PR is. Lock files and generated/vendored
paths are excluded, and deletions aren't counted so refactors that
remove code aren't over-penalized.

Co-authored-by: Orca <help@stably.ai>
2026-04-25 17:20:42 -07:00