Files
orca/docs
Jinwoo HongandOrca 827b84d27a fix(runtime): add single-instance lock + owned-metadata clear (#1312) (#1326)
* fix(runtime): add single-instance lock + owned-metadata clear to prevent orca-runtime.json corruption

Closes #1312.

Every AppImage/.app relaunch was booting a fresh Electron main that clobbered
`<userData>/orca-runtime.json` and `agent-hooks/endpoint.env`. When the newest
instance quit, metadata pointed at a dead pid and `orca status` reported
`stale_bootstrap` even though the original Orca was still running. SIGKILL'd
predecessors also left orphaned `o-<pid>-*.sock` files in userData.

Three surgical changes:

1. `app.requestSingleInstanceLock()` in a new
   `src/main/startup/single-instance-lock.ts` helper, wired into
   `src/main/index.ts` after `configureDevUserDataPath(is.dev)` so dev and
   packaged runs lock in separate namespaces. Losing instances focus the
   primary's window via `second-instance` and quit without touching userData.

2. `clearRuntimeMetadataIfOwned(userData, pid, runtimeId)` in
   `runtime-metadata.ts` — compares both pid AND runtimeId against the
   current file before clearing, so the auto-updater handoff window never
   erases the replacement process's fresh bootstrap. Called from a rewritten
   `will-quit` handler that folds `runtimeRpc.stop()` + owned-clear into the
   same `Promise.allSettled([disconnectDaemon, …]).then(app.quit)` chain
   (inside the `!daemonDisconnectDone` guard so the second-pass re-entry
   can't re-invoke stop+clear).

3. `sweepOrphanedRuntimeSockets()` in `runtime-rpc.ts` runs at the top of
   `start()` on POSIX, using `process.kill(pid, 0)` to probe liveness and
   remove `o-<dead-pid>-*.sock` orphans left by SIGKILL/OOM-kill.

Tests (37 new/updated):
- `single-instance-lock.test.ts` (3): lock-failed does not register listener;
  lock-acquired registers exactly one; callback dispatches correctly.
- `runtime-metadata.test.ts` (+4): clearRuntimeMetadataIfOwned matched /
  pid-mismatch / runtimeId-mismatch / no-file branches.
- `runtime-socket-sweep.test.ts` (4): own-pid-skip / alive-retain /
  dead-sweep / regex-miss separated via synthetic ownPid=1; two
  regex-invariant tests assert the sweep regex matches the real
  `createRuntimeTransportMetadata` output (including the 'rt' fallback).

Design doc: `docs/fix-missing-single-instance-lock.md`.

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

* fix(runtime): focus hidden windows on second-instance event

focus() alone is a silent no-op when the primary window is hidden
(close-to-tray on macOS via Cmd+W, or on a different macOS Space) or
behind other apps on Windows. Call show() before focus() so a second
launch attempt reliably surfaces the existing window regardless of
state.

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-05-02 23:05:14 -07:00
..

Orca CLI Docs

Keep this folder focused on the durable references for Orca's public CLI and runtime model.

Keep These Docs

  • orca-cli-focused-v1-status.md
    • What is actually implemented and intentionally in scope now.
  • orca-cli-v1-spec.md
    • The public CLI contract, selector grammar, JSON envelope, and command semantics.
  • orca-runtime-layer-design.md
    • Why the runtime layer exists and which boundaries it owns.
  • orca-cli-bundled-distribution.md
    • How the bundled desktop-app distribution and PATH registration model works.

Why The Folder Is Small

Earlier design and implementation work produced several planning and evaluation docs. Those were useful while the feature was taking shape, but they were intentionally removed once the implementation converged so future readers are not forced to choose between multiple overlapping sources of truth.