PetOverlay loadStoredPosition now falls back to the legacy 'sidekick-overlay-position' localStorage key and write-throughs to the new key. Deleted orphaned src/main/ipc/sidekick-pet-bundle.ts and its test.
Rebased onto current main to resolve conflicts.
Co-authored-by: orca-bot <bot@stably.ai>
Made updateWorktreeMeta best-effort in launch-work-item-direct so a meta write failure no longer aborts the already-created workspace and orphans it.
### Findings addressed
- ✅ **[medium]** `src/renderer/src/lib/launch-work-item-direct.ts:243` — Meta update failure now aborts a successfully created workspace
Rebased onto current main to resolve conflicts.
Co-authored-by: orca-bot <bot@stably.ai>
Added process.on('exit') restore handler so the renamed spawn-helper is restored even if the vitest worker is killed mid-test.
Findings addressed:
- [low] src/main/daemon/node-pty-fd-leak.test.ts:57 — Test renames helper binary; crash leaves it hidden
Rebased onto current main to resolve conflicts.
Co-authored-by: orca-bot <bot@stably.ai>
Fixed onboarding next() re-entrance with a synchronous in-flight ref guard, and tightened sanitizeOnboardingUpdate's closedAt to require a finite non-negative number.
Findings addressed:
- [medium] src/renderer/src/components/onboarding/use-onboarding-flow.ts — next() not re-entrant
- [low] src/main/persistence.ts — sanitizeOnboardingUpdate accepts NaN/Infinity for closedAt
Rebased onto current main to resolve conflicts; preserved main's advancedVia parameter and duration_ms telemetry inside the new in-flight guard.
Co-authored-by: neil <neil@stably.ai>
Fixed Windows titlebar bugs: WindowControls icon now seeded via new ipc isMaximized() getter on mount; CSS height dropped from 42px to 36px; spacer added to floating right-sidebar toggle and RightSidebar header so content isn't occluded.
Findings addressed:
- [medium] src/renderer/src/App.tsx:50-54 — WindowControls maximize icon wrong on startup if window starts maximized
- [medium] src/renderer/src/assets/main.css:434-460 — Window controls 42px tall but titlebar 36px — bottom 6px overlays content
- [low] src/renderer/src/App.tsx:776-803 — Spacer only rendered in workspace-active titlebar branch
Rebased onto current main to drop ~140 unrelated stale-main reverts; only the 6 Fixer-summary files are touched.
Co-authored-by: orca-bot <bot@stably.ai>
Fixed 6 findings: legacy fetch fallback for local-only bases, memoized canonical fetch key, recorded reconcile token before await, cleared token in finally, configurable publish remote, and fetch-failure-aware base ref error.
Rebased onto current main applying only the Fixer-summary files (worktree-remote.ts, orca-runtime.ts) to avoid silent reverts from a stale base.
Co-authored-by: neil <neil@nous.com>
Users typing CJK or other non-ASCII names (e.g. 中文) into the Create
Workspace dialog hit "Invalid worktree name" because the sanitizer's
ASCII-only allowlist stripped every character, leaving an empty string.
Replace the allowlist with a Unicode-aware one (\p{L}\p{N}) so non-Latin
scripts pass through. Git ref-format and modern filesystems accept UTF-8.
Co-authored-by: Orca <help@stably.ai>
* feat(add-repo): auto-fill clone destination with workspace parent dir
Pre-fills the Clone from URL destination on first entry to the clone step,
deriving the parent directory of settings.workspaceDir so users with the
default config land at ~/orca instead of an empty field that blocks the
Clone button.
Closes#1592
* review: silence max-lines on AddRepoDialog
The PR pushes the file from 411 to 433 lines, over the 400-line cap
for src/renderer/. Matches existing precedent in this dir (RemoteFileBrowser,
WorktreeCard, WorktreeList all carry the same disable + why-comment).
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>
Co-authored-by: Orca <help@stably.ai>
Surface worktree creation immediately and reconcile remote base state
asynchronously, emitting drift/conflict events as fetches complete.
Co-authored-by: Orca <help@stably.ai>
* wip
* WIP: Changes before auto-review fixes
Co-authored-by: Orca <help@stably.ai>
* WIP: Changes before auto-review fixes
Co-authored-by: Orca <help@stably.ai>
* WIP: Changes before auto-review fixes
Co-authored-by: Orca <help@stably.ai>
* fix: address auto-review findings (iteration 1)
Co-authored-by: Orca <help@stably.ai>
* fix: address auto-review findings (iteration 2)
Co-authored-by: Orca <help@stably.ai>
* fix: archive review context and improve agent detection on wizard mount
Co-authored-by: Orca <help@stably.ai>
* fix: address CI lint failures and split use-onboarding-flow.ts
Co-authored-by: Orca <help@stably.ai>
* fix: mock ./onboarding in register-core-handlers test
Co-authored-by: Orca <help@stably.ai>
* fix: also toggle light class on documentElement so onboarding e2e theme wait resolves
The onboarding e2e calls waitForFunction(() => classList.contains('dark') || classList.contains('light')) before snapshotting the starting theme. applyDocumentTheme only toggled 'dark', so on a host that resolves system to light the wait timed out (CI Linux headless). Toggle 'light' as the inverse class so consumers can observe the resolved theme symmetrically; Tailwind keys only on 'dark' so styling is unchanged.
Co-authored-by: Orca <help@stably.ai>
* fix: add braces to Landing menu close-on-outside-click handler
oxlint config requires braces for all if statements.
Co-authored-by: Orca <help@stably.ai>
* chore: trigger CI
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Orca <help@stably.ai>
* Improve node-pty spawn diagnostics
* Preserve original error stack when adding node-pty recovery hint
Mutate the existing Error's message instead of replacing the object so
the original stack trace and custom fields survive into telemetry/logs.
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Orca <help@stably.ai>
Map .astro to a dedicated 'astro' language with frontmatter, embedded
script/style, and expression interpolation handling, instead of falling
back to plain html.
Co-authored-by: Orca <help@stably.ai>
#1524 stopped realpath'ing every worktree root during background refreshes
to avoid TCC prompts, which broke File Explorer for worktrees registered
under /var/folders when realpath canonicalizes them to /private/var/folders.
Lazily canonicalize the registered root only when the user actively touches
it: pass the pre-realpath source path through resolveAuthorizedPath so
isPathAllowedIncludingRegisteredWorktrees can match the canonical target
against the source's registered ancestor and cache the canonical root for
future lookups.
Co-authored-by: Orca <help@stably.ai>
Replace the default Windows native title bar with a custom renderer-drawn
titlebar to match the macOS experience:
- Set titleBarStyle:'hidden' on win32 to remove the OS chrome
- Add min/max/close buttons (Fluent-style SVG) fixed to the top-right corner,
rendered last in DOM order so they're never blocked by -webkit-app-region:drag
- Route close through IPC (window:close-requested) so the terminal-running
confirmation guard stays active; minimize/maximize via window:minimize and
window:maximize IPC channels
- Add maximize state sync (window:maximize-changed) so the restore icon shows
correctly
- Add Orca logo + ··· application-menu button on the left in place of the bare
pl-2 spacer; ··· calls Menu.getApplicationMenu().popup() replicating Alt-key
reveal
- Add window-controls-titlebar-spacer to reserve 138px on the right of the
full-width titlebar so content isn't obscured by the overlay
Co-authored-by: Neil Parker <nwparker@anthropic.com>
* Support Codex pet sidekick animations
* Refine Codex pet defaults and drop unused failed animation state
Always default spritesheetPath to spritesheet.webp when a manifest
omits it, even when explicit frame/animation metadata is present, so
non-Codex bundles still benefit from the standard sheet name.
Drop the 'failed' animation entirely — Orca has no failure state, so
mapping interrupted completions to 'failed' would conflate user
cancellation with agent failure. Codex spritesheets can still expose
a 'failed' row as an asset contract, but it's never selected at runtime.
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Co-authored-by: Orca <help@stably.ai>
Fixed banner Docs link to use openExternal IPC like the block variant; restricted hasKeyringFallback to same-host keyring accounts so multi-host users aren't told a fallback exists when none does.
Findings addressed:
- src/renderer/src/components/github-project/GhAuthErrorHelp.tsx:218-227 — Banner Docs link uses <a target="_blank"> instead of shell IPC
- src/main/github/auth-diagnose.ts:121-127 — hasKeyringFallback ignores host, can mislead multi-host users
Rebased onto current main to drop unrelated reverts.
Co-authored-by: orca-bot <bot@stably.ai>
Split session screen's clearTerminalCache cleanup into a mount-only effect; included client identity in home-screen wireUp dep key via a WeakMap-derived clientKey so forceReconnect re-attaches subs.
Findings addressed:
- mobile/app/h/[hostId]/session/[worktreeId].tsx:436 — clearTerminalCache fires on every client identity change
- mobile/app/index.tsx — useEffect deps array uses inline expression — runs every render
Rebased onto current main.
Co-authored-by: orca-bot <bot@stably.ai>
host-store: write AsyncStorage metadata before SecureStore token to avoid orphaned keychain tokens on crash. mobile IPC: coalesce repeated getPairingQR calls onto a single pending device token via new DeviceRegistry.getOrCreatePendingDevice.
Findings addressed:
- [high] mobile/src/transport/host-store.ts — saveHost orders Keychain write before AsyncStorage — orphaned tokens on crash
- [low] src/main/ipc/mobile.ts:84-95 — getPairingQR creates a device token on every call, leaking pre-paired entries
Rebased onto current main to resolve conflicts; preserved tokenCache.set added on main.
Co-authored-by: orca-bot <bot@stably.ai>
Reordered pi prefill extension to check event.reason before consuming env var; appended shell unset/clear for ORCA_PI_PREFILL after pi exits to avoid stale prefill on rerun.
Findings addressed:
- src/main/pi/titlebar-extension-service.ts:36-46 — Prefill env var consumed before reason check — may silently drop prefill
- src/main/pi/titlebar-extension-service.ts:30-46 — ORCA_PI_PREFILL still set in shell env after pi exits
Rebased onto current main.
Co-authored-by: orca-bot <bot@stably.ai>
Addresses two SIGKILL/wake-routing bugs:
- setWorkspaceSession now merges prior tab.ptyId / ptyIdsByLeafId
when the incoming snapshot's binding is empty, closing the second
half of the SIGKILL race that could clobber persistPtyBinding.
- DaemonPtyRouter.shutdown skips sessionAdapters.delete when
keepHistory=true so legacy-adapter sessions wake on the right
adapter on resume.
Co-authored-by: orca-bot <bot@stably.ai>
Re-added the `item.type !== 'pr'` guard around the relocated 'Start workspace from issue' button in GHEditSection so PRs no longer show it.
### Findings addressed
- ✅ **[medium]** `src/renderer/src/components/GitHubItemDialog.tsx` — 'Start workspace from issue' now renders on PRs
Rebased onto current main; removed the now-redundant early `return null` for PRs at the top of GHEditSection so the per-button guard is reachable and labels/assignees popovers remain available on PRs.
Co-authored-by: orca-bot <bot@stably.ai>
Fix race between in-flight remote watcher install and unwatch/shutdown by tracking cancel tokens; emit overflow fs:changed when the 60s retry timeout gives up so renderer falls back to manual refresh.
### Findings addressed
- [medium] src/main/ipc/filesystem-watcher.ts:445-480 — Race between in-flight installRemoteWatcher and unwatch/shutdown leaks watcher
- [low] src/main/ipc/filesystem-watcher.ts:497-505 — Silent timeout: 60s give-up never notifies renderer
Rebased onto current main.
Co-authored-by: orca-bot <bot@stably.ai>
Added seq + ref guards after awaits in post-scrollback re-subscribe path; awaitReady's prior in-flight promise now resolves before re-arming so old waiters don't pin 3s timers.
Findings addressed:
- mobile/app/h/[hostId]/session/[worktreeId].tsx:280 — Post-scrollback re-subscribe path lacks a seq guard after awaits
- mobile/src/terminal/TerminalWebView.tsx:770 — awaitReady promise replaced without resolving the prior one
Rebased onto current main; conflict in worktreeId.tsx resolved by preserving main's existing 'why: scrollback null viewport' comment alongside the new seq-recheck comment.
Co-authored-by: orca-bot <bot@stably.ai>