If legacy session discovery fails after startup probing already found live work,
do not let the post-discovery sweep reinterpret an empty routing map as drained.
Keep that legacy daemon alive for this app session and let the next startup
re-probe it instead.
Claude review found a conservative-safety edge in the startup sweep: if legacy
session discovery fails after an earlier probe saw live sessions, sweeping the
empty session map could kill live legacy work. Update the design to exclude
adapters with discovery failures from sweep and runtime drain until a later
startup can safely re-probe.
Implement the two-tier legacy daemon cleanup path from the design: reclaim idle
or wedged previous-protocol daemons at startup, and shut down live legacy daemons
when their final routed session exits. Current-protocol daemon startup and
session routing remain on the existing path.
Add pid-file compatibility for legacy integer files and new JSON metadata,
including process identity revalidation before SIGKILL. See
docs/auto-kill-old-daemons.md for design rationale.
The implementation keeps the existing daemon-spawner path regression while adding
pid-file serialization coverage, and adds a small daemon-pty-adapter assertion
for the exposed protocolVersion field. Update the design checklist and files
list before landing the code so the handoff matches the actual test scope.
Legacy Orca daemon processes can survive protocol-version upgrades forever,
hoarding PTY file descriptors after their sessions have exited. This design
captures the zero-regression constraints for reclaiming those legacy daemons
without changing the current daemon lifecycle.
Use a two-tier event-driven cleanup path: sweep idle or wedged previous-version
daemons on startup, then keep live legacy sessions routed to their original
daemon and shut that daemon down when its final session exits.
- BrowserTab: Globe icon uses text-blue-500 on both active and inactive tabs
for a distinct, recognizable anchor in the tab strip.
- shell-icons: GenericTerminalIcon now renders a pitch-black tile with a
thick stroked >_ (chevron at 3.2px, underscore at 2.6px, taller chevron)
so mac/linux/default terminal tabs match the colored-badge treatment of
the PowerShell/CMD/WSL icons instead of a flat lucide chevron.
- SortableTab: all terminal tabs use ShellIcon. On Windows, tabs without a
per-tab shellOverride fall back to the user's configured default
Windows shell so the tab-strip icon reflects what's actually running.
Co-authored-by: Orca <help@stably.ai>
Clicking a worktree card whose row lies outside the sidebar viewport
caused an instant jump when scrolling it into view. Switching
`scrollToIndex` to `behavior: 'smooth'` turns that minimum-distance
scroll into an animated slide while keeping `align: 'auto'` so visible
cards still no-op (no re-centering).
Co-authored-by: Orca <help@stably.ai>
getConnectionId returns undefined during store hydration, which was
misclassified as remote by `!== null` check. Changed to `typeof === 'string'`
so unhydrated state falls through to client-OS quoting, consistent with
terminal-drop-handler.ts behavior.
Co-authored-by: Orca <help@stably.ai>
Switch the reveal scroll from align:'center' to align:'auto' so clicking
a worktree only scrolls the sidebar when its card is not already visible.
Centering on every click made the list feel jumpy during normal navigation.
Co-authored-by: Orca <help@stably.ai>
Electron <webview> elements run in a separate process, so clicks inside
them don't dispatch pointerdown on the renderer document. Radix
DropdownMenu relies on document pointerdown for outside-click detection
and therefore misses webview clicks, leaving the menu stuck open.
Listening for window blur catches the moment focus leaves the renderer
(including into a webview) and closes the menu.
Co-authored-by: Orca <help@stably.ai>
On close/quit (especially auto-updater relaunch via quitAndInstall),
Electron/OS emit resize/move/unmaximize while the window is torn down.
The debounced persistence was capturing those near-minimum bounds, so
the next launch came up at minWidth x minHeight.
- Freeze bounds persistence on window 'close' and app 'before-quit'
(updater strips the window 'close' listener before quitting, so
the app-level latch is needed as a second line of defense).
- Release the freeze on will-prevent-unload so aborted Cmd+Q keeps
saving bounds.
- On restore, discard saved bounds at/below the min dimensions to
recover users who already persisted corrupt bounds.
Co-authored-by: Orca <help@stably.ai>
Before removing a <webview> that currently owns focus, blur the active
element and refocus the window. Without this, macOS hands activation to
the previously-active app (e.g. Slack) because the focused webContents
is gone with no replacement, pulling the user out of Orca on worktree
delete.
Co-authored-by: Orca <help@stably.ai>