Quality pass on main-process/build PRs merged 2026-07-03:
- ios-emulator-backend: resolve the serve-sim executable via a lazily-cached getter
instead of eagerly in the constructor. The bridge is built before the main window
is shown, so the one-time recursive copy + xattr subprocess (first launch after each
version bump) no longer blocks macOS startup for a feature that may go unused (#7174).
- index: collapse the two near-identical `{webContentsId, until}` reload flags
(expectedRendererReload / recoveryReloadInFlight) into one `createWebContentsTimedFlag`
primitive; behavior preserved, including consume-on-read for the recovery reload (#7290).
- check-reliability-gates: coerce gate.commands/testFiles/platforms/providers with an
`asArray` helper before `.includes`, so a hand-edited manifest with a missing/mistyped
field reports a validation failure instead of throwing an uncaught TypeError; extract
`hasCompleteRedGreenEvidence` for the duplicated status check (#7295).
- claude-pty: derive FABLE_WEEKLY_LABEL_RE from WEEKLY_RE.source so a future weekly-
wording change stays in one place and can't reopen the parsing gap it just closed.
- macos-tcc-login-shell: trim the 30-line flag-by-flag JSDoc to the two non-obvious whys
(TCC identity, env(1) SHELL re-assertion) per the repo comment guidance (#7003).
Typecheck, oxlint, oxfmt, `check:reliability-gates`, and touched unit suites all pass.
Quality pass on renderer/shared PRs merged 2026-07-03:
- WorktreeTitleInlineRename: skip the truncation measure + ResizeObserver in `wrapTitle`
mode, where wrapped titles never truncate — it could only churn unused state (#7307).
- editor slice: reuse the `removeEditorStateForReplacedPreview` helper this PR added
instead of a hand-rolled copy of the same six-field eviction (drops ~50 lines) (#6476).
- useFileExplorerTree: extract `readWorktreeDirectory` so the connectionId/settings
assembly for `readRuntimeDirectory` lives in one place, not three (#6321).
- comment-markdown-github-attachment-media: extract a shared `AttachmentFallbackLink`
for the image/video error-fallback link (#6759).
- repository-icon-github: fold the two near-identical live resolvers into one
parameterized `resolveRepositoryIdentityLive`; trim a 3-line comment to 2 (#6507).
- resource-usage-open-slices: delete the `shouldReadPopoverSlices` identity wrapper and
inline `open` at the four call sites (#7275).
- BrowserPane: drop the pointerEvents assignment already applied inside
`ensureBrowserPageWebview` for the reused-webview path (#6958).
- github slice: fix two garbled "…a commit main confirmed…" comments (#7277).
- runtime-file-client: trim the binary-file fallback comment to its whys (#6606).
- composer-branch-selection: drop the inline comment that restated the JSDoc (#6748).
- TabBarQuickCommandsButton: correct the stale "+ Command" comment (button shows no +).
No behavior change (the editor-helper reuse is behavior-equivalent, only more
conservative on an edge case); typecheck, oxlint, react-doctor, oxfmt, and touched
unit suites all pass.
Quality pass on terminal PRs merged 2026-07-03:
- pane-split-close: extract a shared `teardownManagedPane` so `closeManagedPane` and
`detachManagedPaneForExternalMove` can't drift apart on future edits (#7215).
- terminal-link-activation: reuse the existing `isMacPlatform()` instead of a second
inline `navigator.userAgent` copy, keeping one source of truth for Mac detection.
- pty-connection: gate the shadow-cursor moves on empty CSI params so parameterized/
modified cursor keys (e.g. Ctrl+Left word-jump, `ESC[1;5D`) reset command tracking
instead of silently desyncing the buffer used to infer a typed agent name; relocate
the `getAuthoritativePaneAgent` JSDoc to the function it documents (#6954).
No behavior change except the cursor-tracking hardening; all touched unit suites pass.
No max-lines disable per repo rules; extracted to
artificial-opencode-pane-interactions.ts. toReversed() and
import.meta.filename replace reverse()/fileURLToPath.
Co-authored-by: Orca <help@stably.ai>
The three tests grabbed the FIRST did-finish-load listener; on this branch
the renderer delivery-gate reset registers before the orphan sweep, so the
sweep tests exercised the wrong handler (one failing, two vacuously green).
They now fire all listeners like a real reload.
Co-authored-by: Orca <help@stably.ai>
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>
This reverts commit a94d692cd5, restoring the
shorter "Command" label and the Play icon on the quick command entry
(PRs #5528 and #5674).
Co-authored-by: Orca <help@stably.ai>
The 10MB dev bench proved the write-back salvage insufficient: a
pending-cap drop always triggers a snapshot restore, whose replay guard
swallows xterm auto-replies and whose discardTerminalOutput races away
still-queued query writes — the salvaged DSR died both ways and the
fence still timed out.
Salvage now answers directly on the input path (immune to both): CPR
(CSI 6n) from the live buffer via transport.sendInput, DA1 with the
renderer's canned response, OSC color probes via the existing direct
responder. Rare queries (DECRQM, DA2) keep the best-effort xterm
replay.
Co-authored-by: Orca <help@stably.ai>
The renderer credited main's per-PTY in-flight window the moment a
pty:data chunk entered the dispatcher, so the 512KB window meant "bytes
received", never "bytes parsed". Under flood the renderer write queue
grew unbounded behind instant ACKs; main saw no backpressure, crossed
the pending cap, and bulk-dropped output (rc.7.perf DSR timeouts).
Crediting is now parse-deferred: each delivery carries a fire-once
credit (deliverPtyDataWithDeferredAck); the pane's first scheduler write
claims it (writeTerminalOutput.ackCredit) and the output scheduler fires
it when the bytes are consumed — after terminal.write in the
parse-clocked drain, or on ANY discard path (backlog cap replacement,
discardTerminalOutput, disposed-terminal drops, flush recovery).
Deliveries that never reach the scheduler (reconcile drops, restore
queueing, pre-mount eager buffer) settle at handler return, so the
invariant holds: every delivered chunk credits exactly once, parsed or
discarded. E2E ack-gate hold/release and delivery-resync semantics are
unchanged (all crediting still routes through ackPtyData).
Main-side equilibrium: with ACKs at parse cadence, in-flight becomes
true backpressure — pendingData stays near the 256KB producer-pause
watermark, far under the >=2MB drop cap, so bulk floods block the shell
(node-pty pause) instead of dropping.
Co-authored-by: Orca <help@stably.ai>
(A) Under a foreground flood, the hidden-output-restore loop re-fetched
snapshots endlessly: each synchronous applyMainBufferSnapshot starved ACK
processing, main pinned at the in-flight cap, dropped at the pending cap,
and every droppedOutput/modelRestoreNeeded marker re-armed another
restore until the flood ended (rc.7.perf DSR timeouts).
- Restore loop: a foreground live-chunk queue overflow now abandons the
restore immediately (the stream is outrunning snapshot fetch+replay),
with a 3-iteration hard cap + lifecycle warn as backstop.
- Re-arm gate: drop markers/sentinels and reconcile seq-gaps on a visible
pane during its own in-flight/just-abandoned restore no longer re-arm;
live bytes write through and ONE deferred repaint (2s after the last
backpressure signal) heals the gap. Hidden-pane gate semantics are
unchanged.
- Query salvage: discarding queued restore bytes (overflow/refetch) now
extracts DSR/CPR/DA/OSC-color queries and replays them to xterm so
replies still flow.
(B) Main-side: dropOversizedPendingPtyData carves reply-eliciting query
sequences out of the dropped buffer (and out of post-drop latched data,
bounded) and ships them on the droppedOutput sentinel, so DSR probes
survive bulk drops. Query scanning moved to
src/shared/terminal-reply-query-extraction.ts, shared verbatim with the
renderer's hidden-startup query extraction.
Co-authored-by: Orca <help@stably.ai>
sherpa-onnx cannot load model files or hotword lists from Windows
paths containing non-ASCII characters.
- Resolve speech model and hotwords paths to ASCII-safe alternatives
like ProgramData when the default userData path contains non-ASCII
- Migrate existing downloaded models from the legacy non-ASCII cache
- Ensure deleted models are removed from the legacy source folder to
prevent them from being re-migrated on subsequent launches
Fixes the PTY fallback path so Claude Fable usage carries a concrete reset timestamp and the existing status tooltip renders the Fable reset countdown.
The build-identity guard only knew vX.Y.Z and vX.Y.Z-rc.N, so suffixed
perf RCs cut fine but every platform build refused the tag and the
releases published empty.
Co-authored-by: Orca <help@stably.ai>
Bug D: the serialized screen cannot carry the VT100 DECSC saved-cursor
register, so a hidden ESC 7 followed by a post-reveal ESC 8 restored to
home and clobbered live cells. The snapshot epilogue now re-saves at the
source's saved position before the final absolute CUP
(readSavedCursorRegister + serializeWithAbsoluteCursor; the active
buffer's own register, so alt screens carry theirs). Position-only by
design; never-saved terminals are left untouched.
Bug E: a PTY read ending mid-escape leaves the sequence in the emulator's
parser, so serialize dropped it and the racing tail's continuation bytes
rendered literally after reveal (~24% of the fuzz corpus). The emulator
now tracks the unparsed trailing partial at ingest
(terminal-partial-escape-tail.ts, committed post-parse like the mouse
mirror) and ships it as TerminalSnapshot.pendingEscapeTailAnsi.
applyMainBufferSnapshot writes it LAST, after POST_REPLAY reset — any
later ESC would abort the dangling sequence. Seq accounting is unchanged:
the tail is a suffix of bytes the snapshot seq already counts, so
reconcile slicing needs no adjustment.
Fuzz suites: unskip the Bug B/C repros (fixed on this branch) and the new
D/E repros; remove the B/C/E tolerance predicates so regressions fail
loudly. Only Bug A (upstream wrap null-cell) stays tolerated + counted.
Green at FUZZ_ITERATIONS=2000 (fidelity) and 1000 (reconciliation).
Co-authored-by: Orca <help@stably.ai>
- Fidelity suite: add snapshotHasSelfCancellingBoldReset (Bug B) and
isMarginWrapPendingCursorOffByOne (Bug C) predicates so the corpus tolerates +
counts them like Bug A. FUZZ_ITERATIONS=2000 is now green (~113s) and fails
only on genuinely new divergences; each tolerance keeps its <50% degeneracy
guard. Default 300 unchanged (~17s).
- Reconciliation suite: drop SGR 7 (inverse) from the append-only tail. Inverse
marks trailing blanks with an inverse-fg the serializer round-trips slightly
differently by capture depth — a Bug-B-class serialize nuance, not seq
reconciliation. FUZZ_ITERATIONS=1000 is now green; default 200 unchanged.
- Notes updated: every bug class is both pinned (skipped repro) and tolerated in
its corpus; combined default runtime ~19s.
Regex uses String.fromCharCode(27) to stay oxlint no-control-regex clean.
Co-authored-by: Orca <help@stably.ai>
* fix: stop Claude account loading after denial
* fix(claude-accounts): tear down whole login tree on OAuth denial
Use killChild() (not child.kill) on the denial path so the detached
POSIX process group and Windows child tree are killed, matching the
timeout/abort paths and honoring the detached-spawn comment. Strengthen
the regression test to assert the process-group teardown.
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Neil <charlie-eng@stably.ai>
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>
Extends terminal-hidden-view-parking.spec.ts with a deterministic 25-cycle
park->reveal test on a static rich alt-screen TUI frame (box drawing, SGR
colors, wide CJK/emoji). Baselines against the frame after the first snapshot
restore (so both sides pass through identical machinery — the alt-screen restore
correctly drops normal-buffer scrollback, which is contract not garble), then
asserts every subsequent reveal reproduces it byte-for-byte with no accumulated
drift and no hidden-skip banner. Exercises the real renderer teardown +
HeadlessEmulator snapshot restore + PTY reattach path the fuzz suites model in
isolation. Passes in ~29s (electron-headless, workers=1).
Co-authored-by: Orca <help@stably.ai>