46 commits from main. Conflict resolutions (branch structure wins, main
semantics grafted):
- pending-backlog cap (#7630): main's capPendingPtyData/droppedBacklog
2MB tail-trim EXCISED — this branch's droppedOutput sentinel mechanism
(O(1) drop + query salvage + settings-scaled cap + restore marker)
already bounds the unsent backlog and strictly supersedes it; carrying
both would race two cap policies over one buffer. Kept main's
makePtyDataPayload helper and exit-time pending flush (adapted to the
sentinel). Main's duplicate never-ACK cap test removed (covered by the
existing sentinel cap tests); its reload-gate tests kept with the
runtime mock extended.
- replay guard (#7661): main's blind REPLAY_GUARD_RELEASE_FALLBACK_MS
release dropped — this branch's probe-certified stall release covers
the same cold-restore reattach lockout without the auto-reply leak a
timed release can cause in agent TUIs. Main's three regression tests
KEPT, adapted to probe timing (explicit stallCheckMs).
- hidden-pressure scenario: kept this branch's STRICT 1500ms restore
budget (the background keep-tail global budget earns it; main relaxed
to 4s for CI drain overhead) + grafted main's timer-drift gate const.
- ssh-docker-relay-perf: kept this branch's ACK-stalled background PTY
test AND grafted main's new file-streams+git-churn test (4 tests).
- preload/renderer: droppedBacklog threading excised with the mechanism;
main's unrelated changes (ssh importConfig reAdopt, etc.) kept.
Gates: typecheck clean; ipc+daemon+terminal-pane+pane-manager suites
4,396 passed / 14 skipped.
Co-authored-by: Orca <help@stably.ai>
Hidden panes are exempt from pendingData flow control (main gate-drops
their bytes after ingestion), so N background agents ran unbounded ahead
on the one shared daemon->main stream socket (measured 192MB user-space
backlog) and visible-pane echo waited FIFO behind it — typing appeared
seconds late whenever several agents burst on a loaded machine
(8x512KB/s + 12 CPU spinners: p50 293ms fix-off; 12x1MB/s: 6.1s).
Mechanism (replaces producer pacing — no reveal catch-up, ever):
- Shallow socket write gate (128KB) + per-session fairness bypass bounds
echo latency by construction; kernel-flush refill sentinel keeps held
bulk draining at full speed (drain-only refill capped at ~8MB/s).
- Backgrounded sessions' queued output is keep-tail dropped (newest
512KB kept, in-order dataGap replaces the middle); a ~2MB GLOBAL
budget shrinks per-session keep-tails (floor 64KB) so a worktree
switch never waits behind the aggregate. Reply-eliciting query bytes
(DSR/DA/OSC probes) are salvaged from dropped spans.
- Notifications are structurally lossless: the daemon runs the same
shared scanners main uses (bell/OSC 133/pr-link/2031) over every byte
BEFORE drop decisions and relays facts in byte order; ordered
background markers hand scan authority back and forth, seeded with the
emulator's partial escape tail so a sequence split across the handoff
neither phantom-fires nor goes missing. Titles/agent-status stay
main-side (kept-tail convergent).
- Main: background = hidden AND no remote view subscriber (a live
mobile/web view is never thinned); on dataGap main resets cross-chunk
parse carries, drops the headless mobile mirror, and reuses the
hidden-drop model-restore marker.
Wire: three new stream events, tolerated within protocol v19 (old mains
ignore unknown events; old daemons never see the trigger). Kill
switches: ORCA_DAEMON_BACKGROUND_STREAM_DROP=0,
ORCA_DAEMON_SHALLOW_SOCKET_GATE=0.
A/B (pnpm bench:multi-workspace-typing): 8x512KB/s + 12 CPU workers
p50 293ms/p90 647ms -> 15/21ms (= baseline); 12x1MB/s 6,146ms -> 20ms;
light loads unchanged; zero missing echoes. Latin hidden-restore e2e
green (probe-verified aggregate-drain root cause). New deterministic
repro harness: tests/e2e/terminal-multi-workspace-typing-latency.spec.ts
+ CPU pressure workers.
Co-authored-by: Orca <help@stably.ai>
oxlint already fails any file over max-lines that is not suppressed, so the
only way to grow past the budget is to add an eslint/oxlint-disable max-lines
comment or a per-file max-lines bump in mobile/.oxlintrc.json. This adds a CI
gate that freezes the current set of suppressions (config/max-lines-baseline.txt,
355 grandfathered entries) and fails the build when a NEW one appears — with a
loud, actionable message pointing at 'split the file'. Existing oversized files
are untouched; the baseline may only shrink (pnpm check:max-lines-ratchet --prune).
Wired into the root lint script and as a dedicated pr.yml step. Unit-tested
(15 cases) and verified against all three failure paths + clean-tree pass.
Co-authored-by: Orca <help@stably.ai>
Brings in 9 commits: deferred remote catalogs at startup (#7087),
owner-aware pane title decision gating the Gemini GPU fallback (#7458),
incremental transcript parsing for JSONL agents (#7593), gh rate-limit and
git-status spawn-churn fixes (#7595), WSL Codex session bridging (#7477),
jump-palette subscription gating (#7558), and the IDE font dropdown fix.
Conflict resolutions (our structure, main's semantics):
- pty-connection.ts onTitleChange: kept this branch's third parameter and
stale-derived-title guard (staleWorkingTitleClear must never feed
completion tracking), grafted main's resolvePaneTitleDecision so the
display label, GPU policy, and observeTitle all ride the owner-aware
decision (#7428/#7447).
- App.tsx startup: kept this branch's publishTerminalViewAttributesAtAppStart
(hidden-at-launch OSC 10/11 replies) ahead of main's restructured
local-first startup; dropped this branch's early ui.get() overlap — main's
#7087 now awaits ui.get at effectively the same point, making it redundant.
Gates: typecheck clean; 4298 tests across src/main/ipc, src/main/daemon,
terminal-pane, pane-manager. The delivery path (ipc/pty.ts, dispatcher,
scheduler, snapshots) had no conflicts and no incoming changes.
Co-authored-by: Orca <help@stably.ai>
74 commits from main, including the STA-1278 ai-vault transcript perf work,
terminal flicker fix (#7540), renderer V8 heap raise (#7531), scrollbar
position preservation (#7472), and the per-delivery debug-snapshot
allocation removal (#7541).
Conflict resolutions (our structure, main's semantics):
- agent-detection: kept the split-module barrel; grafted main's Gemini/Pi
title-detection refinements (path-fragment false positives, legacy Pi
synthetic titles) into agent-title-core, dropped the superseded
PI_IDLE_PREFIX.
- orca-runtime wait-blocked detection: kept the throttled
scheduleWaitBlockedCheck (branch §1 optimization) and ported it to main's
new cached TerminalTailWaitState API; main's per-chunk cached scan stays
on the leaf mismatch path where it auto-merged. pty.tailWaitState is
deliberately never populated on this branch (throttle owns the pty
record), so the leaf mirror copy invalidates rather than shares — the
fromTail exactness contract is never violated by stale state.
- recordPtyRendererDeliveryPressure: took main's allocation-free peak
update (#7541) and derived per-pty in-flight from this branch's
cumulative sent/acked accounting instead of the removed
rendererInFlightCharsByPty map.
- rpc/methods/terminal detach: kept both sides — our
flushAllAckPendingOutput and main's exitWaiterAbort release.
- pty-connection: kept our single-policy handleCommandFinished (invariant)
alongside main's new sampleVisiblePaneForegroundAgent (bodies were
byte-identical where they overlapped).
- e2e pressure scenarios: kept the Phase-4 hidden-gate contract assertions
and the extracted pressure-script module; adopted main's
MAX_WORST_KEY_LATENCY_UNDER_LOAD_MS budget.
Also documents the renderer-pull delivery watchdog in the branch guide.
Gates: typecheck clean; ipc/daemon/terminal-pane/pane-manager suites 4256
passed; both fuzz suites pass.
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.
Re-based onto the current shared remote tip (4110c296a, which already
carried an older main sync + windows-update-daemon-adoption); this brings
in the 18 newer main commits through v1.4.124-rc.1. MERGE, not rebase.
Conflict resolutions (our structure wins; main's semantics graft in):
- update-check feature (update-check-click-options.ts + test,
GeneralUpdateSettingsSection.tsx, SidebarSettingsHelpMenu.tsx + test,
updater.ts + test): took main's shape — getUpdateCheckHint() centralizes
the RC/perf hint, pointerdown modifier-capture handler, and the refined
`checkVariant === 'prerelease'` guard so a perf check never permanently
opts background retries into the RC channel. getUpdateCheckClickOptions
(the actual behavior) was byte-identical on both sides.
- Ctrl+K clear vs producer flow control (pty-subprocess.ts, session.ts,
session.test.ts): kept BOTH — our pause()/resume() flow-control methods
AND main's clear() ConPTY screen-state resync (#7413). Orthogonal.
- orca-runtime.ts: took main's public visibility on
clearHeadlessTerminalBuffer (ipc/pty.ts Ctrl+K path calls it); dropped
main's createHeadlessEmulator factory — our Phase-5 query-authority
emulator construction is restructured and has no caller for it.
Incoming (auto-merged, off the byte-delivery path): #6277 agent cold-
restore fallback (pty-connection.ts), node-pty ConPTY relocation (#7421),
MiniMax rate limits, translations.
Gates: typecheck 0 errors; ipc+daemon+terminal-pane+pane-manager 4204
passed; both fuzz suites pass; hand-resolved renderer files pass. No
delivery/restore/flow-control/ACK/batching/scheduler bytes changed, so no
10MB bench required.
Co-authored-by: Orca <help@stably.ai>
Conflict: src/renderer/src/lib/github-links.ts (parsing core lives in
src/shared/github-links.ts on this branch). Kept our shared-module
structure; grafted main #7371 semantics into it: exported the named
GitHubIssueOrPRLink type from shared, and the renderer wrapper keeps
normalizeGitHubLinkQuery with the stricter HTTP_URL_PREFIX_RE check and
the new directLink result field.
Also extracted seeded-test-repo.ts from tests/e2e/helpers/orca-app.ts:
the merged fixture crossed the max-lines cap, and the seeded-repo
helpers were a self-contained concept.
Auto-merged hot files verified: main-side changes are spawn-time CWD
canonicalization (#7334/#7403) and a mobile fit-override rebind hook
(#6596) - not on the delivery/restore path, so no bench required per
the branch guide. Throttled wait-blocked machinery intact.
Validated: typecheck clean; daemon + ipc/pty + terminal-pane + both
fuzz suites + github-links run - all failures are pre-existing
Windows-environment ones (identical on a main-based tree), zero
merge-caused.
Main inlined an OSC 133 parser with new 133;C onCommandStarted support;
our branch parses via the shared scanner so main-side side-effect facts
stay byte-identical. Resolution keeps the shared-scanner architecture and
adds 133;C to it; the foreground-agent tracker hooks into the branch's
single handleCommandFinished policy (bytes and sideEffect facts alike).
Co-authored-by: Orca <help@stably.ai>
BUG B (addon patch): @xterm/addon-serialize's SGR diff emitted bold/dim set
params before the shared intensity reset 22, so "1;22" wiped a freshly set
bold and a bare "22" dropped a still-set bold/dim. Patched via pnpm
patchedDependencies (config/patches) to diff bold+dim as one intensity
group with the clearing 22 emitted first. Other flag pairs (4/24, 3/23,
7/27, ...) have dedicated resets and were verified unaffected.
BUG C (Orca-side hardening): the addon restores the cursor with relative
moves computed from where it assumes replay leaves the cursor; a final row
filled exactly to the right margin leaves replay wrap-pending and the
restore lands one column short. New shared
serializeWithAbsoluteCursor appends an absolute CUP from the source
terminal's authoritative cursor at every restore/replay serialize site
(daemon/runtime HeadlessEmulator.getSnapshot, renderer mobile snapshot
serializer, shutdown layout capture). It skips empty snapshots and
wrap-pending sources so it never changes already-correct behavior.
Round-trip repros + non-regression coverage in
src/main/daemon/terminal-snapshot-serialize-roundtrip.test.ts (verified
failing with the fixes stashed). buildRehydrateSequences extracted to its
own module to keep headless-emulator.ts under the max-lines budget.
Co-authored-by: Orca <help@stably.ai>
rc kind can now append an extra prerelease identifier (rc.N.perf):
sorts above its base rc.N but below rc.N+1, so perf-branch RCs are
identifiable by clients without outranking the main RC series.
Co-authored-by: Orca <help@stably.ai>
Conflict resolutions:
- terminal-stream-protocol: Metadata keeps opcode 12 (shipped to mobile
in v1.4.120); branch-only Ack renumbers to 13.
- scheduler: keep HIGH_PRIORITY_MAX_WRITES_PER_DRAIN=8 (perf fix) over
main's 2 (#7139 landed there with the old constant).
- headless-emulator: keep chain structure (scanner classes, query-reply
forwarding); graft main's pathFlavor/remotePosixFileUriAuthority OSC7
options through TerminalOscCwdTitleScanner. Main's
TerminalPrivateModeTracker is logic-identical to the chain's
TerminalMouseModeMirror (kept, with pre-filter).
- orca-runtime: keep chain factory; graft main's pathFlavor wiring and
snapshot cwd fallback; keep both teardown lines.
- pty-connection: keep both chain reconcile and main's ordered-seq
tracking; clear the chain's restored-snapshot baseline on pty exit
(same seq-domain boundary main's reset enforces) — fixes revive with
restarted seq counter dropping chunks as duplicates.
- subscribe-buffer tests: updated to merged semantics — main's inline
overflow recovery ships current data as the FIRST snapshot; the
chain's resized/pending-output-overflow follow-up remains as backstop.
Validation: typecheck clean; 7,548 tests green across daemon/ipc/
runtime/pane-manager/terminal-pane/shared/mobile-transport (1 documented
pre-existing WSL failure).
Co-authored-by: Orca <help@stably.ai>
Revives the terminal model/view architecture chain (hidden view parking,
hidden delivery gate, side-effect authority in main, model query authority
— all kill-switched, defaults on) on top of orca-performance's terminal
performance fixes. 34 conflicted files resolved with these decisions:
- Both sides' features kept and kill-switchable. orca-performance's fixes
preserved exactly: parse-clocked scheduler drains (9e8bb2243), windowed
retained-tail redraw (4e08a28cd), throttled wait-blocked check
(66f20258e), #7139/#7150 cooperative drain, backlog caps, wedge guards,
and probe-certified replay release.
- orca-runtime.ts onPtyData: chain's per-PTY title tracker + side-effect
facts replace the inline OSC title blocks; our scheduleWaitBlockedCheck
and redraw-cursor plumbing retained; refreshPtyForegroundAgent re-grafted
into applyTrackedPtyTitle on status transitions.
- pty.ts: chain's hidden-gate drop sites, restore markers, initiallyHidden
spawn marking, ConPTY DA1 record, and view-attribute/delivery-interest IPC
wired through our newer spawn/delivery structure. The chain's flat 2 MB
pending cap was NOT taken: our scrollback-scaled cap (#7150, empty-drop +
droppedOutput sentinel) wins and now also emits the chain's one-per-episode
pty:modelRestoreNeeded 'pending-cap' marker when the gate is enabled. Our
8 MB renderer in-flight high water kept over the chain's 2 MB.
- pty-connection.ts: chain's gate sync, model-restore channel, side-effect
fact consumer, and post-restore seq reconciliation composed with our
hidden-startup query grammar, synchronized-frame latency machinery, and
probe-certified restore. Phase 6 (skip-grammar deletion) intentionally NOT
taken: our side evolved that grammar past the chain's base and #7150
machinery builds on it; with the gate on it is dormant (main drops hidden
bytes), with switches off it remains the byte-identical fallback.
- Shared module moves adopted (agent-title-*, github-links, bell detector,
command-code, PR-link detector) with our newer bounded regex-free OSC
parsers wired through the chain's scanner classes; our pi-synthetic/Devin/
MiMo agent additions ported into the split modules.
- daemon-pty-adapter: chain's sleep-restore cache + our checkpoint cooldown,
teardown flag, and oscLinks-carrying cold-restore payload combined.
- rpc/methods/terminal.ts: chain's ACK-gated multiplex output + recovery
snapshots composed with our budgeted mobile snapshots and resize re-stream.
- Tests adapted only where they encoded superseded cadence: watermark counts
(2 MB->8 MB), pending-cap trim -> empty-drop sentinel, initial snapshot
frame seq (layout seq -> snapshot output seq), mock module paths.
Contract tests: 881 passed. Renderer terminal suites: 1895 passed.
Full main runtime+ipc: 2974 passed. Typecheck (3 configs) clean.
Pre-existing baseline failures (pty-subprocess WSL, PR sidebar, Linear
prompt, SidebarToolbar) are unrelated and fail identically on 7839fb9db.
Co-authored-by: Orca <help@stably.ai>