Commit Graph
9277 Commits
Author SHA1 Message Date
Neil fc69ec11c6 perf(github): coalesce stronger refreshes after pending requests (#22970)
* perf(github): coalesce stronger refreshes after pending requests

* fix(github): bound the refresh-upgrade wait so a strict caller cannot starve

The upgrade loop retried forever: a caller wanting a stronger refresh waited
for each weaker in-flight request, rechecked, and waited again. A repeating
weaker refresh (the quiet-refresh interval) could therefore pin a forced
noCache caller for the life of the process with no timeout or escape hatch.

Wait out at most one weaker request — enough for peers to share the upgrade —
then issue our own. Call counts are unchanged; progress is now guaranteed.

Retargets the coordination test at that invariant instead of asserting that
strict callers block until the weaker replacement finishes.

* fix(github): let only a dedupe key's current request write its cache

Bounding the upgrade wait fixed the starvation but opened a window the
unbounded loop never had: a stronger request can now run beside a weaker one
for the same key. Nothing fenced the cache writes, so whichever settled last
won. A force-only work-item request does not pass noCache, so gh's own cache
can answer it; settling after the noCache request buried the fresher rows
under a new fetchedAt and isFresh then served them for the rest of the TTL.
Checks rewound run state the same way, and a superseded project request could
stamp its failure over a newer table at the known view key.

Stamp each request with a monotonic id on its inflight entry and recheck
ownership after the provider call, immediately before every cache write — the
work-items entry, both project-view branches, and checksCache plus the PR
status syncPRChecksStatus derives from it. That is the same ownership question
the cleanup guard already asked, so the cleanup now reads the stamp too; the
promise itself cannot be compared from inside its own initializer.

The wait stays bounded and the twenty-one-caller upgrade still collapses to two
provider calls.
2026-09-26 23:57:43 -07:00
c3ff93fd70 fix(editor): highlight Twig templates in files and diffs (#23366)
Select Monaco's bundled Twig language for .twig files, including compound template names. Cover case variants, Windows and UNC paths, and misleading suffixes without changing the recently merged Typst mapping.

Adapted from robbdavis's proposal #22357.

Co-authored-by: Robb Davis <robb@affinitybridge.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 23:55:36 -07:00
NeilandClaude 5da18e154f fix: preserve newer hosted review lookup ownership (#23126)
* fix: preserve newer hosted review lookup ownership

* refactor: reuse the shared lookup generation sequence

Drops this coordinator's private counter for the identical allocator added on
the pull-request branch, so the "never reuse a generation id" invariant lives in
one place. The file is byte-identical on both branches, so either may merge
first.

* docs(store): describe the lookup generation sequence by its contract, not its callers

The JSDoc claimed the sequence was "shared by the pull-request and hosted-review
request coordinators", but the pull-request call site arrives in a sibling
change, so on this branch alone the comment named a caller that does not exist.

Describe what the module provides instead: one process-lifetime monotonic
allocator for lookup-ownership stamps, safe to share across every cache because
callers compare stamps for equality only, never order or magnitude. That stays
accurate whether one coordinator draws from it or several, so it needs no edit
when the second call site lands.

Applied identically on the sibling branch so the file stays byte-identical and
the two add/add introductions keep merging without conflict.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-26 23:37:45 -07:00
NeilandClaude 6ccfc1246c fix: preserve newer pull request lookup ownership (#23119)
* fix: preserve newer pull request lookup ownership

* refactor: share one lookup generation sequence between review coordinators

The sibling hosted-review fix needs the same never-reused generation id, so
move the allocator into src/renderer/src/store/lookup-generation-sequence.ts
instead of keeping a second private counter per coordinator.

Also assert in the lifetime test that a stale lookup cannot publish into
prCache and that the live lookup's answer is what lands there.

* docs(store): describe the lookup generation sequence by its contract, not its callers

The JSDoc claimed the sequence was "shared by the pull-request and hosted-review
request coordinators", but the hosted-review call site arrives in a sibling
change, so on this branch alone the comment named a caller that does not exist.

Describe what the module provides instead: one process-lifetime monotonic
allocator for lookup-ownership stamps, safe to share across every cache because
callers compare stamps for equality only, never order or magnitude. That stays
accurate whether one coordinator draws from it or several, so it needs no edit
when the second call site lands.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-26 23:37:28 -07:00
Neil 172083f304 fix: remove PDF export temp files after setup failures (#23130)
* fix: remove PDF export temp files after setup failures

* fix(export): keep PDF temp cleanup to files this export created, and time out a hung load

Two holes in the temp-document cleanup:

- The write was not an exclusive create, so anything already sitting at the
  generated temp path (a symlink planted in the shared temp dir) would be
  written through, and the cleanup would then unlink an entry this export did
  not create. The write now uses `flag: 'wx'`, and the one failure that means
  "this path is not ours" (EEXIST) skips cleanup entirely.
- The 60s timeout only covered render-and-print, started after the load had
  already finished. An export document whose script never yields fires neither
  `did-finish-load` nor `did-fail-load`, so the load await hung forever and the
  hidden window plus its temp file leaked for the life of the app. The timer now
  starts before `loadFile` and races the whole load-render-print sequence.

Tests cover the preserved foreign file, a never-settling load, a load that
resolves without either event, `did-fail-load`, and that one export's cleanup
cannot touch a concurrent export's in-flight temp file.
2026-09-26 23:19:45 -07:00
Neil 7ac9c8d675 perf: skip macOS DNS probes for unrelated errors (#23121)
* perf: skip macOS DNS probes for unrelated errors

* review(dns-probe-admission): single-source the probe gate and widen resolution-failure coverage

The admission guard duplicated the hint predicate at a second call site, so a gate
that drifted stricter than the hint test would silently drop the DNS diagnostic for
a real lookup failure. Route both through isMacTailscaleDnsHintCandidate, evaluated
once per call, and add a parity test asserting admission never changes the message
the ungated hint decision produces.

Also: widen the predicate to the resolution-failure wordings it missed (EAI_NONAME /
EAI_FAIL / ENODATA / getaddrinfo / "could not resolve" / "name or service not known" /
ERR_NAME_RESOLUTION_FAILED), gate the probe on process.platform === 'darwin' explicitly
rather than relying on the reader's internal check, make the hint idempotent so a
re-wrapped hinted message neither duplicates copy nor re-probes, and rewrite the
cache-window test to assert the resolver state the next relevant error reports instead
of pinning an exact probe count.
2026-09-26 23:07:24 -07:00
Neil 7505e55447 perf: share pending plugin translation startup requests (#23133)
* perf: share pending plugin translation startup requests

* fix(plugins): retry a wedged language-pack startup request instead of joining it

Sharing the pending startup request removed the duplicate IPC call, but the
suppression was permanent: plugins:listLanguagePacks awaits plugin discovery,
so a request that never settles left ensurePluginLanguagePacksLoaded a no-op
for the session. Every later consumer joined a request that would never
finish, where before each one retried — loaded stayed false, pinning the UI on
built-in translations and suppressing the TCC notices that gate on it.

Bound the join to a window instead of a boolean: a request that is merely slow
is still shared, one past the window is treated as wedged and a later consumer
starts its own. Adds the stalled-request test the change was missing.
2026-09-26 23:07:10 -07:00
Neil dc8f623a3a fix: retire stale review lookups after cache invalidation (#23182)
* fix: retire stale review lookups after cache invalidation

* test: pin the fence a retired review lookup answer has to clear

The extraction widened canAdoptDetachedAnswer: a retired owner is no longer in
the in-flight index, so with no replacement reader the scope generation is the
only thing stopping its pre-invalidation "no review" from being adopted as
current — which would short-circuit the lookup for the review Orca just opened.
Cover that interleaving, and restore the invariant comments the extraction
dropped (token identity, expire idempotency, and that a size-cap eviction
forfeits the wall-clock sweep).
2026-09-26 23:06:57 -07:00
Jinjing f5f537ef14 Revert "Support mouse Back/Forward buttons in shortcuts (#23287)" (#23350)
This reverts commit a86fae0889.
2026-09-26 22:58:01 -07:00
NeilandHarshul Rathod bdb897b735 Respect disabled OpenCode variants and refresh WSL settings safely (#23328)
Respect disabled OpenCode variants, preserve explicit config ownership, and refresh WSL guest settings safely across reconnects.

Based on Harshul Rathod proposal #22805.

Co-authored-by: Harshul Rathod <harshulrathod1640@gmail.com>
2026-09-26 22:48:35 -07:00
459410a63b Preserve Hermes YAML configuration during hook installation (#23324)
Preserve supported Hermes YAML values and comments while installing or removing Orca hooks.

Adapted from manthis and Pr1p proposals #22366 and #20632.

Co-authored-by: Maxime AUBURTIN <m@hellomax.io>
Co-authored-by: Chen <zwq19980411@gmail.com>
2026-09-26 22:13:24 -07:00
NeilandKelvin Amoaba 41607a9ddc fix(sidebar): preserve list focus when selecting workspaces (#23320)
Keep keyboard focus in the workspace list during selection changes, and transfer it to the selected terminal on Enter only when focus actually moves.

Based on Kelvin Amoaba proposal #22911.

Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
2026-09-26 22:01:24 -07:00
7438bc80f5 fix(orchestration): deliver dispatch mail and replies to the current lead (#23325)
Deliver Dispatch mail and ordinary replies to the current lead Run, preserving original delivery receipts and pre-bind mail draining.

Based on Seongho Bae proposals #22977 and #22979.

Co-authored-by: Seongho Bae <seonghobae@me.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 21:59:39 -07:00
Neil fddf8c8331 feat(editor): highlight Typst files and diffs (#23323)
Highlight Typst files and diffs through the existing lazy TextMate provider.

Based on contributor proposal #22884.
Co-authored-by: Quan Nguyen <qnguyen.dev2@gmail.com>
2026-09-26 21:58:14 -07:00
Neil f41cecc712 fix(search): keep commas inside grouped file filters (#23319)
Keep grouped commas intact when building search filters for ripgrep and Git.

Based on contributor proposal #22915.
Co-authored-by: KAPUIST <thsxornjs12@gmail.com>
2026-09-26 21:58:10 -07:00
Neilanddrakeo338 c3c53f1d24 fix(sidebar): show unread emphasis in compact agent rows (#23327)
Show unread emphasis in compact workspace rows using the existing pane acknowledgment state.

Based on drakeo338’s bounded PR #22870. pinhaum reported #22857 and proposed the broader #22899 variant; the local candidate preserves the existing acknowledgement policy.

Co-authored-by: drakeo338 <paranoyouz@gmail.com>
2026-09-26 21:47:26 -07:00
NeilandYi-111-a fa3642256f fix(terminal): retain Japanese middle dots and tildes in file links (#23322)
Retain Japanese middle dots and tildes in rooted and explicitly relative terminal file paths; preserve existing path routing and suffix handling.

Co-authored-by: Yi-111-a <47240345+Yi-111-a@users.noreply.github.com>
2026-09-26 21:45:32 -07:00
23e5e77637 fix(grok): show zero usage for an explicit zero quota (#23321)
Infer zero weekly Grok usage for a confirmed explicit zero quota while retaining unreported and monthly precedence safeguards.

Adapted from huiq777’s PR #22303 and the payload analysis from deminit02-hue in issue #20657. The accepted exception is limited to explicit zero cap.

Co-authored-by: Hui <a3239737781@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-26 21:45:28 -07:00
NeilandKAPUIST 2ce47d9bc2 fix(browser): accept dotted hostnames with explicit ports (#23318)
Allow dotted browser domains with explicit numeric ports through the existing URL normalizer.

Co-authored-by: KAPUIST <thsxornjs12@gmail.com>
2026-09-26 21:45:25 -07:00
Neil 1526d416e2 fix(terminal): recognize a Git Bash launcher by its install layout (#23308)
* fix(terminal): recognize a Git Bash launcher by its install layout

* fix(terminal): require git-bash.exe in the launcher install-layout check

* test(terminal): pin each Git Bash launcher install-layout marker as necessary
2026-09-26 21:35:09 -07:00
NeilandClaude 1f00eaeefd perf(history): coalesce tombstone directory rescans (#23031)
* perf(history): coalesce tombstone directory rescans

* perf(history): reuse one tombstone listing instead of re-reading per completion

Refilling the 64-slot tombstone removal window used to list the whole
`.pending-delete` directory again, synchronously, after every removal that
finished. A backlog of 1,024 tombstones cost 1,026 listings of a directory
that starts 1,024 entries long, all on the main process thread.

Each history root now keeps the names from its last listing and takes the
next one from memory when a slot frees, listing the directory again only
once that list runs out. The listing moved to `fs.promises.readdir`, so it
no longer blocks the main thread.

This replaces the previous coalescing-on-setImmediate approach, which left
the directory being re-listed once per completion batch and needed a
deferred-roots set, an event-loop turn of latency, and an unref'd immediate
whose freed slots could go unfilled at exit. Holding the names removes all
three.

Two behaviours are kept deliberately:

- Freed slots are offered across roots, so a root displaced at the shared
  cap is not stranded until the next startup.
- A listing cannot re-submit a removal that was already under way when it
  started, including one that finished before the listing resolved.

Five real-filesystem samples per version, 1,024 tombstone directories each
holding a meta.json, macOS arm64 / Node 24. Medians: directory listings
1,026 to 6, names enumerated 494,348 to 1,077, blocking main-thread time in
this path 820 to 7 ms, total drain 886 to 75 ms. The 886 ms breaks down as
266 ms of `readdirSync`, ~554 ms of per-entry work over those 494k names
and its garbage, and ~70 ms of actual recursive rm, which is the unchanged
floor the remaining 75 ms consists of. Average concurrent removals return
to 62 of 64 from the 46 a deferred refill left idle.

Adds coverage for a listing that fails mid-drain with later completions
still able to recover, and for both roots draining under one shared cap.
The heavy drain tests now run on real timers so real `fs.promises` and
microtask ordering are exercised.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(history): warn when a tombstone root read fails for a reason other than absence

readTombstoneNames swallowed every readdir error, so EACCES or ENOTDIR on the
initial enumeration left tombstones in place with no diagnostic until a later
completion happened to re-read. An absent root stays silent; it is the norm.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-26 21:22:47 -07:00
NeilandClaude 21170c6e22 perf: avoid repeatedly encoding retained VM recipe output (#23048)
* perf: avoid repeatedly encoding retained VM recipe output

* perf: capture retained VM recipe output as raw bytes in the shared byte buffer

The previous commit added a third byte-retention buffer to the repo. This
replaces it with the one that already existed and removes the remaining
encoding work.

`runRecipeCommand` no longer calls `setEncoding('utf8')` on the child's stdout
and stderr. It keeps the raw `Buffer` chunks and runs one `StringDecoder` per
stream to feed the existing string callbacks, which is exactly how
`setEncoding` is implemented, so callbacks see the same characters at the same
boundaries. With the bytes already in hand the capture encodes nothing: the
4,194,304 bytes the ring still encoded for 4 MiB of output drop to 0, and the
UTF-8 continuation trim collapses from one scan per chunk to a single scan when
the tail is decoded.

Retention is now `GrowingByteBuffer.appendRetainedSuffix`, which had no
production consumer. It gained an O(1) head offset, so `discardPrefix` and
`retainSuffix` mark bytes dead instead of moving the whole tail and `append`
slides or grows only when the head offset runs out of room. Quick Open path
accumulation and the SOCKS handshake buffer get that win too. Without the
offset the per-chunk memmove costs 12.36 ms for 4 MiB; with it, 0.25 ms against
the ring's 0.53 ms and the old per-chunk re-encode's 265.78 ms.

Two behaviour notes. Odd capture limits are clamped once at entry instead of
carrying a per-chunk coercion path no production caller could reach, so an
infinite or NaN cap is now bounded at 1 MiB rather than retaining everything.
And malformed UTF-8 yields a different tail: replacement characters no longer
inflate the byte count, so a malformed tail keeps more of what the recipe
actually wrote.

The encoding-budget assertions no longer spy on `Buffer` itself, where any
unrelated allocation in the same tick could flip them. They count bytes through
the capture's own buffer class and still assert the deterministic oracle: at
most 5 MiB moved for 4 MiB of output, exactly 4 MiB appended, 1 MiB decoded,
and the stored chunks identical to the Buffers the stream delivered.

Co-Authored-By: Claude <noreply@anthropic.com>

* test(vm-recipe): emit Buffers from the doctor stream doubles

Dropping setEncoding('utf8') means stdout and stderr now deliver Buffers, so
the hand-rolled EventEmitter doubles emitting strings threw inside the data
listener — the capture retained nothing and the exit path never settled.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-26 21:22:13 -07:00
Neil 080c4ad62a fix(ssh): name the missing unzip when Bun archive extraction cannot start (#23298)
* fix(ssh): name the missing unzip when Bun archive extraction cannot start

Extracting the downloaded Bun runtime shells out to `unzip` on POSIX hosts,
which a minimal Debian/Ubuntu install does not ship. runProcess rejects a
missing program with a bare `spawn unzip ENOENT`, which the caller's
non-zero-exit branch never sees, so the operator got an errno instead of a
remedy. Translate that one errno into a message naming the tool and the
ORCA_UNZIP_BIN override.

* fix(ssh): reuse the canonical absence predicate for extractor launch failures

isDefinitiveAbsence is the repo's single errno allowlist for "definitively not
there", and it also covers ENOTDIR — which spawn throws synchronously when a
configured ORCA_UNZIP_BIN has a regular file for a parent. That case previously
escaped as a bare `spawn ENOTDIR` naming no path at all.

Also correct the comment: a deleted working directory is not a second source of
these errnos, because runProcess leaves cwd unset and the child inherits the
parent's without resolving it. Verified on macOS, Linux and Windows.
2026-09-26 21:07:59 -07:00
Neil 067844b646 fix(design-system): replace hand-rolled diff draft-card shadow with shadow-xs (#23307)
The inline AI-note draft card in the diff view used a fourth, hand-rolled
box-shadow tier with raw rgba values instead of the documented shadow-xs
token, so it didn't track theme/token updates like the rest of the UI.
Restated the value under `.dark` too, since it shares selector specificity
with `.orca-diff-comment-popover`'s dark shadow later in the file and would
otherwise lose the cascade to that unrelated rule.
2026-09-26 20:56:41 -07:00
Neil 98cfdc809f fix(kimi): don't crash if config.toml is deleted mid-write (#23293)
* fix(kimi): don't crash if config.toml is deleted mid-write

writeConfigToml checked existsSync(configPath) then called statSync(configPath)
to preserve the file's mode, with no error handling in between. If the file
was deleted in that window (e.g. a concurrent uninstall), statSync threw
ENOENT and the exception escaped install()/getStatus() uncaught.

Now a missing-file stat during that race is treated the same as a missing
file at the check: fall back to the default 0o600 mode and continue the
write. Any other stat error still throws, preserving the existing
mode-read-failure behavior.

* fix(kimi): use isDefinitiveAbsence for the config delete-race check

Reuse the repo's canonical absence check instead of a hand-rolled ENOENT
comparison, per review feedback on #23293. isDefinitiveAbsence also covers
ENOTDIR (an ancestor directory replaced by a file), which the inline check
missed but is equally "the config is definitively not there."
2026-09-26 20:56:37 -07:00
NeilandClaude fed613bab7 perf: avoid rescanning partial notebook output frames (#23138)
* perf: avoid rescanning partial notebook output frames

* perf(notebook): stream bridge frames and skip the unused size accounting

The reader buffered every record of a chunk before delivering the first one, and
asked the framer for byte accounting it can never use. An unbounded line limit
cannot reject, so the per-segment `Buffer.byteLength` and the rejection-prefix
retention were pure overhead for the notebook and Codex readers; both are now
skipped once, behind a hoisted check. Frames are handed to the consumer as each
line completes, so the first output of a chunk paints without waiting for the
last.

The dropped buffer only ever preserved a trailing partial record across a
consumer throw, which cannot help: that throw leaves the stdout 'data' listener
and takes main down with it. Rejections are no longer discarded either — the
bridge keeps fd 1 to itself, so an unreadable line means the frame channel is
damaged and now says so.

Tests move into notebook-kernel.test.ts beside the reader's existing coverage,
and add the never-terminated record and a guard that no record bytes are
measured when no limit applies.

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-26 20:48:19 -07:00
Neil a2325bbb9b fix(worktrees): clear orphan cleanup on BusyBox WSL distros (#23296)
The WSL "is this path gone?" probe decided a path was missing by matching
GNU coreutils' exact wording, `stat: cannot statx ...`. BusyBox writes
`stat: can't stat ...`, so on an Alpine-style distro a successful orphaned
worktree delete was still reported as a permanent failure, on every retry.

Match only the trailing strerror text, which is POSIX and already pinned to
English by the probe's LC_ALL=C. Permission failures still report failure.
2026-09-26 20:43:45 -07:00
NeilandClaude 375c0279c5 perf: bound wildcard segment work in nested repository scans (#23149)
* perf: bound wildcard segment work in nested repository scans

* perf: bound the ** path walk in nested repository scans, not just one segment

The wildcard-segment fix left the larger blowup in place. A short .gitignore line
made only of `**` segments still costs exponential work in the outer path walk:
`**/**/.../z` at 24 segments and 73 characters, against an eight-segment
candidate, takes about 49 million recursive calls and ~150 ms here — larger than
the 25 ms single-segment case this branch removes. Rules are inherited down the
tree and re-checked for every directory, so that price is per directory, the
runtime's 15s scan timeout fires, and the user silently gets a short repo list.

Two independent bounds, both kept:

- `**` spans zero or more segments, so `**/**` accepts exactly what `**` accepts.
  Parsing now collapses a run of them to one segment, taking the reported shape
  from 49M recursive calls to 26 matcher steps.
- The walk memoizes on (pattern index, candidate index), so no other arrangement
  of `**` can reintroduce the blowup. A rule holding at most one `**` is already
  linear and skips the table, because allocating it costs more than the walk it
  would save on the shapes real ignore files contain.

The budget suite's process-CPU ceiling is replaced by a matcher step counter read
through `readNestedRepoGlobMatchSteps`, so an algorithmic regression fails the
suite rather than passing on a fast machine. Each bound has its own budget case,
and each fails when only the other is applied.

The equivalence oracle now also covers multi-segment and anchored patterns
including `**`, checked against the pre-change per-segment expression walking
uncollapsed segments. Code-unit and metacharacter cases are unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-26 20:39:42 -07:00
OrcaWinandm4air 3eb1adec20 ci: reuse fixture setup and scope localization extraction (#23291)
Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
2026-09-26 18:46:26 -07:00
OrcaWinandm4air 46907de602 fix(ssh): recover abandoned caches without deleting live dependencies (#23281)
Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
2026-09-26 18:17:34 -07:00
Neil 5b11834d68 fix(editor): preserve Markdown source across rich edits (#23280)
* fix(editor): preserve Markdown source across rich edits

* perf(editor): remove repeated Markdown suffix scans and block reparses

* fix(markdown): retain case-insensitive editable details parsing
2026-09-26 18:10:21 -07:00
OrcaWinandm4air 6433c3c7a3 fix(ssh): preserve interrupted installation outcomes through retries (#23273)
Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
2026-09-26 18:03:55 -07:00
Neil a86fae0889 Support mouse Back/Forward buttons in shortcuts (#23287)
* feat: support mouse Back and Forward shortcut bindings

* fix: ignore duplicate mouse shortcut presses until release
2026-09-26 17:53:58 -07:00
OrcaWinandm4air 47ddfbdc0d feat: let users choose JSON or SQLite when profile copies diverge (#23278)
Replace the copy-a-command startup dialog for diverged JSON/SQLite profile
state with Use SQLite / Use JSON buttons. The choice relaunches Orca into the
locked recovery preflight, applies it, then starts normally. Adds a
current-sqlite recovery selector (and --current-sqlite CLI flag) that archives
the diverged JSON and republishes it from SQLite.

Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
2026-09-26 17:03:05 -07:00
ee6281ff79 fix: dispose OpenCode 2 hooks after prompt setup and cleanup failures (#23209)
* fix: dispose OpenCode 2 hooks after prompt setup and cleanup failures

* test: pin reviewed OpenCode setup cleanup bytes

* fix(i18n): restore diff note draft catalog entries

* test: isolate historical hourly build version inputs

* test: align historical package input with shared CI repair

* test: inject hourly package version without module mocking

* test: share the hourly package input contract across CI repairs

* test(windows): verify NSIS policy with native PowerShell modules

---------

Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
Co-authored-by: OrcaWin <alpha-eng@stably.ai>
2026-09-26 15:30:41 -07:00
Neil 34d055c2fa perf(relay): release canceled AI Vault startup requests (#23027)
* perf(relay): release canceled AI Vault startup requests

* test: pin the historical hourly package version fixture

* test: provide the historical package version through build options

* test(ai-vault): cover delayed readiness rejection across restart
2026-09-26 15:27:21 -07:00
Neilandm4air 003b37d6e0 perf: cap shared-path scans and synchronize Windows PTY access (#23194)
* perf: stop scanning shared paths when suggestions are full

* fix(i18n): restore diff note draft catalog entries

* fix(windows): synchronize native terminal table lifetime

* fix: restore catalog entries required by the current CI baseline

* fix(i18n): make AI the recipient of diff notes

* fix(ci): preserve focused Playwright file selection

* test(ci): require focused commands on every platform

Assert each golden platform step and its focused arguments before deduplicating Playwright discovery probes.

* test: pin the historical hourly package version fixture

* test: provide the historical package version through build options

* test(windows): retain PTY stress failure evidence

---------

Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
2026-09-26 15:15:17 -07:00
OrcaWinandm4air 408499ec58 Keep SSH terminals parked after their own workspace updates (#23193)
* fix(ssh): suppress workspace echoes acknowledged during stale reads

* fix(ssh): preserve newer workspace observations during resync

* fix(ssh): retain newer own acknowledgements during stale reads

* fix(ssh): deliver peer snapshots cached by rejected patches during stale reads

A stale-revision patch reply caches the peer snapshot under a new host
observation token, but the renderer only records a conflict and blocks
uploads. Suppressing an identical stale read then left the peer change
unapplied. Only suppress when the intervening write kept the pre-read
token, which is what a contiguous own acknowledgement does.

---------

Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
2026-09-26 15:11:34 -07:00
Neilandm4air 8f173581f3 fix: refresh strict Gitea lookups and synchronize Windows PTY access (#23162)
* fix: refresh strict Gitea lookups after creating a review

* fix(i18n): restore diff note draft catalog entries

* fix(windows): synchronize native terminal table lifetime

* fix(ci): preserve focused Playwright file selection

* test: isolate hourly identity inputs from release version changes

* test(windows): retain PTY stress failure evidence

* test(orcad): preserve launcher startup phase evidence on timeout

* test(ci): require focused commands on every platform

Assert each golden platform step and its focused arguments before deduplicating Playwright discovery probes.

---------

Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
2026-09-26 15:11:23 -07:00
4c38cabb4e fix(windows): synchronize native terminal table lifetime (#23257)
* fix(i18n): restore diff note draft catalog entries

* fix(windows): synchronize native terminal table lifetime

* fix(ci): preserve focused Playwright file selection

* test(windows): retain PTY stress failure evidence

* test: isolate hourly identity inputs from release version changes

* test(ci): require focused commands on every platform

Assert each golden platform step and its focused arguments before deduplicating Playwright discovery probes.

---------

Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
Co-authored-by: Neil <neil@stably.ai>
2026-09-26 15:11:17 -07:00
OrcaWinandm4air 10cfe9218f test: target writer timeouts and diagnose Bun startup stalls (#23267)
* test(persistence): start the fault timer after the real worker is ready

* test(orcad): preserve launcher startup phase evidence on timeout

* test: isolate historical hourly build version inputs

* test: align historical package input with shared CI repair

* test: inject hourly package version without module mocking

* test: share the hourly package input contract across CI repairs

---------

Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
2026-09-26 15:05:44 -07:00
Neilandm4air b4717f0f57 fix: honor canonical SSH ownership in worktree listings (#23198)
* fix: honor canonical SSH ownership in worktree listings

* test: name SSH listing host encodings explicitly

* fix(i18n): restore diff note draft catalog entries

* fix: consolidate execution host imports in listing handlers

* test: isolate historical hourly build version inputs

* test: align historical package input with shared CI repair

* test: inject hourly package version without module mocking

* test: share the hourly package input contract across CI repairs

---------

Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
2026-09-26 15:05:37 -07:00
3ab183d770 fix: stop stale runtime event work after renderer cleanup (#23066)
* fix: stop stale runtime event work after renderer cleanup

* fix(i18n): restore diff note draft catalog entries

* test(browser): report the phase of WebRTC probe timeouts

* fix: preserve runtime subscription ownership during nested sync

* test: isolate hourly identity inputs from release version changes

---------

Co-authored-by: OrcaWin <alpha-eng@stably.ai>
Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
2026-09-26 15:05:30 -07:00
Neil 1554f15b6c fix: close abandoned static web asset readers (#23062)
* fix: close abandoned static web readers and align AI note labels

* test: pin the historical hourly package version fixture

* test: provide the historical package version through build options
2026-09-26 15:01:38 -07:00
Neil 5f72c54f9d fix: bind filesystem root grants to their repository owner (#23206)
* fix: bind filesystem root grants to their repository owner

* test: name repository host encoding in ownership cases
2026-09-26 14:58:47 -07:00
Neil be5d10c830 Cancel abandoned relay search work (#22997)
* fix: cancel abandoned relay searches

* fix: restore catalog entries required by the current CI baseline

* fix(i18n): make AI the recipient of diff notes
2026-09-26 14:37:34 -07:00
OrcaWinandm4air 4b6fe95943 fix(windows): preserve relocated terminals and native process scans (#22872)
* fix(windows): ship the process-table addon to the relocated daemon host

The Windows terminal daemon runs from a copy of the app under
%LOCALAPPDATA%\Orca\daemon-host\<version>. That copy took node-pty but not
@vscode/windows-process-tree, so the daemon's bare require of the addon found
nothing and every process-table read (foreground tracking, descendant sweeps)
fell back to a powershell.exe Get-CimInstance scan (#16905).

- Copy the addon's runtime files (package.json, lib/, the .node binary) into
  the host; the ~25MB of gyp intermediates beside them are filtered out.
- Treat a host missing those files as unmaterialized, so hosts built before
  this are rebuilt, and skip relocation if the install itself lacks them.
- Log the daemon's native/CIM capability at startup and warn once when the
  process table falls back to CIM.

Revives #19525 on current main.

* test(windows): locate update-survival loss before relaunch

* test(windows): preserve daemon tree before update-survival proof

* test(windows): distinguish Electron exit from launcher close timeout

* test(windows): verify process exit when inherited pipes delay close

* test(windows): trace installer process checks in isolated survival runs

* fix(windows): probe process-query capability before installer sweep

* fix(windows): match installer probe and process-check profile behavior

* fix(windows): use NSIS separators for the process-check include

* test(windows): dismiss session-search overlay in survival harness

---------

Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
2026-09-26 14:31:07 -07:00
Neil f7abecde01 fix: release file watches when their renderer document ends (#23055) 2026-09-26 14:29:30 -07:00
Jinjing b42de170b1 Implement responsive browser toolbar overflow with tool folding (#23265)
Toolbar buttons fold into a dropdown menu when space is constrained,
preserving minimum address bar width. ArtifactPublishButton gains
controlled popover state with optional virtual anchoring. Tour-pinned
tools stay visible while others fold in priority order.
2026-09-26 14:23:20 -07:00
fe50f3ed04 fix: release dictation session listeners when speech workers exit (#23077)
* fix: release dictation session listeners when speech workers exit

* fix(i18n): restore diff note draft catalog entries

* fix(i18n): make AI the recipient of diff notes

* test(persistence): start the fault timer after the real worker is ready

---------

Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
Co-authored-by: OrcaWin <alpha-eng@stably.ai>
2026-09-26 14:23:03 -07:00