Skip to content

Sync upstream main 2026-10-19 (15 commits) [skip ci] - #36

Merged
karlorz merged 16 commits into
fork-mainfrom
sync/upstream-2026-10-19
Oct 19, 2026
Merged

karlorz merged 16 commits into
fork-mainfrom
sync/upstream-2026-10-19

Conversation

@karlorz

@karlorz karlorz commented Oct 18, 2026

Copy link
Copy Markdown
Owner

Orca upstream sync 2026-10-19: RESULT (prepared, NOT pushed)

Written ~02:45 SGT 2026-10-19 by grok-bot-1.

  • Worktree: /workspace/code/orca-worktrees/sync-upstream-2026-10-19 (main checkout untouched: still on sync/upstream-2026-10-13a, clean)
  • Branch: sync/upstream-2026-10-19 (local only)
  • Tip: 87ad453. Merge commit, parents fork-main 9cf9711 (includes the versionCode-100 bump / mobile-android-v0.0.57-4) + upstream/main b6325ef
  • Merge-base: d7aea6d. Upstream commits merged: 15 (fork was 768 ahead / 15 behind at merge time)
  • NOT done: push, PR, merge, tags, fork-main writes, CI. Karl never gave GO for the push; android-apk's room note says "Muse review + Karl GO, then push".
  • Upstream moved after the merge: e43f3e7 (feat(opencode): open OpenCode 2 in the chat view and list 2.x models before the first message stablyai/orca#28424 OpenCode 2 chat view) is 1 commit newer and is NOT included. Either take it in the next sync, or re-merge before pushing (that would need another quick test pass).

Upstream commits included

stablyai#30355 stablyai#30362 stablyai#30369 stablyai#30370 stablyai#30373 stablyai#30375 (ssh/ipc module-move refactors), stablyai#30380, stablyai#30257, stablyai#29140, stablyai#30387, stablyai#30384, stablyai#30388, stablyai#30284 (mobile sidebar stamp sort), stablyai#29070 (mobile landscape session tabs), stablyai#30137 (fmt)

Conflict resolutions (all were import-path conflicts; fork logic is byte-identical to fork-main)

  1. src/main/ipc/runtime-environments/runtime-environment-managed-tunnel.ts: used upstream's new ../../../ paths. Kept the fork's restore-hold imports (isManagedOrcadRestoreMutationHeld, managedServerUpdateDeps → ../../ssh/...) and the fork's restore-hold-gated block. Pointed that block's lazy import() at ../ssh/ssh-host-launch-session-note.
  2. …/runtime-environment-managed-tunnel.test.ts: upstream path, plus the fork's MANAGED_ORCAD_RESTORE_HOLD_ENV import (../../ssh/managed-orcad-restore-hold).
  3. …/runtime-environment-unreachable-hint.ts: upstream ../../../shared paths, plus the fork's classifyRemotePairingHostname import.
  4. …/runtime-environment-unreachable-hint.test.ts: the fork's SSH_TUNNEL_UNREACHABLE_HINT import, plus the upstream path.
  5. src/main/startup/main-process-runtime-launch.ts: kept the fork's registerDesktopMobilePairingOffers import, plus upstream's new runtime-environments/runtime-environment-mobile-relay-hosts path.

Checked: diffing each file against its fork-main version shows only import/vi.mock specifier changes. Every relative import, vi.mock and import() specifier in src/ and mobile/ resolves; there are no new unresolved specifiers compared with either parent.

Protocol / runtime launcher

check-runtime-launcher-protocol-ratchet.mjs --base origin/fork-main: daemon PROTOCOL_VERSION 49→49, result OK. The only launcher file touched is orcad-remote-node-runtime.ts, and only its import path changed (ssh/remote-exec/remote-exec-command). Daemon protocol and launcher behavior are unchanged. The protocol-bump label is not needed.

Tests (local, heavy-run, Node 22.19; pnpm install --ignore-scripts + process-host build)

  • Desktop vitest (src/main/ipc/runtime-environments/, startup launch-activation/ready- tests, runtime-composition-parity, mobile-pairing-offer, managed-orcad-restore-hold, ssh-host-launch-session-note): 52 files, 259 passed / 10 failed / 1 skipped.
    • All 10 failures also happen on unmodified fork-main 9cf9711, so they were there before the merge: main-process-runtime-launch-activation ×5 (rpcServer.setMobilePairingOffers is not a function, fork test mock gap), runtime-environment-transport-routing-tailscale-hint ×3 and runtime-environments-status-diagnostics ×2 (the fork's SSH-tunnel hint replaces the expected Tailscale text).
  • Conflicted test files re-run at the final tip: 2 files, 21/21 passed.
  • Mobile vitest (src/layout, src/session, src/worktree/workspace-list*): 281 files, 2629/2629 passed.
  • Typecheck: NOT verified. A full tsc (TS 7 native) went past 5.7 GB RSS and was killed (newbie also killed one run); the parent then forbade full tsc. A file-scoped tsc is not cheap here because the changed files pull in most of the main-process graph. The specifier-resolution scan and vitest module loading stand in for it. Mobile tsc was not run either.

Review

Muse (thread 411d43f8, ask/reply in ops/orca-dispatch/muse/orca-sync-upstream-2026-10-19-{ask,reply}.md): APPROVE. Muse confirmed the resolutions are correct and that no label is needed. On risk, Muse said: "no new failures introduced; type safety verified by import-resolution scan, not full tsc."

Pending (needs Karl GO)

git -C /workspace/code/orca-worktrees/sync-upstream-2026-10-19 push origin sync/upstream-2026-10-19
gh pr create -R karlorz/orca --base fork-main --head sync/upstream-2026-10-19 \
  --title 'Sync upstream main 2026-10-19 (15 commits) [skip ci]' --body-file <this file's sections above>

Then: no merge, no tags. Landing waits for Karl GO.

nwparker and others added 16 commits October 18, 2026 07:26
… into ssh/{system-transport,config,remote-exec}/ (stablyai#30355)

git mv plus import, vi.mock and path-literal rewrites; one e2e route regex follows the moved
dynamic-forward process.
…c/ssh/ and ipc/runtime-environments/ (stablyai#30362)

git mv plus import, vi.mock and path-literal rewrites; e2e route regexes and the Windows host lane
filter follow the moved handlers.
…xport shims (stablyai#30369)

Deletes local-agent-install-dir-detection, notification-burst-cooldown, terminal-git-credential-guard
and tui-agent-detection-commands (pure re-export modules) and the re-export lines in seven more
ipc modules; importers and test mocks name the real modules.
…lpers from their owning modules (stablyai#30370)

Removes the re-export lines in runtime-rpc-result (hasRuntimeRpcErrorCode), sync-runtime-graph,
sync-key, the terminal orphan-recovery modules, orcad-idle-exit, remote-runtime-subscription-transport,
two orcad modules and the ssh-connection test harness; importers and test mocks name the real modules.
…not re-export shims (stablyai#30373)

Removes the re-export lines in 22 src/main/runtime modules (rpc schemas, skill surface, worker
identity, terminal viewport, teardown, git, e2ee crypto and more); importers and test mocks name
the real modules.
…rs from their owning modules (stablyai#30375)

Removes the re-export lines in worktree-logic, worktree-base-directory-poller, filesystem-watcher and
runtime-environment-transport-routing. Test mocks that supplied a re-exported name now mock the
module that defines it, so they still reach the code under test.
…ill sends resume records (dark, layout-owner build only) (stablyai#30380)

* chore(layout): the drift check's ignore comment names every main-only kind (dark, layout-owner build only)

* fix(layout): a quit stage retried after a failed one still sends the resume records (dark, layout-owner build only)

* feat(layout): the window's local layout stream reopens after a loss, and its snapshot redraws every workspace (dark, layout-owner build only)
…i#30257)

Orca started jcode's background server itself as a terminal opened, ahead of
the jcode client. On daemon-backed terminals that launch had no PATH and
silently failed; where it did start, the server ran jcode's tools and hooks
outside the shell's environment, without the client's launch flags, and
outside jcode's own startup lock. jcode's client already waits for its server
to signal ready, so it is now the only thing that starts it.
…ow (stablyai#29140)

* feat(settings): remove a downloaded agent runtime from its Settings row

When the host offers managed-runtime.remove.v1 and an Orca-installed copy is
there with nothing running, the Settings install row shows a trash button
("Remove downloaded runtime") that asks first: "Remove {agent} from this
host? Running {agent} chats stop. Chat history is kept." While the host removes
it the row says "Removing…"; a refused removal shows the host's reason and keeps
the button. Chats never show it.

* fix(settings): offer Remove for a damaged copy too, and say which host the downloaded runtime leaves

The row offers Remove whenever the host says Orca's copy is there (canRemove), damaged included;
an older host without it keeps today's rule. The confirmation now reads "Remove the downloaded
{agent} runtime from {host}? Running {agent} chats there stop. Chat history is kept.", naming the
paired host, or this computer.

* fix(settings): Remove follows the host's canRemove alone

* fix(settings): the Remove dialog says the sign-in is kept too

* fix(settings): show the downloaded runtime's install state as the provider's status line

The Antigravity row in Settings > Chat > Providers drew its install state as a
bordered box nested inside the row. It now reads like the other rows: one grey
status line under the name, with its actions as inline links joined by ' · '
(Installed · Remove, Not installed · Install · size, a thin progress bar with
Cancel while downloading, Reinstall · Remove for a damaged copy, Try again
after a failure). A healthy install no longer offers Reinstall. The Remove
confirmation now says running chats stop and their history is kept.

* fix(settings): make Antigravity's first Install a primary button beside the switch

Not installed now shows a high-contrast Install button at the row's right end in
Settings > Chat > Providers and Settings > AI Provider Accounts > Antigravity; the
status line keeps the sentences (Not installed · 112 MB download.). Every other
action stays a link in the line.
…stablyai#29070)

* fix(mobile): put the session tabs in the top bar on a landscape phone

A sideways phone is about 390pt tall and the session header spent two rows
on it. On a landscape phone the tab strip now shares the top bar with the
back button, title and panel icons. Portrait and tablet layouts are unchanged.

* fix(mobile): give session tabs side borders and a filled active tab

In the landscape top bar the tabs sat between the title and the panel
icons with nothing marking where one tab ended. Each tab now has a 1pt
border on its sides, running the full height of the bar, and the active
tab gets the raised fill, as the desktop tab strip draws them. The same
strip is used in portrait, so both orientations match.

* fix(mobile): reset tab strip measurements on view attachment

* style(mobile): format tab strip ref dependencies

* fix(mobile): keep two header rows in landscape windows too narrow for top-bar tabs

A short, narrow window (a ~390x350 web window) is wider than tall, so it
counted as a landscape phone and moved the tabs into a top bar that has no
width left for them. Top-bar tabs now also need at least 568pt of width,
the narrowest landscape phone.

* fix(mobile): give the landscape top-bar tab strip a fixed left edge so scrolled tabs never read as part of the title

* fix(mobile): 12pt between the session title and the landscape tab strip
…ate off (stablyai#30387)

A due update check makes agy start --bg-updater, whose own console child opens
a visible window on Windows and takes focus, so stepping away from Orca for
15+ minutes and coming back flashed a terminal (stablyai#27390). Set
AGY_CLI_DISABLE_AUTO_UPDATE=true on both probes; a background quota read should
not update the user's CLI anyway. Only 'true' is honoured (agy 1.4.2).

Co-authored-by: Orca Worker <orca-worker@localhost>
…dow-wide layout hold goes (dark, layout-owner build only) (stablyai#30384)

* chore(layout): the drift check's ignore comment names every main-only kind (dark, layout-owner build only)

* fix(layout): a quit stage retried after a failed one still sends the resume records (dark, layout-owner build only)

* feat(layout): the window's local layout stream reopens after a loss, and its snapshot redraws every workspace (dark, layout-owner build only)

* fix(layout): a command whose target main's copy lacks is a logged refusal, not the window's own change (dark, layout-owner build only)

* feat(layout): frames keep each tab the window drew, closed or moved as drawn until main answers; the global frame hold goes (dark, layout-owner build only)

A refused draw-first terminal create is closed (its terminal stopped) at the refusal. The
activation create no longer draws main's tab itself while the stream is down: the reopened
stream's snapshot does.

* fix(layout): a tab move or drag-out the frame already drew is not placed again by the window (dark, layout-owner build only)

Also holds the group sizes the window drew until main saves them.

* test(layout): with frames flowing, a pin promotes a preview tab once and tab-change bookkeeping runs once (dark, layout-owner build only)

Also states that the held-tab overlay builds frame slices only.

* test(layout): read the rename's title without a cast

* chore(layout): the drift check's header lists the same ignored records as its inline comment
* Require a full hover delay before each tab preview

Tab previews opened almost immediately after a previous preview had been shown, so sweeping across the tab strip caused a flurry of popups. Raise the tab tooltip delay to 800 ms and drop the warm-start chain: the shared open-state context, the 300 ms skip delay, and the slide animation that carried position between cards. Every tab now waits its full dwell time, and keyboard focus still shows the preview immediately.

* Test that tab hover cards wait a full dwell on every hover

The tab hover card no longer slides instantly between neighboring tabs. Each hover now waits for the full delay before showing a preview. The e2e test still expected instant sliding, so it was rewritten to match.

- Remove the frame-recording helpers and the slide and reversal assertions.
- Check that no card appears before the dwell, and that the card appears after it.
- Check that leaving a tab cancels a pending preview, and that time spent on other tabs does not count toward the dwell.
- Check that re-entering the same tab requires a fresh dwell.
…d order under the pointer (dark) (stablyai#30284)

* feat(sidebar): sort stamps reconcile stored tiers at startup against live hook rows and terminals (dark)

* test(sidebar): a restart clears an unbacked local tier and keeps an SSH host's

* fix(sidebar): run the sort tier reconcile once hook rows and PTYs settle, seeding hydrated rows

* fix(sidebar): clear a stored tier only on proof its terminals died; a rest seed adds no clear

* chore(sidebar): merge origin/main; locality helper moved to shared

* feat(sidebar): sort Recent and Smart by host stamps behind the sidebar-inputs switch

With ORCA_SIDEBAR_INPUTS=main, the window, main and the phone order Recent by
lastActivityAt and Smart by smartTier then smartAt (Needs you, Done, Working,
then the rest by Recent). The window holds its displayed order while the
pointer is over the list or a drag runs. Switch off: today's sort path.

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

* chore: restore files the merge commit's formatter rewrote

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

* fix(sidebar): stamp-order review fixes behind the sidebar-inputs switch

The window writes no Recent stamps with the switch on (terminal start and
exit, unread marks, comment edits), the hover hold covers only Recent and
Smart and ends with a drag, main follows only explicit metadata saves, and
the phone picks its sort from the unfiltered rows.

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

* test(sidebar): folder writers and a Manual drag under the stamp switch

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

* test(sidebar): name the stamp type in the ps summaries test

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
…tablyai#30137)

Two merged changes left lines past the formatter's 100-column width in
structured-session-create-support.ts, structured-agent-session-create-adoption.ts
and transcript-opencode-sqlite-query.ts. Any branch that merges main gets them
reformatted by the pre-commit hook, which pushes two of them past the 300-line
limit and fails CI. Format them, and keep them under the limit by moving the
bounded row readers and the resume adopt payload into the modules that own them.
No behavior change.
# Conflicts:
#	src/main/ipc/runtime-environments/runtime-environment-managed-tunnel.test.ts
#	src/main/ipc/runtime-environments/runtime-environment-managed-tunnel.ts
#	src/main/ipc/runtime-environments/runtime-environment-unreachable-hint.test.ts
#	src/main/ipc/runtime-environments/runtime-environment-unreachable-hint.ts
#	src/main/startup/main-process-runtime-launch.ts
@karlorz
karlorz merged commit e9e5c82 into fork-main Oct 19, 2026
37 of 40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants