Remote AI-vault rescans re-read every candidate session file over SSH in
full on every refresh. Cache parse results per host keyed by remote path
with an (mtime,size) signature so unchanged files skip the body transfer
and re-parse entirely; only new/changed files are read. LRU-bounded at
4096 entries per host (matches the local parse cache bound), kept across
reconnects, evicted on target removal. Extends `#7593`'s local-only fix
to the SSH path.
Co-authored-by: Orca <help@stably.ai>
retainedAgentsByPaneKey snapshots a completed agent (a full AgentStatusEntry
— up to ~24KB of prompt/message text — plus a TerminalTab) per ephemeral
paneKey. paneKeys never recur, and the map is pruned only on worktree removal
or manual dismissal, so a long-lived worktree in a busy multi-agent /
orchestration session grows it without bound. This is the dominant
large-payload driver of the renderer JS-heap OOM seen in the Windows crash
bundles (heap climbing to the 3586 MB V8 old-space limit under continuous
multi-agent work).
Cap the map with insertion-order (== retention-order) FIFO eviction, mirroring
capRecordByInsertionOrder in github.ts: the newest completions survive; the
oldest simply stop showing in the recently-completed overlay. retainAgents is
the only path that grows the map, so capping there fully bounds it.
Adds a leak regression test that drives the production retainAgents path with
distinct ephemeral paneKeys and asserts the map stays bounded — fails before
this change (grows to N), passes after (capped at MAX_RETAINED_AGENTS).
Co-authored-by: Neil <neil@stably.ai>
* fix(renderer): raise renderer V8 heap toward the 4GB pointer-compression cage
Renderer OOM ('renderer crashed'/'oom', exit 5 / 0xE0000008 / SIGTRAP) is the
dominant crash in the crash channel: the renderer JS heap reaches Chromium's
default V8 old-space ceiling (~RAM/4) and V8 aborts. Two adversarial leak hunts
(13 agents across every renderer subsystem) found no unbounded GB-scale leak, so
this is a capacity ceiling, not a leak.
Chromium sizes the renderer heap at ~RAM/4, leaving 8-15GB machines well under
V8's ~4GB pointer-compression cage (an 8GB machine caps near 2.2GB). Reclaim that
unused headroom via --max-old-space-size in a focused startup module, gated on
physical RAM (>=8GB, ~40% of RAM, floor 3072MB, capped at the real 4096MB cage).
16GB+ machines are already at the cage so this is a no-op for them; low-RAM
machines keep the default to avoid trading a clean OOM for OS memory-pressure
kills.
Overridable with ORCA_RENDERER_HEAP_MB (number to force, default/off/0 to opt
out). Verified on Electron 42.3.3: the main-process js-flags switch propagates to
the renderer V8 and is honored up to the 4096MB cage (5000/12288 -> 4096).
Co-authored-by: Orca <help@stably.ai>
* fix(renderer): address CodeRabbit — floor-to-0 override + Linux 8GB gate
- parseRendererHeapOverrideMb: a fractional override in (0,1) floored to 0 and
emitted an invalid --max-old-space-size=0; treat floored-to-0 as an opt-out.
- Lower the RAM gate from 8 to 7.5 GiB: os.totalmem() on Linux reports MemTotal
(excludes kernel/firmware-reserved RAM), so a real 8 GB box reports ~7.7 GiB
and was wrongly excluded from the headroom — the exact crashing population.
7.5 still cleanly excludes 6 GB machines (report ~5.7 GiB).
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Orca <help@stably.ai>
110 files carried an eslint/oxlint-disable max-lines directive but are
already under the default max-lines budget (300 .ts / 400 .tsx / 600 .mjs
/ 800 test), so the suppression is dead. Removing it restores real
max-lines coverage on these files with zero behavior change.
Each removed directive had max-lines as its only rule; verified via a
full oxlint run (0 max-lines violations, 0 new errors). Diff is pure
deletions (200 lines, 0 additions) — no code touched.
Co-authored-by: Orca <help@stably.ai>
Bump marketing version 0.0.22 -> 0.0.24 and Android versionCode 4 -> 5.
The 0.0.22 base was never committed after prior releases, so the Jul 6
builds carrying the show-all-worktrees fix (#7500) regressed below the
0.0.23 already on TestFlight (iOS) and collided with the existing
0.0.22/versionCode 4 APK (Android, no upgrade signal). Committing the
bump makes app.json authoritative again so 0.0.24 supersedes both.
Co-authored-by: Orca <help@stably.ai>
Two independent pieces, no behavior change to terminal handling:
1. Daemon lifecycle file log. The detached daemon runs with stdio
ignored, so field failures have zero daemon-side evidence. The daemon
now writes rotated NDJSON lifecycle events (startup/ready/hello
accept+reject/session create/attach/exit/kill/shutdown/uncaught
exceptions) to logs/daemon.log via a new optional --log-file fork arg.
Fail-open (any fs error disables logging), adoption-neutral (old
daemons without the arg keep working, protocol untouched), and the
diagnostic bundle collector now includes the file, bounded by the same
lookback window as trace spans.
2. tools/win-update-e2e: a packaged NSIS update proof harness. Installs
version N, drives the installed app (isolated userData), plants a
canary marker session, silently updates to N+1, relaunches, and
asserts an explicit expectations profile: --expect cold-restore
(today's behavior) or --expect survival (the Phase 1 target). Window
flashes are detected by baseline-diffed window enumeration with
canary-title attribution; daemons are identified by command-line
marker, never exe name. Refuses to run when a pre-existing Orca app is
running or (without --allow-existing-install) installed, and only
uninstalls an install it fully owns.
Ensure agent CLI startup and draft launch commands use the correct quoting
format based on the user's configured local Windows shell (e.g., cmd.exe).
This avoids using host settings for remote/SSH targets where local shell
preferences do not apply.
Issue #7236 reported that any non-empty worktree Setup Script failed on
Windows PowerShell with a "missing terminator" parser error, regardless
of content. Root cause: in pre-encoded builds the setup-runner command
(`cmd.exe /c "<runner>"`) was typed into PowerShell as raw stdin, where a
dropped/unbalanced double quote got re-parsed as an open string.
Encoded-command delivery (base64 UTF-16, shipped in v1.4.81) already
fixes this by passing the command as a shell argument with quotes intact.
This adds a regression test tying resolveSetupRunnerCommand to
resolveWindowsShellLaunchArgs: the real setup-runner command must reach
PowerShell via -EncodedCommand (startupCommandDeliveredInShellArgs),
never raw stdin, with its quotes preserved verbatim.
Co-authored-by: Neil <neil@stably.ai>
* Clarify Orca orchestration tool boundary and sidebar lineage
Add a "Tool Boundary" section to the orchestration skill, requiring
explicit Orca runtime state instead of generic subagent tools or
chat-only parallel workers. Also add tests to verify the tool boundary
and clarify sidebar lineage for same-worktree workers.
* Clarify worktree lineage guidance and parent-child boundaries
Update orchestration guidance and tests to clarify when to use child versus
top-level worktree lineages, and when to prefer same-worktree workers.
* Require stating the desired Orca lineage before creating a worktree from
an active feature branch.
* Limit child worktrees to conceptually stacked or dependent tasks.
* Prefer same-worktree workers unless isolated checkouts are explicitly
needed and do not require uncommitted changes.