Commit Graph
317 Commits
Author SHA1 Message Date
Neil a50a44bb8d feat(wsl): bridge sh/dash/ash panes report their folder (OSC 7) at every prompt (#35597)
* feat(wsl): bridge sh/dash/ash panes report their folder (OSC 7) at every prompt

bash, zsh, fish and nushell panes already tell the terminal daemon their
folder; a bridge pane whose login shell is sh, dash or busybox ash did
not, so restores fell back to the starting folder.

dash has no rcfile flag or prompt hook, but an interactive sh reads $ENV
after ~/.profile, and dash 0.5.8+ (plus ash and bash-as-sh) expand $(...)
in PS1. The bridge now points ENV at a new sh/env file in the published
wrapper tree, saving the user's own ENV. That file hands ENV back to the
user's value (so children see theirs), sources it, and inside WSL only
prefixes PS1 with the report. A root containing $, ` or \ is skipped,
since the shell expands ENV's value.

A non-interactive sh -c never reads ENV, and a missing file (Orca
updated away or uninstalled) is silently ignored by dash, ash and bash.

* fix(wsl): sh ENV hook survives quotes in the user's ENV and keeps prompt width

- The user's ENV is expanded through a here-document, so a value with a
  quote, $ or space no longer breaks startup with a syntax error.
- bash-as-sh and busybox ash (fancy prompt) get the report inside \[ \]
  so its invisible bytes don't count toward the prompt width; dash has no
  line editor to miscount and would print \[ literally, so it stays bare.
- Tests: a user ENV of `$HOME/u "q" sp/env`, a user PS1 with $, a quote
  and a backslash, and reports read through the daemon's WSL parser.
- CI: edits to the sh hook and the bridge launch trigger the shell
  contracts job (its prefix list moves to its own module, keeping the
  scope script under its line limit), and the sh and fish WSL pty tests
  leave the unit shards.

* ci: check out the shell-contract prefix module in the change detector

The detector job sparse-checks-out a fixed file list; the new
pr-shell-contract-prefixes.mjs that pr-code-change-scope.mjs imports was
missing from it, so the job failed with ERR_MODULE_NOT_FOUND. A contract
test now walks the scope script's local imports and requires each in
that list.

* ci: list the shell-contract prefix module wherever the scope script's modules are listed

Two config-script suites copy pr-code-change-scope.mjs and its sibling
modules into a fixture repo; without the new pr-shell-contract-prefixes.mjs
the copied script failed to load, and the detector fell back to running
everything. Also lists it with the scope script's other modules in the
mobile workflow trigger and the mobile non-test file set.
2026-10-28 21:56:13 -07:00
OrcaWinandOrcaWin 3ce252c79a ci: run preflight on free hosted ARM off the PR critical path (#35652)
Unit shards now wait for a standalone plan job instead of preflight, and
packaging and the layout oracle start immediately, so preflight's slower
free runner no longer delays the PR gate.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 21:30:26 -07:00
OrcaWinandOrcaWin 006bbb28e7 ci: run PR unit shards on free hosted ARM as 12 shards (#34906)
* ci: run PR unit shards on free hosted ARM as 12 shards

Enterprise's 1,000-job limit makes more, smaller shards free. A 12-shard
cold run on ubuntu-24.04-arm measured 361s median / 412s max per shard,
against ~390s / ~441s for five warm Blacksmith 8-vCPU shards.

The Blacksmith-store module cache producer becomes dispatch-only since
hosted shards cannot read it.

* TEMP: force 12 shards on this PR (repo var is still 5); drop before merge

* test: size the full-inventory routing check from FULL_SHARD_COUNT

* Revert TEMP 12-shard override; the repository variable is now 12

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 21:10:45 -07:00
Neil 5616230ecd feat(wsl): bridge fish panes report their folder (OSC 7) at every prompt (#35517)
The bridge fish launch's -C now also defines a fish_prompt hook that
sends the same percent-encoded OSC 7 as bash and zsh, only inside WSL,
after the user's config.fish.
2026-10-28 18:10:58 -07:00
OrcaWinandOrcaWin 12a7d4c13a feat(mobile): localization infrastructure and language setting (#35399)
* feat(mobile): add UI localization infrastructure

Mobile follows the phone's language (or an in-app choice under Settings > Appearance)
across the same 11 languages as desktop, switching live like the theme does.

- i18next with desktop's translate(key, fallback, options) call shape; catalogs in
  mobile/src/i18n/locales load lazily, English fallbacks stay inline
- Hermes lacks Intl.PluralRules: load the FormatJS polyfill with the 11 languages' rules
- OTA pages get the shell's language through an optional bridge init field
- iOS permission prompts localized; iOS and Android 13+ per-app language pickers
- verify:mobile-localization and a coverage ratchet run in lint, check:changed and CI

* fix(mobile): mount pages after the newest language request; tighten localization gates

- Wait for the latest page language activation, not a superseded one
- Keep literal fallbacks when a key also has a dynamic one
- Count headerTitle as visible copy; select the mobile check when the runtime catalog generator changes

* feat(mobile): repaint themed components on language changes

Components that read the theme already subscribe for repaint; a language switch
repaints them too, so labels built by helpers during render follow it. RPC
recordings load the real i18next and JSON catalogs.

* fix(mobile): scope the translate() gate to render bodies and memos; prune stale keys on sync

Handlers and effects may call translate() when they run. sync:mobile-localization now
removes keys no code references from every catalog.

* fix(mobile): use node: imports in the locale config plugin; pass uiLocale in bridge hook test

* chore(mobile): refresh the localization coverage baseline

* fix(mobile): follow render callbacks in the translate() gate; keep used plural siblings on prune

Also let anonymous default-exported screens count as components, flag any plural
family a locale started, and mark JSON modules as ES modules in the recording loader.

* fix(mobile): treat async and named local callbacks as handlers in the translate() gate

* chore(mobile): refresh the localization coverage baseline

* chore(mobile): refresh the localization coverage baseline

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:14:05 -07:00
Brennan Benson bb1b05e3bd Clear Google cookies from a browser profile, as often as you need (#34158)
* Add repeatable Google cookie clearing for browser profiles

* Bind Google cookie clearing to its successful import target

* Repair cookie-clear contract test boundaries and positive flows

* Correct cookie-clear test fixture typing

* test: use checked runtime bindings in browser profile RPC fixture

* test: provide page registry to sidecar forwarding fixture

* fix: use selected browser profile owner for cookie clear menus

* test: provide confirmation context to link materialization fixture

* test: classify cookie clear session channels

* refactor: consolidate browser command property guards

* test: update cookie clear fixture for merged registry API

* feat: move Google sign-in recovery to browser settings

* Freeze Settings Google cookie clearing intent and refresh availability

* Restore baseline browser import disclosure coverage

* Pass the selected browser profile into cookie settings

* Localize Google cookie settings search keywords

* Update cookie restart fixture policy exports

* Keep localized browser search results visible

* fix: make Google cookie clear a red right-aligned setting that explains when to use it

* Explain why Google cookies are handled separately in the clear row caption
2026-10-28 14:40:57 -07:00
Neil 045f8c8266 feat(files): show images and PDFs from the byte-range preview path, local and remote (#35165)
* feat(files): show images and PDFs from the byte-range preview path, local and remote

ImageViewer and PdfViewer read an orca-media:// URL instead of base64 when
the editor opens a file: images load by URL, and pdf.js reads PDFs by
range, so a large PDF no longer arrives whole through files.readPreview or
pages into memory first. The grant mints only for the editor's viewers;
diffs, git blobs, markdown images and the paired web client keep base64.

- Minting an image checks its header with the base64 path's rule, so an
  image proven too large to decode safely never reaches the decoder.
- orca-media gains fetch and CORS privileges, and range responses expose
  Accept-Ranges and Content-Range, so pdf.js can read by range.
- Grants report the file size the viewer used to estimate from base64.

* fix(files): read PDFs by real range, check served images, keep old hosts' previews

- pdf.js fetches ranges only over http(s), so an orca-media URL was read
  whole; a small range transport now hands it bytes=a-b reads from the
  grant, and a failed range fails the preview instead of hanging it.
- A file can change after mint, so the raster header is checked again on
  the bytes each image request serves (the same handle locally).
- A paired host without files.readChunk falls back to files.readPreview
  for images and PDFs, as before; only audio and video need the update.

* fix(files): mint no local document grant for a renderer gone mid-mint

The local image/PDF mint is async now (authorize, open, header check), so
a renderer that closed meanwhile could leave a grant no teardown drops. It
binds the renderer lifetime first and refuses to mint once it's gone, as
the remote mint does.

* fix(files): keep the 50 MB cap for URL images, and probe remote headers incrementally

An <img> decodes the whole file, so image grants keep the base64 path's
50 MB cap; PDFs, now read by range, don't need one. A remote header probe
reads only each wider step's new bytes instead of re-reading from the
start. A replaced image of a different size resets its zoom.

* fix(files): tear down a PDF load whose range failed, and read 256 KiB ranges

A failed range only showed the error and left the pdf.js task, its worker
and pages alive; it now destroys that load first. pdf.js asks for one
readChunk-sized range at a time instead of 64 KiB, and a Range preflight
gets its CORS answer instead of 405.

* fix(files): read PDF ranges over IPC so orca-media needs no fetch or CORS

orca-media had gained supportFetchAPI and corsEnabled, and its responses
sent Access-Control-Allow-Origin: *, so pdf.js could fetch ranges. That let
any default-session frame holding a token read the bytes. pdf.js now reads
a PDF grant's ranges through fs:readPreviewRange, which main answers only
for the renderer that minted the token. The scheme is back to element-load
privileges (standard, secure, stream), responses carry no CORS headers, and
preflights get 405.

Grant bookkeeping moves to preview-grant-registry.ts. An e2e spec proves an
orca-media URL can't be fetched from the app page or read from another
session.

* ci(e2e): route the byte-range preview sources to the viewer specs that exercise them

Changes to the orca-media grant path, the image/PDF viewers and the PDF
range transport now run the PDF reload, rebuild and find specs, the remote
large-file open, media playback and the partition-isolation spec.

* fix(files): stop PDF range reads on abort, abort remote reads with the window, fix the CI route

- A closed or reloaded viewer schedules no further pieces of a merged range,
  and a remote range read stops when its window goes away.
- A URL without a size is an error rather than a fetch the scheme refuses.
- The PR guard job's sparse checkout and its admission test include the new
  route module, and the route now also covers the mint handler, preload
  bridge, editor surfaces, scheme registration and read client.

* fix(files): classify linked previews by their target, keep range reads off stopped WSL distros

A local image or PDF reached through a link is classified by the file it
resolves to, at mint and on every read, and a re-mint after the link is
retargeted gets a fresh grant of the new type. A paired host's document
whose first bytes are another kind defers to files.readPreview, which
classifies the target there. Lazy local reads go through the non-waking
WSL guard, as fs:readFile and fs:readFileChunk do.
2026-10-28 09:31:22 -07:00
OrcaWinandOrcaWin ca2154945b ci: run advisory e2e lanes on free hosted runners (#34725)
The layout oracle merge gate keeps Blacksmith via fast_runners: true; the
advisory e2e call, nightly schedule and layout-owner dispatch run on
ubuntu-24.04.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 22:08:17 -07:00
8b64ec281a ci: restore main's Vitest transform cache in PR unit shards (#34512)
* ci: restore main's Vitest transform cache in PR unit shards

Main produces per-shard transform caches on a schedule; PR shards restore
the newest one for the same config/lockfile/runtime policy. A Vitest cache
key generator folds each literal specifier's resolution candidates into the
per-module key so newly added files that shadow a resolution invalidate the
importer, and bails on glob-expanded dynamic imports.

* ci: list the resolution key plugin in the node tsconfig project

* ci: accept Vitest's CACHEDIR.TAG when sealing the unit module cache

Vitest 5.0.5 tags its cache root, which made every seal fail with
'invalid cache entry name' so no producer cache was ever saved.

* ci: reseed the unit module cache when any cache-key input lands on main

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

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-10-27 20:04:56 -07:00
OrcaWinandOrcaWin e0f32dcac1 ci: seed hosted Linux packaging and mobile bundle caches on main, and stop PR-local saves (#34672)
- Warm electron-builder-linux-<versions> and the hosted ubuntu-24.04 Electron native modules
- PRs restore hosted Linux Electron native modules without saving
- Replace mobile verify's bundler-cache with a restore of a warmup-saved bundle
- Drop the pnpm store cache where a direct install was faster (mobile main, glibc-floor containers)

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 19:40:29 -07:00
OrcaWinandOrcaWin 4cd62c4946 ci: split the layout oracle window scenarios across two shards (#34671)
The single-file oracle cannot be split by whole-file balancing, so pass
Playwright test-level shards to the changed-spec lane. It was the last
required check in 40 of 42 measured runs.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 19:25:17 -07:00
OrcaWinandOrcaWin 2cd3e6d6a3 ci: narrow churny cache keys and move PR-local cache saves to main (#34600)
* ci: narrow native, launcher and packaging cache keys and stop PR-local saves

* ci: hash Rust crate sources, not build outputs, in launcher and hook keys

* ci: fail closed on unlocked native packages and cover transitive key inputs

* ci: resolve the Windows Rust cache scope with a script, not a nested local action

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 18:14:29 -07:00
59dbb54dad ci: keep Git compatibility on Blacksmith (#34625)
Its three parallel real-Git lanes, two of them through Docker, push
git-binary-compatibility.test.ts past the 30s test timeout on the 4-vCPU
hosted runner (64s file time vs 14s), failing PR #34600 twice after #34566.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-10-27 17:29:39 -07:00
OrcaWinandOrcaWin 9cc555e2de ci: run off-critical-path PR jobs on free GitHub-hosted runners (#34566)
Keep preflight and the unit-test matrix (the PR critical path) on Blacksmith; move routing, aggregation, contract, packaging and mobile checks to hosted standard runners, which are free for public repos under Enterprise concurrency.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 15:19:23 -07:00
Kelvin Amoaba 917ef9c737 feat(browser): install Chrome extensions from the Web Store into Orca's browser (#30940) 2026-10-27 22:04:12 +00:00
hwantageandNeil 483573f0b9 fix(browser): focus newly opened image tabs (#34127)
* fix(browser): focus newly opened image tabs

Focus the window before the webview so Command+W closes the new
image tab instead of the original tab after a plain image click.

Add tests for focus order, image loading, and close-shortcut forwarding.

Fixes #34114

* test(browser): verify image tab focus with native keyboard input

* refactor(ci): keep browser E2E routes within registry size limit

* fix(ci): enable background launch for native browser regression

* test(ci): include browser routes in isolated detector fixture

---------

Co-authored-by: Neil <neil@stably.ai>
2026-10-26 22:52:40 -07:00
ad2156c358 test: remove 140 low-value cases and 49 suites (#34062)
* test: remove 140 low-value cases and redundant browser probes

* fix: remove unused upstream chat menu import

* test: pin the host-split layout fixture branch

---------

Co-authored-by: Orca Test Audit <test-audit@stably.ai>
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-26 15:16:27 -07:00
OrcaWinandOrcaWin f34c13ca1e test: remove low-value main-process suites and browser probes (#33889)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-26 12:48:28 -07:00
OrcaWinandOrcaWin 819d273e27 perf(lint): one ast-grep scan feeds both the lint gate and the flaky-test ratchet (#33903)
lint:ast-grep and check-flaky-test-pattern-ratchet each parsed the whole tree.
ast-grep-gates.mjs scans once; the lint gate re-runs ast-grep only on files with
warning-or-error findings (ast-grep's own report and exit code), and the flaky
ratchet counts test-* matches from the shared scan.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-26 03:50:42 -07:00
OrcaWinandOrcaWin a26006aa6a perf(ci): overlap preflight's serial tail; parallel ratchets; allow 2-10 unit shards (#33887)
- Plan unit selection starts after setup (overlaps lint) instead of last.
- Localization extraction starts with the typecheck; test-file-runners is background.
- run-ratchets.mjs runs ratchets in a pool (19s serial -> 8s locally).
- pnpm lint uses CI's single-parse check-import-boundaries.mjs.
- ORCA_UNIT_FULL_SHARD_COUNT accepts 2-10 (default stays 5).

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-26 03:17:34 -07:00
Jinwoo Hong a5f7da4928 revert(daemon): ship official Node in the macOS terminal host again, keep stall telemetry (#33688)
Reverts #29133 except its daemon async-I/O stall telemetry, so we can measure how often stalls happen on official Node before committing to a patched runtime. The macOS terminal host goes back to the official Node 24.22.1 download and the daemon protocol back to v51; no release or hourly build published v52.
2026-10-25 20:07:30 -04:00
Neil 65e513b193 fix(daemon): recover lost macOS worker wake-ups in the packaged terminal runtime (#29133)
Builds the macOS terminal host's Node 24.22.1 from pinned source with a libuv patch: idle threadpool workers recheck for queued work every 30 s instead of waiting forever, so a lost Darwin condition-variable wake-up (libuv #5280) no longer strands terminal I/O. Bumps the daemon protocol to v52 so new terminals start on the patched runtime right after an update; older daemons stay attachable. Adds stalled/recovered daemon async-I/O telemetry, and lets release workflows rebuild older refs that predate the source build.

Fixes STA-11709, #31926.
2026-10-25 17:28:34 -04:00
OrcaWinandOrcaWin 7d6603aa17 [comment audit] Complete repository-wide comment cleanup (#33249)
* [comment audit] Align legacy failure-read counts with cached display

* [comment audit] Condense shared provider lifecycle and browser recovery comments [skip ci]

* [comment audit] Condense shared generation, path and preview comments [skip ci]

* [comment audit] Condense host, file and Git contract rationale [skip ci]

* [comment audit] Tighten Git lifecycle and provider contract comments [skip ci]

* [comment audit] Clarify shared host authority and launch isolation [skip ci]

* [comment audit] simplify local access mobile and native chat contracts [skip ci]

* [comment audit] simplify native chat presentation and state contracts [skip ci]

* [comment audit] simplify native runtime and provider contracts [skip ci]

* [comment audit] simplify migration and orchestration contracts [skip ci]

* [comment audit] simplify plugin trust and process capture rationale [skip ci]

* [comment audit] simplify terminal delivery and remote compatibility rationale [skip ci]

* [comment audit] clarify remote recovery and launch wire rationale [skip ci]

* [comment audit] shorten shared RPC compatibility and runtime evidence comments [skip ci]

* [comment audit] simplify secure storage shell startup and sidebar rationale [skip ci]

* [comment audit] clarify sidebar, skill and SSH invariants [skip ci]

* [comment audit] condense structured chat delivery and timing rationale [skip ci]

* [comment audit] condense terminal replay and telemetry invariants [skip ci]

* [comment audit] clarify launch permission and terminal delivery rationale [skip ci]

* [comment audit] clarify workspace ownership and layout contracts [skip ci]

* [comment audit] wait for fitted and painted SSH terminal links

* [comment audit] clarify layout persistence and session ownership [skip ci]

* [comment audit] clarify host routing and workspace lifecycle contracts [skip ci]

* [comment audit] clarify startup persistence and app lifetime comments [skip ci]

* [comment audit] clarify recovery and activity boundaries [skip ci]

* [comment audit] condense activity and artifact invariants [skip ci]

* [comment audit] condense automation authority contracts [skip ci]

* [comment audit] simplify automation scheduling and history contracts [skip ci]

* [comment audit] clarify browser chrome and annotation lifecycles [skip ci]

* [comment audit] clarify browser routing and retained guest ownership [skip ci]

* [comment audit] clarify browser recovery and document ownership comments [skip ci]

* [comment audit] restore hosted runners required by native IME fixtures

* [comment audit] shorten preview, palette and dashboard invariants [skip ci]

* [comment audit] clarify terminal preview, dashboard and retention comments [skip ci]

* [comment audit] clarify diff-note recovery and editor lifecycle comments [skip ci]

* [comment audit] shorten rich-text and combined-diff ownership comments [skip ci]

* [comment audit] shorten autosave, draft recovery and model ownership comments [skip ci]

* [comment audit] shorten save-queue, notebook and Markdown constraints [skip ci]

* [comment audit] shorten Monaco, PDF and rich Markdown safeguards [skip ci]

* [comment audit] clarify rich Markdown source and selection safeguards [skip ci]

* [comment audit] clarify editor loading and emulator stream lifetimes [skip ci]

* [comment audit] trim emulator and feature tour narration [skip ci]

* [comment audit] clarify floating workspace and GitHub cache ownership [skip ci]

* [comment audit] trim provider controls and Linear filter explanations [skip ci]

* [comment audit] clarify pairing and chat resume lifetimes [skip ci]

* [comment audit] clarify chat delivery and transcript lifetimes [skip ci]

* [comment audit] clarify session options and host-owned status [skip ci]

* [comment audit] clarify draft durability and live-status precedence [skip ci]

* [comment audit] Trim chat send and model ownership explanations [skip ci]

* [comment audit] Shorten transcript ownership and send recovery comments [skip ci]

* [comment audit] Simplify native chat composer and transcript hook comments [skip ci]

* [comment audit] Shorten native chat scroll and structured session explanations [skip ci]

* [comment audit] Trim workspace picker and onboarding commentary [skip ci]

* [comment audit] Simplify pet rendering, review cache and quick open comments [skip ci]

* [comment audit] Trim sidebar and session history explanations [skip ci]

* [comment audit] Condense session resume and review checks comments [skip ci]

* [comment audit] Shorten checks state and file explorer refresh comments [skip ci]

* [comment audit] Trim plugin bridge and source-control action rationale [skip ci]

* [comment audit] Trim source-control listing and review rationale [skip ci]

* [comment audit] Shorten sidebar lifecycle and explorer safeguards [skip ci]

* [comment audit] Condense Settings account and appearance rationale [skip ci]

* [comment audit] Trim pairing and repository Settings explanations [skip ci]

* [comment audit] Condense Settings search SSH and terminal safeguards [skip ci]

* [comment audit] Shorten Settings voice and provider ownership comments [skip ci]

* [comment audit] Condense Settings draft persistence and host-state rationale [skip ci]

* [comment audit] Trim Settings hooks and sidebar setup rationale [skip ci]

* [comment audit] Condense sidebar deletion and board-filter safeguards [skip ci]

* [comment audit] Condense worktree cards, host ownership and Markdown contracts [skip ci]

* [comment audit] Condense sidebar drag, folder and filtering contracts [skip ci]

* [comment audit] Condense sidebar parity, sleep and host ownership contracts [skip ci]

* [comment audit] Prune focus-read baseline after comment cleanup

* [comment audit] Clarify sidebar visibility, board drops and agent evidence [skip ci]

* [comment audit] Tighten sidebar listing, drag and reveal contracts [skip ci]

* [comment audit] Clarify viewport geometry and skill update safeguards [skip ci]

* [comment audit] Tighten skill inventory, usage and host status comments [skip ci]

* [comment audit] Clarify usage ownership and resource kill safeguards [skip ci]

* [comment audit] Tighten tab selection, rename and search contracts [skip ci]

* [comment audit] Tighten tab-strip geometry and drag ownership comments [skip ci]

* [comment audit] Tighten Tasks recovery, pagination and mutation comments [skip ci]

* [comment audit] Tighten provider loading and terminal recovery comments [skip ci]

* [comment audit] Tighten completion, cadence and PTY ownership comments [skip ci]

* [comment audit] Clarify terminal restore and parked-pane boundaries [skip ci]

* [comment audit] Tighten PTY startup and replay explanations [skip ci]

* [comment audit] Clarify PTY identity and delivery ownership [skip ci]

* [comment audit] Shorten remote reconnect and input replay rationale [skip ci]

* [comment audit] Condense terminal parking clipboard and file link comments [skip ci]

* [comment audit] Clarify IME ownership and trim trace history [skip ci]

* [comment audit] Shorten pane recovery and parked watcher explanations [skip ci]

* [comment audit] Condense snapshot replay and visibility recovery rationale [skip ci]

* [comment audit] Shorten terminal parking and keyboard ownership rationale [skip ci]

* [comment audit] Trim renderer lifecycle and menu rationale [skip ci]

* [comment audit] Condense workspace cleanup ownership and settlement notes [skip ci]

* [comment audit] Clarify renderer hook evidence and source ownership [skip ci]

* [comment audit] Tighten IPC ownership and reconnect explanations [skip ci]

* [comment audit] Trim renderer focus, paste and attention comments [skip ci]

* [comment audit] Shorten scroll, locale and agent lifecycle comments [skip ci]

* [comment audit] Trim agent launch, resume and ownership commentary [skip ci]

* [comment audit] Shorten account, browser and editor comments [skip ci]

* [comment audit] Clarify host-mirror waits, previews and input ownership [skip ci]

* [comment audit] Condense launch recovery and editor tokenization comments [skip ci]

* [comment audit] Condense workspace selection and terminal pane rationale [skip ci]

* [comment audit] Condense terminal fitting and rendering recovery comments [skip ci]

* [comment audit] Condense terminal input and host routing explanations [skip ci]

* [comment audit] Condense ownership and sleeping-session recovery rationale [skip ci]

* [comment audit] Condense structured launch and terminal link explanations [skip ci]

* [comment audit] Condense terminal ownership and workspace file routing rationale [skip ci]

* [comment audit] Condense session persistence and workspace activation rationale [skip ci]

* [comment audit] Condense workspace routing and browser ownership rationale [skip ci]

* [comment audit] Condense mirror recovery and layout authority rationale [skip ci]

* [comment audit] Condense runtime transport and file safety rationale [skip ci]

* [comment audit] Condense runtime graph and structured session rationale [skip ci]

* [comment audit] Condense browser creation and remote tab recovery rationale [skip ci]

* [comment audit] Condense snapshot authority and publisher recovery rationale [skip ci]

* [comment audit] Condense frame, startup and provider cache rationale [skip ci]

* [comment audit] Condense host twin and agent lifecycle rationale [skip ci]

* [comment audit] Condense browser authority and editor cleanup rationale [skip ci]

* [comment audit] Condense editor buffer identity and review cache rationale [skip ci]

* [comment audit] Condense provider lifetime and repository ownership rationale [skip ci]

* [comment audit] Condense reconnect, hydration and terminal retirement rationale [skip ci]

* [comment audit] Condense recovery, reconciliation and persistence rationale [skip ci]

* [comment audit] Condense cleanup ownership and listing admission rationale [skip ci]

* [comment audit] Condense teardown ordering and terminal ownership rationale [skip ci]

* [comment audit] Condense recovery ledger and web host-boundary rationale [skip ci]

* [comment audit] Condense web reconnect and credential lifecycle rationale [skip ci]

* [comment audit] Condense cloud rollout and assignment safety rationale [skip ci]

* [comment audit] Condense relay session and database recovery rationale [skip ci]

* [comment audit] Condense relay placement and protocol compatibility rationale [skip ci]

* [comment audit] Condense build and packaging constraints [skip ci]

* [comment audit] Condense CI gates and validation isolation rationale [skip ci]

* [comment audit] Condense catalog identity and browser validation rationale [skip ci]

* [comment audit] Condense mobile browser and frame-budget rationale [skip ci]

* [comment audit] Shorten mobile route and browser test explanations [skip ci]

* [comment audit] Condense editor and session seam test rationale [skip ci]

* [comment audit] Trim session and terminal closure history [skip ci]

* [comment audit] Shorten terminal browser and census explanations [skip ci]

* [comment audit] Preserve root-only E2E diagnostic baseline

* [comment audit] Condense mobile seam and HTML preview test rationale [skip ci]

* [comment audit] Condense preview instrumentation and render harness rationale [skip ci]

* [comment audit] Condense bundle contracts and native-build constraints [skip ci]

* [comment audit] Shorten native packaging and CI routing rationale [skip ci]

* [comment audit] Condense release tooling and benchmark constraints [skip ci]

* [comment audit] Condense packaging and platform gate rationale [skip ci]

* [comment audit] Shorten mobile route and history rationale [skip ci]

* [comment audit] Condense mobile browser and component rationale [skip ci]

* [comment audit] Shorten drawer and workspace-form rationale [skip ci]

* [comment audit] Trim mobile review and editor-document explanations [skip ci]

* [comment audit] Condense editor lifecycle and Markdown explanations [skip ci]

* [comment audit] Trim mobile file, diagnostics and dictation commentary [skip ci]

* [comment audit] Simplify mobile host-list and workspace-view explanations [skip ci]

* [comment audit] Clarify mobile shell lifetime and bridge delivery constraints [skip ci]

* [comment audit] Condense bridge stream, native request and audio rationale [skip ci]

* [comment audit] Reduce bridge schema and page-client commentary [skip ci]

* [comment audit] Tighten mobile page bridge contracts [skip ci]

* [comment audit] Clarify mobile cache and session constraints [skip ci]

* [comment audit] Condense mobile route and lifecycle rationale [skip ci]

* [comment audit] Tighten mobile shell hook timing rationale [skip ci]

* [comment audit] Clarify route handoff and notification compatibility [skip ci]

* [comment audit] Clarify push registration and dictation cleanup constraints [skip ci]

* [comment audit] Condense keyboard geometry and native media ownership rationale [skip ci]

* [comment audit] Tighten mobile chat scroll and composer concurrency rationale [skip ci]

* [comment audit] Condense mobile reply compatibility and upload ownership rationale [skip ci]

* [comment audit] Condense optimistic echo and scroll ownership rationale [skip ci]

* [comment audit] Tighten stream replay and queued session ownership rationale [skip ci]

* [comment audit] Condense mobile composer and reply-schema constraints [skip ci]

* [comment audit] Clarify mobile transcript recovery and session ownership [skip ci]

* [comment audit] Clarify mobile queue and source-control compatibility [skip ci]

* [comment audit] Condense storage and task launch constraints [skip ci]

* [comment audit] Clarify task schemas and terminal document ownership [skip ci]

* [comment audit] Tighten terminal input and viewport rationale [skip ci]

* [comment audit] Shorten terminal and RPC recorder contracts [skip ci]

* [comment audit] Condense recorder engine and connection contracts [skip ci]

* [comment audit] Shorten host credential and relay recovery comments [skip ci]

* [comment audit] Tighten pairing recovery and bundle transport rationale [skip ci]

* [comment audit] Clarify RPC delivery and workspace catalog boundaries [skip ci]

* [comment audit] Condense catalog and relay entry contracts [skip ci]

* [comment audit] Shorten shutdown and SSH relay delivery contracts [skip ci]

* [comment audit] Condense WSL relay and E2E regression rationale [skip ci]

* [comment audit] Shorten cross-version harness and renderer fixture explanations [skip ci]

* [comment audit] Condense paired-host and E2E lifecycle rationale [skip ci]

* [comment audit] Shorten layout oracle and regression explanations [skip ci]

* [comment audit] Condense paired recovery and ownership regression contracts [skip ci]

* [comment audit] Shorten restart, sidebar and SSH lifecycle contracts [skip ci]

* [comment audit] Condense terminal rendering and IME regression rationale [skip ci]

* [comment audit] Shorten terminal recovery and benchmark contracts [skip ci]

* [comment audit] Condense tooling and Windows lifecycle proof rationale [skip ci]

* [comment audit] Condense workflow routing and release rationale [skip ci]

* [comment audit] Condense mobile security and installer contracts [skip ci]

* [comment audit] Shorten native rationale and stylesheet workarounds [skip ci]

* [comment audit] Shorten Windows visibility probe rationale [skip ci]

* [comment audit] Condense embedded release and signing rationale [skip ci]

* [comment audit] Retain current main test behavior in final reconciliation [skip ci]

* [comment audit] Complete final comment review across current source inventory

* [comment audit] Handle consolidated audit reports before final CI

* [comment audit] Preserve credential storage census detail [skip ci]

* [comment audit] Scale broad changed E2E selections with verified timing shards

* [comment audit] Align E2E assertions with browser close and settled session metadata

* [comment audit] Match existing E2Es to current resource and windowing contracts

* [comment audit] Observe the shared server outage notice in reconnect coverage

* [comment audit] Make existing renderer probes measure settled tab and PTY work

* [comment audit] Align palette E2E selector with task search

* [comment audit] Refresh remaining palette search selectors

* [comment audit] Keep selector correction within selected audit specs

* [comment audit] Await emoji fixture settings inside renderer evaluation

* [comment audit] Cancel fixture fit retries between terminal tests

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-25 04:05:46 -07:00
Neil 5447a26fd1 perf(lint): keep JS plugins out of default oxlint and adopt ast-grep (#33430)
* perf(lint): keep JS plugins out of default oxlint and adopt ast-grep

Any jsPlugin makes Oxlint hand every file's AST to Node, so the seven custom
plugins cost the default `oxlint` run several times its native time.

- Move app-store-performance, quadratic-buffer-concat, renderer-scrollbar-style
  and ime-enter-guard (scope- or dataflow-aware) to config/oxlint-js-plugins.json,
  run by `pnpm lint:js-plugins`, CI, lint-staged and the changed-lines gate.
- Port sort-comparator-performance, mobile-pairing and native-chat-design-tokens
  to ast-grep rules with rule tests, and delete the plugins.
- Add @ast-grep/cli, config/sgconfig.yml, `pnpm lint:ast-grep` / `test:ast-grep`,
  a CI step, and an ast-grep pass in check-changed-code-quality.
- Add flaky-test rules (wall-clock reads, real-time waits, polling loops,
  unquarantined skips, unexplained timeout bumps), baselined by a count ratchet.

* Enforce flaky-test ratchet on changed files; refresh baseline

* docs(agents): keep custom-rule details out of AGENTS.md

* Resolve ast-grep from the repo so gate scans of other roots work
2026-10-25 00:23:38 -07:00
Neil 24069f0a97 ci: fail when a checked-in test file has no runner (#33080)
* ci: fail when a checked-in test file has no runner

Two node:test files under .github/actions lost their runner when #31792
trimmed cloud pretest, and the two monaco .bench.ts budgets were never run
by any CI job. Wire both back in and add a static check that every
test-like file is collected by a declared runner or imported by a
collected entry (the src .spec.* suite-module convention).

* ci: ignore type-only imports and quote the lease glob for cmd.exe

* ci: parse type-only imports, cover UNIT_EXCLUDE, route cloud runner edits

Type-only imports are now dropped with the TypeScript parser, so a type
alias before a runtime re-export no longer hides it. UNIT_EXCLUDE files
must be named by a pr.yml or unit-tests.yml step. A cloud-only diff that
adds a test or edits a runner config now runs the static job. The monaco
benchmarks stay manual (pnpm test:perf:benchmarks) until a CI runner
proves their wall-clock budgets.

* ci: require UNIT_INCLUDE names in dedicated jobs and erase typeof import()

* ci: resolve each runtime import to the one file Vite loads

The unit dependency graph keeps every plausible candidate so it can
invalidate conservatively, which cannot prove a suite runs: an import of
./case.spec counted both case.spec.ts and case.spec.tsx. Resolve with
Vite's extension order instead.

* ci: take runtime imports from transpiled output

Imports used only as types are erased without a type modifier, so
parsing for type-only syntax still followed them. Derive edges from
ts.transpileModule output, which erases what Vitest's transform erases,
and only transpile files that can reach an uncollected candidate.

* ci: fix the agent-status benchmark config and route all cloud code

The agent-status benchmark config inherited the unit projects, whose
includes override its own, so it ran the whole unit suite and never the
benchmark. Clear projects as the performance config does. Route every
cloud code file to the static job, since content-detected tests can have
any name.
2026-10-24 00:57:17 -07:00
Neil e38cf787e8 ci(windows): route real installer probes by changed inputs (#32993)
* ci(windows): route real installer probes by changed inputs

* ci(windows): remove nonexistent process-host routing prefix
2026-10-23 18:04:13 -07:00
OrcaWinandOrcaWin 61ad1ba166 ci: move routine checks and unsigned builds to Blacksmith (#32913)
* ci: move routine checks and unsigned builds to Blacksmith

* ci: retain GitHub Mac images for isolated SSH fixtures

* ci: keep shared terminal perf preparation on Blacksmith

* test: allow encrypted slow-link fixture to finish on ARM CI

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-23 13:29:01 -07:00
Neil 4ed7fb08af ci: run full unit shards on eight-core workers (#32567) 2026-10-23 07:13:51 -07:00
Neil 315b7c1546 ci: move Linux package and relay jobs to the Blacksmith pool (#32442)
* ci: run relay integration on the Blacksmith x86 pool

* ci: use the validated Blacksmith pool for Linux packaging

* test: allow shared Linux download caches across validated runner pools
2026-10-23 06:30:37 -07:00
Neil 758b9c2b71 ci: avoid slow Ubuntu mirrors during WebKit setup (#32205)
* ci: reuse bounded Ubuntu mirror setup for WebKit

* ci: preserve Ubuntu setup for dispatched older refs
2026-10-23 00:32:31 -07:00
Neil 8b5c732e6e ci: skip relay integration for renderer-only PRs (#31842) 2026-10-21 22:31:54 -07:00
Neil 0a7d6bb2d5 refactor(main): group ephemeral VM lifecycle modules (#31771) 2026-10-21 21:31:21 -07:00
Neil 307f0cdaee Move Relay deployment configuration into private cloud operations (#31792)
* refactor(cloud): move deployment configuration into private operations repo

* docs(cloud): clarify private operator ownership

* fix(ci): install pnpm through npm-compatible bootstrap

* fix(ci): avoid native downloader metadata timeout

* test(push): move deployment preflight contract into private repo

* fix(ci): bootstrap Node before installing pnpm in minimal containers

* fix(ci): pass Windows boundary test paths through the Node runner

* fix(ci): run Windows boundary Vitest with installed Node
2026-10-21 21:01:25 -07:00
Neil 8ba1c9ba09 fix(ci): restore cloud and main checks during pnpm registry outages (#31793)
* fix(ci): recover verified pnpm setup from registry metadata outages

* fix(ci): prepare native pnpm shims after fallback verification

* fix(ci): provide Node for pnpm fallback in bare containers
2026-10-21 20:25:36 -07:00
Neil 95d9682b0c fix(ci): prepare historical VM rollback snapshots (#31775) 2026-10-21 19:40:42 -07:00
Neil eb9d2f9a06 fix(security): update Node runtimes for October security releases (#31687)
* fix(security): update Node runtimes for October security releases

* fix(ci): compare normalized web file inventory without ordering artifacts
2026-10-21 17:06:28 -07:00
Brennan Benson afcb385c86 ci: install verified fish 4 directly for shell contracts (#31581)
* ci: install fish 4 from its GitHub release when the Launchpad PPA is down

* TEMP: skip the fish PPA to prove the GitHub release fallback (revert)

* Revert "TEMP: skip the fish PPA to prove the GitHub release fallback (revert)"

This reverts commit 58ba0c5074.

* ci: install pinned fish directly from its verified release

* ci: isolate standalone fish from runner resources
2026-10-21 14:05:32 -07:00
Brennan Benson 2187f0b6b2 ci: one list for Windows boundary tests and one step for ratchets (#30643)
* ci: one list for Windows boundary tests and one step for ratchets

The Windows boundary step's 74 test paths were hand-listed in pr.yml and
again in WINDOWS_PACKAGE_TESTS, and the copies had drifted: six files ran
in the step but could not trigger the job. The step now prints
WINDOWS_BOUNDARY_TESTS, which WINDOWS_PACKAGE_TESTS spreads.

The ten per-ratchet preflight steps and the eight lint entries become one
run-ratchets.mjs that runs every check-*-ratchet(s).mjs it finds.

* fix(ci): preserve existing local lint ratchet scope
2026-10-20 22:13:36 -07:00
Neil a308277f9a fix(deps): root and mobile resolve one zod, and CI fails if they drift (#31260)
* fix(deps): root and mobile resolve one zod, and CI fails if they drift

Mobile type-checks src/shared zod schemas. With mobile on zod 4.6.5 and the
root on 4.6.7, TypeScript treated them as unrelated packages, so wrapped
schemas inferred {} (tests/e2e/helpers/phone-feed-list.ts:154) whenever a
job installed mobile deps.

* fix(deps): guard every package mobile's tsconfig remaps, not only zod

* test(ci): pin the shared-dependency version check to the static phase
2026-10-20 19:12:29 -07:00
NeilandClaude d6bc6cb3b3 fix(process-host): let a slow Windows taskkill finish instead of orphaning the grandchild (#29501)
* fix(process-host): let a slow Windows taskkill finish instead of orphaning the grandchild

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

* fix(process-host): abandon taskkill shortly after the root exits so it cannot walk a reissued pid

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

* test(process-host): log the taskkill outcome and caller settle time under load

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

* ci: register the late-taskkill Windows test in the package-windows path list

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

* fix(process-host): release the git admission slot on root close again; cap the background taskkill at 30 s

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-20 17:30:38 -07:00
Neil 32343cc703 test(skills): synchronize Windows rename contention (#31237) 2026-10-20 15:15:59 -07:00
Neil 12bf32836b feat(ci): ratchet raw repo connectionId host checks; migrate the cheap ones (#31096)
* feat(ci): ratchet raw repo connectionId host reads; one drop-in resolver

Codex review 6 class fix (#4/#6/#7): host decisions read off a repo row's
legacy connectionId miss rows that name SSH only as executionHostId.

- getRepoRoutingConnectionId (shared/execution-host.ts): drop-in for a raw
  repo.connectionId routing check that also finds executionHostId-only SSH.
- check-repo-host-read-ratchet: per-file count of raw repo connectionId
  reads in src/main, src/shared, src/cli; counts may only shrink.
- Migrated 66 cheap reads: runtime GitHub/GitLab commands, PR/MR head ref
  fetches, preserved-branch cleanup, ref queries, base-ref IPC, worktree
  preparation, trash sweep, scan cache TTL, usage metadata.

* fix(ipc): PR base IPC routes executionHostId-only SSH rows; ratchet is a stated lower bound

Review follow-up (Opus on #31096):
- worktrees:resolvePrBase decided git/gh routing on the raw connectionId while
  its head-ref fetches already used the resolver; one resolved connectionId
  now drives all of it (test fails on main).
- getRepoRoutingConnectionId's contract is stated exactly: never local when the
  raw field is set; on a contradictory ssh row executionHostId wins.
- The ratchet regex no longer matches report.connectionId; header and docs
  say it is a lower bound.
- Regression tests for a runtime GitHub and GitLab command site.

* test(ci): pin the repo host-read ratchet step to the static phase

* fix(ci): repo host-read ratchet skips verbatim field copies into projected rows

A copy of connectionId into a projected row decides nothing; migrating it to
the resolver would change what the projection publishes. The sidebar feed
catalog's copy (added after the baseline) and two older projections no longer
count; baseline pruned to 91.
2026-10-20 14:00:32 -07:00
Neil 28d9f959de Run selected SSH tests instead of the whole suite on PRs (#30928)
* fix(ci): run only selected managed SSH specs on pull requests

* fix(ci): retain full SSH coverage for routed shared helpers
2026-10-19 18:21:53 -07:00
Neil cbb9f369b8 Stop running the experimental layout suite on every matching PR (#30907) 2026-10-19 16:16:50 -07:00
Jinjing f14475caa6 fix(browser): label popups from committed document origins (#30540)
* fix(browser): label popup chrome from committed documents

* fix(browser): keep opaque popup documents neutral

* test(browser): prepare real popup identity validation

* test(browser): apply background policy in popup probes

* test(browser): fix popup title and view-lifetime checks

* fix(browser): ignore subframe failures in popup chrome

* rm draft docs

* fix(browser): finish popup probe teardown after signal exit

* test(browser): use typed popup probe window access

* fix(browser): prevent automatic popup title updates

* commit

* fix test
2026-10-19 16:13:54 -07:00
Neil 92eb9790bc ci: fail the static job on unformatted files (#30863)
* ci: fail the static job on unformatted files

Runs oxfmt --check over the same tree pnpm format writes (~2s), and makes the
pre-commit hook format markdown and YAML so it covers what CI now checks.

* ci: route docs-only and workflow-only diffs through the formatting check

The format check reads the whole tree, so a diff that skipped the static job
could land drift that fails every later PR. Any changed file oxfmt formats now
selects static analysis (not typecheck or units), like the mobile-only route.
The path detector checks out .oxfmtrc.json for its ignores. The hook no longer
fails a commit whose only matches oxfmt ignores (lockfiles).
2026-10-19 16:08:52 -07:00
e9fa0cf95c fix: a tab close by the handle a split returned finds the new pane (dark, layout-owner build only) (#30786)
* fix(renderer): list a pane main holds before the window mounts it, so a tab close by a split's handle finds it (dark, layout-owner build only)

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

* test(e2e): the split-close spec polls through the host's "can't answer yet" terminal list

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

* fix(runtime): a pane the window lists before main binds its terminal keeps main's terminal (dark, layout-owner build only)

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

* fix(runtime): a tab close by a main-side split's handle stands on main's own record of the pane (dark, layout-owner build only)

Replaces the window-side listing and the binding fill: the window's list lags main in three
ways (built before main wrote the pane, from it before the binding, or before the window mounts
it), and only main's own layout answers all three.

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

* fix(runtime): main's relisting for a close tells no clients (dark, layout-owner build only)

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

---------

Co-authored-by: E2E Test <e2e@test.local>
Co-authored-by: Claude <noreply@anthropic.com>
2026-10-19 15:41:18 -04:00
Jinwoo HongandE2E Test 40e7bd1db9 A pane main first sees when its terminal starts goes where the window split it (dark, layout-owner build only) (#30772)
* fix(terminal): a pane main first sees at its binding goes where the window split it (dark, layout-owner build only)

* fix(terminal): keep main's divider positions when taking the window's split tree

* test(terminal): main's divider above the window's new split is kept

* ci: the layout-owner switch-on job runs the hidden-terminal load spec that caught the split graft

* test(terminal): type the side-by-side fixture as a split so ratio spreads typecheck

---------

Co-authored-by: E2E Test <e2e@test.local>
2026-10-19 14:52:07 -04:00
Neil 30f5bef947 fix(ci): background steps are single run steps, so no action reads the event payload while the runner rewrites it (#30795)
* fix(ci): background steps are single run steps, so no JavaScript action reads the event payload while the runner rewrites it

* test(ci): guard the background slot cap and pin the payload-free allowlist
2026-10-19 10:28:19 -07:00
Neil baf123eda8 fix(persistence): repo-row store writes take the row, not the id; ratchet the rest (R4-2a) (#30756)
* fix(persistence): repo-row store writes take the row, not the id; ratchet the rest (R4-2a)

* fix(persistence): host-filter the runtime nested import; widen the id-only write ratchet (review)

* fix(runtime): nested import keeps matching runtime-stamped native rows on a paired host

* fix(persistence): class-scope the ratchet param exemptions; update a new main test to the target shape

* fix(ipc): fence a project-group move by the resolved twin host, so an SSH twin is not WSL-fenced

* test(ci): pin the id-only store write ratchet step to the static phase
2026-10-19 10:14:07 -07:00