Commit Graph
14896 Commits
Author SHA1 Message Date
Neil e6eaabb587 test(files): the native-ignore watcher test waits on delivered events, not a fixed sleep (#30236)
It flaked on loaded CI shards when a single write never reached the watcher. Files are now rewritten until seen, readiness is proven before the storm, and a sentinel written after the storm replaces the 300 ms debounce sleep. Disabling the ignores still fails it.
2026-10-18 00:10:44 -07:00
Neil 262a61703a ci(e2e): start the managed-SSH lane for every helper only its specs import (#30233)
* ci(e2e): route every helper only managed-SSH specs import to their lane, by import graph

* ci(e2e): normalize import-closure paths to / on Windows
2026-10-18 00:06:24 -07:00
Neil d3d6162f5c test(orcad): orca serve's argv makes orcad serve the web client and 404 other paths (#30120) (#30222) 2026-10-18 00:05:29 -07:00
NeilandClaude Opus 5.5 5c66b2ef63 fix(ssh): a late relay-era attach releases only its own viewer, never a successor's (#30219)
The legacy relay bridge counted viewers per PTY id and released them by PTY id. A pane whose
attach answered after it left (or after a reconnect replaced the bridge) handed its viewer back
by PTY id, so the release landed on the current bridge and dropped a successor pane's viewer:
that pane stopped receiving output. Each attach now returns an acquisition id (in-app IPC only;
the relay wire is unchanged) and detach releases exactly that acquisition.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 00:03:25 -07:00
Neil 7ede32ec12 ci: fail when CI config, workflows or e2e code name a src/ file that no longer exists (#30224)
* ci: ratchet src/ path literals in CI config, workflows and e2e code that name no file

* ci(path-literal): resolve relative imports exactly

* ci(path-literal): resolve against tracked files only; read ./src imports

* ci(path-literal): scan src/packages and src/types references too

* ci(path-literal): skip paths quoted in comments

* ci(path-literal): keep a recursive glob's boundary

* ci(path-literal): strip comments with a string-aware scan; any import occurrence is exact

* ci(path-literal): imports need a module or index; relative globs and folders stay prefixes
2026-10-18 00:02:58 -07:00
Neil f47337d852 refactor(worktree): one worktree path equality; the ipc copy folded WSL ext4 tails (#30227)
src/main/ipc/worktree-path-comparison.ts kept its own areWorktreePathsEqual and
dedupeWorktreesByPath. Its Windows branch lowercased a WSL UNC path's ext4 tail, so two
case-twin WSL checkouts merged into one row in removal safety, folder-upgrade dedupe and
the SSH listing fallback. Every caller now uses git/worktree-path-comparison, which gains
the macOS /private/tmp fold the ipc copy had. worktreePathComparisonKey keeps its exact
bytes (retirement namespace keys persist it) in worktree-path-comparison-key.ts, and the
worktree-logic re-export goes.
2026-10-18 00:02:29 -07:00
Neil b21cda129f fix(ssh): say when a managed server may be behind this app, and retry a failed update once per launch (#30218) 2026-10-18 00:02:07 -07:00
Neil 9085c5bb87 build(packaging): fail when orca serve's serve-selection entry or a chunk it requires is left in app.asar (#27404) (#30228) 2026-10-18 00:01:46 -07:00
Neil f0a69625ae docs(agent-hooks): ORCA_FEATURE_REMOTE_AGENT_HOOKS now only gates the WSL hook relay (#30223) 2026-10-17 23:51:51 -07:00
Neil 6afbe49c17 chore: delete unimported SSH, renderer and orchestration modules (#30214)
Removes modules with no importers on main (and their tests), the unused
RELAY_DEPLOY_TEARDOWN_TIMEOUT_MS constant, and the ssh-connection-utils
re-export of ssh-auth-resolution that only its own test used.
2026-10-17 23:47:51 -07:00
Neil 993fd20223 test(preflight): freeze the clock in the explicit-binary timeout test (#30221)
The budget is deadline - Date.now(), so a millisecond tick between the two reads made it 4999.
2026-10-17 23:45:27 -07:00
Neil 932dc1be29 chore(runtime): delete the never-served TLS branch of the LAN WebSocket server (#30220)
No released build ever passed a certificate to WebSocketTransport or set the pairing TLS
fingerprint; only ws-transport's own tests used tls-certificate.ts. The tests now run over ws://.
2026-10-17 23:44:42 -07:00
Neil 9810a5cc92 refactor(worktree): one comparison-only worktreeIdentityKey replaces three key wrappers (#30217)
worktreeIdComparisonKey (nullable '::' key), runtimeWorktreeIdentityKey ('\0' key) and
runtimeWorktreeLookupKey (JSON tuple) all folded the same path spelling. They become one total
key in shared/worktree/id.ts; a malformed id keys as itself. Also fixes id.test.ts literals that
were missing a colon, which made the WSL/UNC parity assertions compare null to null.
2026-10-17 23:43:55 -07:00
Neil 9a86d271dc chore(updater): delete the rollout-flag module nothing reads (#30211)
The nudge request parsed and stored a rollout block, but no build ever read a flag from it.
Drops the module, its call site, its tests, and the e2e env that fed it.
2026-10-17 23:38:45 -07:00
Jinwoo Hong 2a8b4c31a5 Phone and old-client tab lists keep editor tabs under owned ids (dark, layout-owner build only) (#30216)
With the layout-owner switch on, the session-tabs projection and the windowless host's editor
projection matched an editor tab to its file by path only, so tabs under an owned id got no row
(or lost their tab id, color and pin). Both now use the shared editorTabShowsFile matcher, which
is path equality with the switch off.
2026-10-17 23:35:10 -07:00
Jinwoo Hong d4b3a65d52 fix(layout): main routes folders by the window's host rule and never stops layout frames (dark, layout-owner build only) (#30201)
* fix(layout): a folder spanning local and SSH repos routes to local and never stops layout frames (dark, layout-owner build only)

In a layout-owner build, main's router threw folder_workspace_connection_ambiguous for a
folder workspace whose project group mixes local and SSH repos. layout.apply for it was
rejected, and the same throw inside the layout stream failed the whole projection, so no
workspace got frames.

- Router (layout-owner build): a folder routes by its stamp, then its group's stamp (the
  window's save rule), else the shared resolveFolderWorkspaceHost; ambiguous maps to local,
  where the window already saves it. Terminal starts still refuse the ambiguity.
- Stream (layout-owner build): a workspace the router throws on is left out and logged once;
  every other workspace keeps its frames.

Window-owned builds are unchanged: the switch folds both branches away.

* refactor(folder-workspaces): move the window's folder host rule to shared (move only)

getFolderWorkspaceHostId moves unchanged from the renderer's folder catalog to src/shared/folder-workspace-execution-host.ts so main can route by the same rule. Its one renderer dependency, getProjectGroupHostId, is a direct alias of getRepoExecutionHostId, which the shared copy calls instead.

* fix(layout): main routes folders by the window's host rule and keeps a workspace's frame when routing fails (dark, layout-owner build only)

- Router: a layout-owner build routes a folder with the window's own rule (its stamp, its SSH
  target, then its group's host), shared since the previous commit. It reads no repos, so it
  cannot throw, and an SSH group holding a local repo now routes to SSH, where the window saves it.
- Stream: a workspace whose routing throws keeps its last published layout instead of being sent
  as removed, which would make the window drop its tabs.
- Stream: routing failures have their own logged-once flag, so they never hide a later
  projection or listener failure.
- One table of folder kinds is checked against both main's router and the window's save.
2026-10-17 23:32:41 -07:00
Jinwoo Hong 25fb579c12 fix(layout): refuse a layout change on a workspace a WSL move has paused (dark, layout-owner build only) (#30198)
* fix(layout): refuse a layout change on a workspace a WSL move has paused, and say why (dark, layout-owner build only)

* fix(layout): refuse without a toast; keep the move message in main
2026-10-17 23:26:38 -07:00
Neil 8209d301d8 test(runtime): record Electron vs orcad composition wiring and fail on undeclared differences (#30212) 2026-10-17 23:25:41 -07:00
Neil d4aa9dcadc revert: restore pinned npx skills installer (#30207)
Reverts #30185 so the separate installer project can proceed. The restored shared command already pins skills@1.7.2 for CLI, desktop updates, and setup commands.
2026-10-17 23:24:02 -07:00
Neil 1e29bd1907 ci(e2e): route remote product sources without a hand-kept route to the managed-SSH lane (#30210) 2026-10-17 23:15:50 -07:00
Neil 553bde347a ci: simplify CocoaPods pin validation (#30208) 2026-10-17 23:09:25 -07:00
Jinwoo Hong 95d6018323 Main keeps editor tabs under owned ids and in-place re-owns in step (dark, layout-owner build only) (#30206)
A restored tab re-owned inside its own workspace now tells main through
renameEditorFiles with the file's new record; main skips it for paired servers.
Main's load, save, close and tab-host read an editor tab's file by its owned id
as well as its path, behind the layout-owner switch.
2026-10-17 23:04:15 -07:00
Jinwoo Hong 31f766515d Main records when a workspace's default tabs were applied (dark, layout-owner build only) (#30176)
* feat(layout): main records a workspace's default-tabs mark from the window (dark, layout-owner build only)

* fix(layout): record the default-tabs mark after the tab creates it covers (dark, layout-owner build only)

* test(e2e): strict default-tabs mark and exact tab count across a crash (dark, layout-owner build only)
2026-10-17 23:02:05 -07:00
Jinwoo Hong b8fbfce3a6 Main repairs a terminal stored in two panes once at startup (dark, layout-owner build only) (#30178)
* fix(layout-owner): main repairs a terminal stored in two panes once at startup, after moving the dropped pane's owners (dark, layout-owner build only)

* fix(layout-owner): the load repair moves the dropped pane's records and skips the write when an owner move fails (dark, layout-owner build only)

* fix(layout-owner): the load repair leaves a paused WSL move's workspace untouched (dark, layout-owner build only)
2026-10-17 23:02:00 -07:00
Jinwoo Hong 483a17becc Reopening a file in its open tab sends the main process the changed file record (dark, layout-owner build only) (#30197)
* fix(layout): a reopen that rewrites an open tab's file record reaches main (dark, layout-owner build only)

* fix(layout): compare reopened editor records without a new renderer import
2026-10-17 22:58:06 -07:00
Neil 4baacca5c0 fix(startup): shell PATH probe falls back and retries when the shell cannot launch (#30204)
* fix(startup): shell PATH probe falls back and retries when the shell cannot launch

* chore: drop hydrate-shell-path from the process-host direct-import baseline
2026-10-17 22:54:54 -07:00
Neil ffb818bf61 Ship the locked skills installer instead of executing npx (#30185)
* security: ship a locked skills installer instead of running npx

* chore: remove retired skills process import exception

* test: include the locked installer in packaged layout fixtures

* test: reuse the real installer builder for package fixtures
2026-10-17 22:51:14 -07:00
Neil dcfe8c9e6c perf(typecheck): pin Bun as a devDependency and typecheck with it (#30149)
* perf(typecheck): pnpm tc uses the pinned Bun checker when available

bun check (Bun 1.4.3, TypeScript 7.0.2 parity, already used by CI) checks the
node project in ~29 CPU-s / ~2 GB peak vs tsc's ~98 CPU-s / ~16.6 GB. tsc's
incremental cache rarely helps agents: noEmit builds store no declaration
signatures, so the first edit to any file after a cold check re-checks every
transitive importer (a comment in src/shared/constants.ts re-checks all 18k files).

pnpm tc / tc:node / tc:web / tc:cli now pick the Bun from config/.bun-version when
it is on PATH and fall back to tsc with a one-line hint otherwise;
--compiler=native forces tsc. The pinned-Bun probe is shared with the
localization extraction check.

* build: pin Bun as a devDependency and make it the only default checker

The PATH probe left anyone without the exact pinned Bun (including a 1.4.2
global) on tsc's expensive path. bun@1.4.3 is now a devDependency, its
postinstall is allowed, and pnpm tc / typecheck:ci run that binary. A missing
binary is an error pointing at pnpm install rather than a silent fallback;
--compiler=native still selects tsc. A test keeps the devDependency equal to
config/.bun-version.

* ci: link the pinned Bun after the script-free install

--ignore-scripts leaves node_modules/.bin/bun as bun's postinstall stub, so the
typecheck runner found no binary and any pnpm-run script calling bun would hit
the stub before setup-bun's copy. pnpm rebuild bun runs only that allowed build.
2026-10-17 22:43:00 -07:00
Neil dbb84f4ad9 fix(ssh): move parked terminal history through the snapshot channel so a big saved buffer no longer blocks a host's move (#30126) (#30188) 2026-10-17 22:41:41 -07:00
Neil 1e95c037e0 fix(native-chat): say why the chat composer is locked and offer Take back when a phone holds the input (#30199) 2026-10-17 22:41:09 -07:00
Neil d93568368e fix(ssh): move the open workspace to the server's linked project when joining an existing server (#30189)
* fix(ssh): move the open workspace to the server's linked project when joining an existing server

* fix(ssh): follow the active repo and detected checkouts when rehoming a linked workspace

* fix(ssh): treat a missing server row as unknown, and keep watching for it
2026-10-17 22:40:20 -07:00
Neil b5fa888a93 fix(worktrees): stop CLI-created worktrees flashing into a filtered sidebar (#30194)
* fix(worktrees): keep a CLI-created worktree out of listings until its metadata is saved

A watcher-driven listing during `git worktree add` surfaced the new checkout as a bare
external row. The host's default-terminal request then made that stale row active, so it
slipped past Hide sleeping and Hide CLI-created until the next refresh hid it (~1s flash).

* fix(worktrees): hold canonical checkout paths during creation
2026-10-17 22:38:23 -07:00
Neil c359d09f22 chore(deps): remove unused desktop and mobile declarations (#30182)
* chore(deps): remove unused desktop and mobile declarations

* fix(deps): retain parser used by historical-release tests
2026-10-17 22:34:51 -07:00
Neil bbdbe72eba fix(runtime): paired clients list a folder-upgraded checkout under the host's id (#30190)
worktree.detectedList built its rows from the raw Git scan, so a folder project upgraded to Git
was published under Git's spelling (C:/x) while the host keyed its metadata and terminals by the
folder's (C:\x). Apply preserveFolderUpgradeWorktreePath at the runtime listing scan every
runtime listing reads.

Fixes #30150
2026-10-17 22:24:42 -07:00
Neil fa738f30bb fix(notebook): run cells only when the resolved owner is this computer (#30187)
A managed SSH or paired-server workspace has no SSH connection id, so the
notebook read it as local and ran its cells in the desktop's own Python
against a same-named local file. Derive the execution host from resolveOwner;
refuse remote, ambiguous and unloaded owners.
2026-10-17 22:19:55 -07:00
Jinwoo Hong b8264e860b Main drops the layout of workspaces the catalog no longer validates (dark, layout-owner build only) (#30177)
* feat(layout): main drops the layout of workspaces the catalog no longer validates (dark, layout-owner build only)

* rename the paired-host check so the switch-off bundle keeps its names

* a repo id two hosts register skips the listing purge
2026-10-17 22:19:35 -07:00
Jinwoo Hong e0abf71a62 refactor(layout-owner): one placement helper for drawn tab opens (dark, layout-owner build only) (#30174)
The chat, simulator, and browser tab recorders each computed where the window
drew a just-opened tab with the same lines. They now share drawnTabPlacement.
2026-10-17 22:19:16 -07:00
Neil 904259d122 fix(runtime): keep a restored unfinished agent unverifiable for the hydration window, not 30 minutes (#30186) 2026-10-17 22:14:38 -07:00
Neil a42049f297 fix(tooling): lock routine dependency audit executables (#30183) 2026-10-17 22:12:03 -07:00
Jinwoo Hong aff4ee7ac7 feat(sidebar): main produces this host's workspace rows, checked against the window (dark) (#30184)
* feat(sidebar): main produces the local workspace rows, checked against the window (dark)

* fix(sidebar): workspace rows invalidate the listing only on metadata saves; prove it on the real cache

* fix(sidebar): workspace rows merge the listing fresh instead of invalidating the shared cache

* chore(sidebar): workspace rows comments say what the fresh merge reads
2026-10-17 22:10:09 -07:00
Jinwoo Hong b9b1b85261 test(layout-owner): an older session's moved editor tab gets its workspace's id on save and from the first frame (#30172)
Sessions saved before #29930 can hold a moved editor tab whose
worktree id still names the workspace it came from. Pin that the
saver writes the workspace's own id and that the window's tab carries
it after main's first snapshot. Tests only.
2026-10-17 22:09:10 -07:00
Neil ed40719964 Pin CocoaPods release installer in the Ruby lockfile (#30181) 2026-10-17 22:00:57 -07:00
Max HsuandNeil c2188f66e4 fix(tasks): bound GitLab all-projects fan-out to avoid runtime queue overflow (#30157)
* fix(tasks): bound GitLab all-projects fan-out to avoid runtime queue overflow

The GitLab Tasks list started one listIssues/listMRs runtime RPC per selected repo at once. With 150+ projects this, combined with other callers on the same selector, overflowed the runtime RPC call queue and surfaced "Remote runtime call queue is full".

Fetch per-repo lists through mapSettledWithConcurrency with a limit of 6 (below the queue's foreground concurrency of 8), and stop starting new calls once the selection goes stale.

Fixes #30133

* test(tasks): assert merged GitLab rows without a type assertion

---------

Co-authored-by: Neil <neil@stably.ai>
2026-10-17 22:00:40 -07:00
Neil 68808db38a chore(docs): replace ESLint with Oxlint (#30180) 2026-10-17 21:51:31 -07:00
Neil 6c45958c8c refactor(renderer): tighten the host-identity stack (#30124) 2026-10-17 21:34:47 -07:00
Jinwoo Hong 303c7c91ef fix(sidebar): main's temporal owner reads the catalog the way the window does (dark) (#30166)
* fix(sidebar): main takes its row baseline from the session's catalog and skips unchanged listings

* fix(sidebar): read catalog listings the way the window's merge does

* fix(sidebar): a seeding listing re-samples, and listings compare with the window's equality
2026-10-17 21:32:33 -07:00
Neil af056df751 refactor(projects): shrink twin-removal teardown to the attributed close actions (#30060) 2026-10-17 21:12:19 -07:00
Neil 98b4139e0b fix(sidebar): confirm before sleeping a workspace that another host's copy shares (#30047) 2026-10-17 21:00:08 -07:00
Jinwoo Hong bf97836ae0 Pane titles stay layout: the window stops writing tab names as pane titles, and main loads them as the window does (dark, layout-owner build only) (#30136)
* refactor(shared): move the pane title sanitizer to shared, unchanged

So main's layout Loader can apply the same rule the window applies on load.

* fix(layout): pane titles stay layout in a layout-owner build (dark)

The window stops writing a revealed terminal's tab name as its pane title,
and main's Loader drops a lone pane title that only repeats the tab's name,
as the window's load does. Both behind ORCA_LAYOUT_OWNER_IS_MAIN.

* fix(layout): the Loader compares a lone pane title with the tab bar's quick command label too (dark)

As the window's row hydration does when the row has no label.

* fix(layout): the Loader compares a lone pane title with the tab bar label, the live title (dark)
2026-10-17 20:59:57 -07:00
Jinwoo Hong bb0f229aa5 test(e2e): wait for git status to show the seeded file before the discard confirmation test acts (#30165) 2026-10-17 20:59:19 -07:00