* feat(windows): custom title bar with renderer-drawn window controls
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
* fix(windows): titlebar logo color and window-controls overlap
- Logo light-mode invert: :not(.dark) selector was matching in dark mode
because .dark lives on <html> (:root), not on a descendant. Fixed to
:root:not(.dark) so the invert(1) filter only fires in light mode.
- Overlap with right-side controls: introduce --window-controls-width CSS
var (138px on Windows, 0px elsewhere) on the root div so every affected
surface reads a single source of truth:
- Workspace-view floating sidebar toggle (absolute top-0): right now uses
var(--window-controls-width) instead of hardcoded 0
- window-controls-titlebar-spacer width uses the var
- Right sidebar header: new .right-sidebar-header-inset class adds
padding-right: var(--window-controls-width) to both the top-activity-bar
and side-layout header variants so the close button is never hidden
* fix(windows): window-controls hover must not bleed below titlebar
The .window-controls container and .window-controls-btn were both 42px
tall while the titlebar is 36px. The hover background filled the full
button height, painting 6px of highlight into the content area below
the titlebar. Shrink both to 36px to match.
* fix(windows): side activity bar icons obscured by window-controls overlay
In side-bar activity-bar mode the icon strip is flush against the right
window edge. The fixed-position window-controls overlay (138×36px)
covers the top-right corner, making the topmost icons unreachable.
Add --window-controls-height (36px on Windows, 0px elsewhere) CSS var
and apply it as padding-top on the side activity bar via
.side-activity-bar-windows-inset — same pattern used by
--window-controls-width for the horizontal dimension.
---------
Co-authored-by: Neil Parker <nwparker@anthropic.com>
Added windowsShell parameter to buildAgentDraftLaunchPlan so the post-exit clear-var uses Remove-Item Env: on PowerShell/pwsh and set "FOO=" on cmd.exe; threaded settings.terminalWindowsShell through both call sites.
### Findings addressed
- ✅ **[high]** `src/renderer/src/lib/tui-agent-startup.ts:160-163` — Windows clear-var command only works in cmd.exe, breaks in PowerShell
Rebased onto current main; added settings?.terminalWindowsShell to the useCallback dep array in useComposerState to satisfy react-hooks/exhaustive-deps.
Co-authored-by: orca-bot <bot@stably.ai>
Added DeviceRegistry.rotatePendingDevice and threaded a 'rotate' option through the mobile:getPairingQR IPC + preload + MobilePane so explicit Regenerate clicks mint a fresh pending token instead of returning the same one.
Findings addressed:
- [medium] src/main/runtime/device-registry.ts:44-50 — 'Regenerate QR' no longer rotates the token
Rebased onto current main to resolve conflicts.
Co-authored-by: orca-bot <bot@stably.ai>
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>
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>
* 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>
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>
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>
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>
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>
Don't seed empty-success worktree roots in worktrees:list[All] catch (prevents auth-cache poisoning); restored focus-gated fetchWorktrees polling for the active repo so non-active worktrees pick up terminal-driven branch switches; encode detached HEAD as undefined instead of '' so renderer's nullish-coalescing preserves prior branch.
Rebased onto current main to apply only the intended diff.
Co-authored-by: orca-bot <bot@stably.ai>
Fixed bundle-sheet keyed-canvas discard, narrowed magenta key threshold to avoid keying purples/pinks, hardened bundle copyFile against TOCTOU via O_NOFOLLOW, and skipped frame detection when the manifest already provides a valid sprite layout.
Rebased onto current main to resolve conflicts; reviewed and merged round-1 reviewer feedback (no committed node_modules).
Co-authored-by: orca-bot <bot@stably.ai>
Selecting a PR/issue/Linear row replaces the focused input with a source
pill, which causes Chromium to retarget the next keydown to document.body.
Allow body/documentElement as submit targets so the modal shortcut keeps
working post-selection. Also tighten the modifier check to be platform-
exclusive (Cmd-only on Mac, Ctrl-only elsewhere).
Co-authored-by: Orca <help@stably.ai>
The orca.yaml trust dialog now adapts copy and layout based on whether
this is a first-time approval or a re-prompt after the script changed.
Re-prompts lead with '<repo>'s setup script changed — run the new
version?' so users understand why they're being asked again.
Restyles the 'always trust' checkbox as a card and threads a
previouslyApproved flag from ensureHooksConfirmed into the dialog.
Co-authored-by: Orca <help@stably.ai>
Per-scope persisted column widths via fr-weight redistribution between
adjacent column pairs, so the table fits its container without growing.
Also relocates "Start workspace from issue" button into GHEditSection and
expands comment composer with a labeled send button.
Co-authored-by: Orca <help@stably.ai>
* feat(feedback): let anonymous users opt in to PR tag + contact
When 'Submit anonymously' is checked the feedback dialog now smoothly
expands to reveal two optional fields:
- GitHub username \u2014 we'll @-mention them on the fix PR
- Email or x.com handle \u2014 we'll reach out when it's fixed
The animation uses a grid-rows 0fr\u21921fr transition so it expands
naturally without measuring DOM. New fields are forwarded through the
IPC + main-process proxy as 'anonymousGithubLogin' and 'anonymousContact'
so the backend can tell self-typed handles apart from verified gh
identity. Backend changes (slack message + route) ship in
orca-marketing-website.
Co-authored-by: Orca <help@stably.ai>
* feat(feedback): split anon contact into email + x.com, tighten copy
Address review:
- move 'all optional' wording up to the top header line
- drop the inline 'we'll tag you on the PR' helper (placeholder says it)
- split the single contact input into two separate inputs (email +
x.com handle), each with its own placeholder
IPC field rename: anonymousContact \u2192 anonymousEmail + anonymousX. Backend
PR is updated to match before either side ships.
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Orca <help@stably.ai>