* fix(renderer): fix unescaped quote lint error in GeneralPane
* refactor: replace allowPrerelease workaround with generic feed URL
Use electron-updater's generic provider pointed at GitHub's
/releases/latest/download/ so the manifest always comes from the latest
stable release. This eliminates the client-side RC filtering, the GitHub
releases API fallback, and the manual-download path entirely.
Persist edit-mode files in the workspace session so they are restored
on restart. Diffs and conflict views are intentionally excluded as they
depend on transient git state.
* fix: fall back to stable release when electron-updater picks an RC
When the latest GitHub release is an RC, electron-updater (with
allowPrerelease enabled) reports it as available and never considers
older stable releases. Previously the code simply rejected the RC and
sent not-available, silently hiding real stable updates.
Now the update-available handler calls findFallbackReleaseVersion()
when it detects a prerelease, which queries the GitHub releases API
(filtering out prereleases/drafts) to find the newest stable version
newer than what's running and offers it as a manual download.
* fix: persist check timestamp when RC fallback fetch fails
The .catch path in the update-available RC handler was missing
recordCompletedUpdateCheck(), which meant a failed GitHub API call
during fallback would not persist the check timestamp. On next app
launch the interval check could fire immediately instead of waiting
the full 36 hours.
* feat: improve terminal compatibility with default fonts across platforms
Add cross-platform monospace font fallback chain (SF Mono, Menlo, Monaco,
Cascadia Mono, Consolas, DejaVu Sans Mono, Liberation Mono) so the terminal
renders correctly on macOS, Windows, and Linux out of the box.
- Platform-aware default font in settings (SF Mono / Cascadia Mono / DejaVu)
- buildFontFamily deduplicates user font against full fallback chain
- Error handling for pty spawn failures with user-facing error banner
- Zero-dimension diagnostic when terminal container has no layout
- WebGL context loss / unavailability logging for debugging
* feat: improve terminal font fallback and pty error handling
- Add cross-platform terminal font fallbacks
- Surface pty spawn errors to terminal UI
- Fix max-lines eslint error in TerminalPane
- Fix curly braces eslint error in constants.ts
* fix: defer updater quitAndInstall to allow React/UI state to settle
PR #299 introduced a regression where the one-click auto-update flow
would synchronously invoke `quitAndInstall` immediately upon receiving
the `downloaded` state transition. This triggered a synthetic `beforeunload`
event (to capture terminal buffers) and an IPC call to quit in the exact
same event loop tick that React and the Toast library were processing
state updates. This disrupted the renderer's synchronous shutdown and flush
logic, causing the app to fail to quit and install properly.
This adds a `setTimeout` to defer `quitAndInstall`, pushing it to the
bottom of the event queue. This allows the UI state to settle and ensures
the `beforeunload` flush sequence executes cleanly.
Test cases have also been updated to use fake timers.
* fix: centralize updater restart deferral in main process
The `gh api --cache 60s` flag caused stale check-run data even when
the user explicitly clicked refresh. Thread a `noCache` flag through
IPC so manual refreshes skip the gh CLI cache while polling still
benefits from it.
* clean-up-repo-local-setup-script
- Add authorization cache for worktree roots to improve filesystem read performance
- Use ensureAuthorizedRootsCache instead of rebuilding on every list operation
- Fix useMemo side effect in WorktreeList by returning sorted IDs directly
- Add error display in QuickOpen and FileExplorer for unauthorized paths
- Improve section order in SourceControl (unstaged, staged, untracked)
- Add keyboard shortcut guard in WorktreeList for arrow keys
- Address review findings from code quality checks
* fix: update test mocks for filesystem-auth cache integration
- filesystem.test.ts: invalidate auth roots cache in beforeEach to
prevent stale cache state from leaking between tests
- worktrees.test.ts / worktrees-windows.test.ts: add store.getRepos
mock return value so rebuildAuthorizedRootsCache can iterate repos
- worktrees-windows.test.ts: add third listWorktrees mock for the
cache rebuild call consumed during worktrees:create
* fix: resolve oxlint errors for max-lines and missing useEffect dependency
- Extract repeated worktree mock data into shared variable to reduce
worktrees.test.ts below the 300-line limit
- Add missing 'toggleSidebar' to useEffect dependency array in App.tsx
- Add local image insertion support with file picker and toolbar button
- Harden image copy with COPYFILE_EXCL flag to prevent overwrites
- Add deconfliction loop limit (1000 iterations) to prevent hangs
- Force image re-render on filePath change for correct URL resolution
- Extract toolbar button into reusable RichMarkdownToolbarButton component
- Use setHeading (not toggleHeading) for idempotent slash commands
- Add path utilities (dirname, joinPath) with comprehensive tests
- Add image utility functions for safe copy destination handling
* fix: address review findings
- Default to 'editor' target when drop lands outside tagged zones,
preserving the prior open-in-editor behavior for sidebar/editor body drops
- Add trailing space after each terminal-dropped path so multi-file drops
are properly separated in terminal input
* feat: route native file drops to editor vs terminal by drop surface
Add data-native-file-drop-target markers and IPC target field so the
preload can classify OS drops before forwarding to the renderer.
* feat: add explicit worktree setup flow
- Centralize worktree activation setup flow
- fix: render orca.yaml file contents in settings repo pane instead of tags when using config file
- fix: command preview title for yaml configs
- fix: update UI copy and styling to better reflect yaml setup hooks
- fix: run setup hook in background if CLI worktree is created while GUI is closed
- fix: prevent duplicate terminal tab creation when creating worktrees from the UI
- fix: ensure CLI worktree create returns correct payload type and hooks up UI setup flow
- Squashed commits
- fix minor regression
- fix: close worktree context menu when deleting
- fix: keep delete dialog open while archive hook runs and support inline yaml scripts
- chore: fix lint, typecheck and react state mutations during render for setup script feature
* fix(lint): split worktrees.test.ts to stay under max-lines limit
Extract Windows path-handling tests into worktrees-windows.test.ts
to bring the original file under the 300-line oxlint max-lines rule.
* fix(test): set up path mocks for setup launch payload test
The computeWorktreePathMock and ensurePathWithinWorkspaceMock were
cleared by afterEach but not re-established in the test, causing
areWorktreePathsEqual to receive undefined and crash.
* feat: allow opening files outside the worktree in the editor
Fixes an issue where prompting Claude Code to open a file outside the worktree
would fall back to opening the default system viewer, and dragging external files
into Orca wouldn't work.
- Replaced `shell.openFilePath` fallback with internal `store.openFile` for
external files clicked in the terminal.
- Added a global drag-and-drop handler (`useGlobalFileDrop`) that resolves
external file paths and opens them natively in Orca.
- Used `window.api.fs.stat` to prevent opening directories directly in the editor,
falling back to the OS system viewer.
Closesstablyai/orca#271
* fix: authorize external editor file opens
* feat: add update reminder component and background polling
* refactor: replace update reminder banner with subtle bottom-right toast
Swap the full-width top banner for a compact fixed-position toast in the
bottom-right corner, matching the existing Sonner toast styling. Also
extract pure functions (statusesEqual, isBenignCheckFailure) from
updater.ts into updater-fallback.ts to fix max-lines lint error.
* fix: mock checkForUpdates to return a promise so .catch() works in tests
* feat: add copy remote URL to line number context menu
Add 'Copy Remote URL' option to the line number gutter right-click menu,
allowing users to quickly copy a shareable link to a file and line on
GitHub, GitLab, Bitbucket, or other hosted git providers.
- Install hosted-git-info to parse remote URLs and generate browse URLs
- Add getRemoteFileUrl() to resolve file URLs using default branch
- Wire up IPC handler, preload bridge, and renderer UI
- Use ExternalLink icon to distinguish from path copy options
* refactor: use @types/hosted-git-info instead of custom type declarations
Replace the custom hosted-git-info.d.ts with the @types package from
DefinitelyTyped. Use a targeted cast for browseFile() which the @types
package doesn't include yet (stuck on v3 API).
* refactor: revert to local type declarations for hosted-git-info
The @types/hosted-git-info package is stuck on the v3 API and lacks
browseFile(). A local .d.ts is cleaner than casting around stale types.
* fix: address review findings
- Add sandbox="allow-same-origin" to PDF iframes to prevent script execution
- Wrap atob() in try/catch to gracefully handle corrupt base64 data
- Reset imageError state on content change to allow re-rendering
- Add click overlay on PDF iframe so popup open works correctly
- Compact test mock resets to stay within max-lines lint rule
* fix: consolidate binary preview tests to stay within max-lines limit
- Reject worktree creation if the computed branch name already exists locally, on a remote, or in PR history. This prevents a fresh worktree from inheriting a stale/merged PR immediately after creation.
- Wrap getPRForBranch in try/catch so GitHub API failures don't block worktree creation
- Fix remote branch matching to compare full branch name after refs/remotes/<remote>/ prefix, preventing false positives
- Wrap updateWorktreeMeta in try/catch so meta-update failures don't leave the dialog in an error state for an already-created worktree
* feat: show ShieldAlert icon for conflict-review tabs
Display a distinct orange ShieldAlert icon for tabs opened in
conflict-review mode, differentiating them from regular diff tabs.
* fix: clear stale Rebasing/Merging badge on non-active worktrees
The git status polling only runs for the active worktree. When a
non-active worktree finishes rebasing, its conflict operation was
never updated to 'unknown', leaving the badge stuck.
Add a lightweight git:conflictOperation IPC (fs-only, no git subprocess)
and poll it for non-active worktrees that have a non-unknown operation.
Once the operation clears, the worktree drops out of the poll list.
Enable --hidden flag for ripgrep so dotfiles users commonly edit
(.env, .github/*, .eslintrc, etc.) appear in quick-open results.
Use a blocklist of tool-generated hidden dirs instead of blocking
all dot-prefixed paths.
Key changes:
- Add --hidden to rg and filter via HIDDEN_DIR_BLOCKLIST
- Add second rg call with --no-ignore-vcs to surface .env* files
- Use fast string-slice prefix stripping with path.relative() fallback
- Guard against path traversal in the fallback path
- Handle Windows path separators via --path-separator and normalization
- Collect into shared Set to avoid duplicate array spread
Expose whether a worktree is the repo's main working tree (the first
entry from `git worktree list`). This lets consumers distinguish the
main worktree from linked worktrees created via `git worktree add`.