The Source Control hub's next-step bar is now the only bottom action on the
PR tab: the tab body takes its footer from the caller, and only the
diff-review dock passes the old bottom action. The legacy Conflicts box is
gone, since the gate row and the bar's Resolve already cover it, so a
conflicting PR no longer says so four times. The bar keeps its reason line
only where its button does not name the blocker.
* fix(terminal): observe foreground at the physical PTY owner
* fix(terminal): keep existing inventory, inspection and display semantics around master-group foreground
Review round 1 fixes for the physical-owner foreground observation:
- Stop and liveness verification keep complete-inventory proof: the router's
scoped listProcesses({ptyIds}) is owner resolution again (absent = []).
Only the launch guard's old-owner fallback asks for an established
target's owner via an internal targetOwnerOnly option.
- Degraded daemon mode routes foreground observations and target reads to
the established owner, so an unreachable unrelated daemon cannot refuse a
known terminal there either.
- Display and name refreshes read the master's foreground group but take
member rows from the shared single-flight process-table snapshot; no
per-terminal ps per refresh. Recognized agent names skip the confirm scan
again, and builds without the native accessor keep the existing reader.
- Ordinary inspections keep their first-match routing; strict owner and
incarnation checks apply only to foreground decisions. The unused
foregroundOnly preload/IPC/RPC surface is removed.
- Local inventory forwards only the target scope, never caller deadlines.
- An interpreter running an agent script counts as that agent, as before;
a blank argv row no longer voids a terminal capture outside the
foreground group.
- Bump the packaged compatibility contract to daemon protocol 55 and move
the node-pty accessor above the process getter's doc comment.
* fix(terminal): keep the node-pty patch hunk well-formed and drop redundant foreground tests
Remove two stray context lines from the src/unixTerminal.ts hunk so its body
matches its header (strict patch parsers reject the mismatch), and update the
lockfile patch hash. Prune foreground tests whose rows repeat branches the
parity table already covers.
* fix(terminal): index the shared snapshot by TTY once and keep observation age nonnegative
Display refreshes filtered the whole shared process table per pane, so
work grew with panes times processes. Group each snapshot by normalized
TTY once, memoized by array identity, and look each pane up directly;
the scaling contract now counts row TTY reads at N and 10N panes.
Both foreground observation producers clamp capturedAgeMs at zero, so a
wall-clock step back during the read no longer yields an envelope the
validator rejects and the launch guard refuses.
* test: move foreground-observation compat tests into the protocol compatibility suite
Main removed daemon-pty-adapter-steady-state-compat.test.ts; the merge restored it with only this branch's block. Reuse the suite's existing inspection adapter helper so no new type assertion is added.
Collapsed parents each walked their full subtree per render, which was
quadratic on deep lineage chains. Build all parents' signal states once per
lineage tree identity instead.
Fixes STA-13325
* Show the retry command when worker_done times out on a frozen Orca
* Say nothing was sent when only the contract check timed out
* Say nothing was sent even when the retry command cannot be printed
Rows lead with the file name and put its folder under it, so names stop
truncating. The whole row opens the diff, one quiet button stages or
unstages, and discard moves to a left swipe that still asks first. A
status line, a Commits row and a conflict banner with Abort sit above
Uncommitted and Staged sections that carry Stage all and Unstage all.
The rarer git actions move into the header's grouped menu.
* fix(git): apply textconv filter to original blob in diff view (#37100)
Apply git cat-file --textconv when reading non-previewable blobs for diffs so that encrypted or filtered files (git-crypt, sops, etc.) are rendered as readable text instead of binary.
Fixes#37100
* fix(git): apply textconv to binary working-tree files for unstaged diffs
* fix(git): textconv only diffs whose editable side stays byte-exact
Unstaged diffs keep raw bytes unless the path's driver leaves the working
tree unchanged (clean/smudge encryption such as git-crypt); the check runs
in a scratch object store so nothing is written to the repo. Drops the
binary working-tree textconv, which made converted text editable.
* fix(git): read the stored blob first and convert only paths with a driver
cat-file --textconv pretty-prints trees, so a directory replaced by a file
showed a tree listing. Reading the blob first keeps absence and type
handling unchanged, and drivers are looked up in parallel so paths without
one cost no extra wait. Driver failures are kept out of the settled cache,
deleted files convert, and the clean-filter probe gets a read deadline.
* fix(git): never settle-cache diffs that ran a textconv driver
Driver output depends on config, keys and tools the worktree stamp does not
cover, so a locked key or failing driver could pin a raw result. Deleted
files stay raw, since Monaco's revert arrows would restore converted text,
and drivers run off the WSL direct-read route so profile variables reach
them.
* fix(git): show the editable unstaged side against checkout bytes
A worktree that the driver leaves unchanged does not make the converted
original safe: Monaco's revert copies the original into the editable side,
and a driver like `tr a-z A-Z` would restore ONE where checkout writes
one. Unstaged diffs now read the Git side with `cat-file --filters`, which
is exactly what checkout writes and decrypts clean/smudge encryption, so
the scratch-store probe is gone.
* fix(git): share one driver lookup per path and keep editable ranges in checkout form
check-attr is a read, so it no longer counts as a worktree mutation or
waits on WSL write probes. Commit, branch and submodule diffs look the
driver up once per path, the unstaged submodule range shows checkout bytes
like the rest of the editable side, and a staged rename stays out of the
settled cache when either path has a driver.
* test(git): age the diff stamp with a fixed timestamp
---------
Co-authored-by: Hrithik <hrithik@Hrithiks-MacBook-Pro.local>
Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
* fix(native-chat): keep received output when the journal queue is busy
The journal sink refused its 1,025th outstanding write, and the
fire-and-forget append, publish and tombstone paths dropped that
refusal, so a reply or tool result vanished on reopen while the drain
still reported success. Pressure now only pauses provider reading; the
sink no longer refuses output it has already received. The final-tail
reservation existed only to get past that refusal, so it goes too.
Pi relied on refusals to pause its reader, so it now binds the sink's
reading control after startup, alongside the lane's own hold.
* test(pi): prove a command start keeps a journal-paused reader paused
* test(native-chat): drop pressure tests that no longer guard a contract
fire() fell back to its loop snapshot when a concurrent learn (no enabled
automations left) or forget had cleared the entry during an earlier host's
wake, which could wake a distro for a deleted automation. A cleared entry
is now skipped.
* fix(emulator): report Device Hub blocking iOS simulator input instead of a silent success
* fix(emulator): keep the session backend so the pane input check sees iOS sessions
* test(emulator): pin the pane input check to active iOS sessions
* fix(emulator): probe Device Hub via process-host and recheck on pane keyboard input
* refactor(emulator): use the shared RPC error-code predicate in the pane input check
* fix(emulator): key the pane input check on the live stream after the session hook stopped returning session
Main's session hook no longer returns session and sits at its line cap, so the pane keys the check on the live preview URL. The iOS-only session check moves into its own module to keep the runtime commands under the cap.
The close button sat at a fixed 16pt from the right edge and ignored the
window's right safe-area inset, which on the iPhone Duo is the status
column holding the clock and the camera. Offset it by that inset, and size
it to 44pt itself because page Pressables ignore hitSlop.
* fix(web): give the web client a plugins API so the update-review toast cannot crash
The web preload has no plugins namespace, so its fallback proxy answers
takeUpdateReviewNotices() with undefined and the startup watcher threw
reading .length. Plugins run only in the desktop app; the web client now
reports no held updates, an empty auto-update state and no install counts.
* test(web): drive install counts through the store; tighten comment
Subscribing to the whole settings object re-rendered DiffViewer and rebuilt its
options object on every unrelated settings write, which made @monaco-editor/react
call updateOptions on the diff editor each time. Select the three diff fields and
memoize the options, mirroring the combined diff fix (#36921).
* Clarify Git operation status across workspaces
* fix translation
* Clarify when a Git operation is running in another workspace
* Clarify Git operation feedback in Chinese translations
* Clarify which Git operations can block another workspace
* Show Git operation waiting feedback during PR preparation
* rm file
* Fix remote operation ownership test setup
* Fix remote operation ownership test setup
* fix(cli): keep inferred worktree creation in the caller project
* Fix caller checkout ranking and creation guidance
* Share caller-host containment preparation across CLI selections
* Correct Windows CLI fixture syntax and snapshot command
* Match worktree fixture output to typed execution hosts
* Regenerate bundled workspace placement guidance
* Refuse ambiguous workspace ownership and preserve launch replay
* Scope runtime filesystem mocks to their aggregate tests
* Preserve launch proof semantics under strict test diagnostics
* Keep launch proof imports within their compiler project boundary
* Consolidate journal cleanup test imports
* Adapt launch fixtures to the current host settings contract
* Keep the CLI error formatter under the file-size limit
Move the selector-ambiguity workspace-choice check into selector-ambiguity-recovery.ts, which already owns that error's recovery text. Behavior is unchanged.
* Expect main's concise orchestration output in the workspace-choice CLI tests
Orchestration commands now print the one-line failure on stderr and the workspace choices and next steps on stdout (or compact JSON plus the stderr line with --json), and print concise success fields.
---------
Co-authored-by: Orca QA <orca-qa@users.noreply.github.com>
* fix(emulator): scope emulator list to the worktree's sessions
emulator list ignored --worktree and returned serve-sim's global iOS helper list. It now lists the session registry's attached sessions (iOS and Android) for the selected worktree, or every worktree's for --worktree all.
* fix(emulator): drop stopped devices before listing sessions
* fix(emulator): point the no-active hint at emulator devices
* test(emulator): assert list results, not serve-sim calls
* refactor(emulator): prune stopped devices inside the registry listing
* Nest chat-UI orchestration workers under the agent that started them
Main's lineage projection only walked terminal panes, so workers running
in the chat UI never got a parent link and listed flat in the sidebar.
It now also projects chat workers, keyed by their visible chat row, and
resolves a chat creator or coordinator to that chat's visible row
instead of its handle or private mailbox pane key.
* Fix public worker lineage across assignment and row identities
* Complete terminal lineage provenance and bound active session selection
* Repair lineage test runtime boundaries and SQLite counters
* Provide read-only crew snapshots for each agent
* Batch public lineage verification after exact recency selection
* Derive crew relations once per meaningful host change
* Remove package manager lockfile churn from hook
* Use checked runtime values in lineage integration tests
* Document the trusted Dispatch SQL row boundary
* Keep lineage integration imports within their test programs
* Load native lineage fixtures before test execution
* test: complete lineage inputs in runtime and sidebar fixtures
* test: seed benchmark facts from active dispatches
* test: replace partial orchestration DB casts with typed fixtures
* test: complete stale-leaf mailbox fixture session input
* Derive durable crew parents from retained assignment proof
* fix(test): render worker lineage fixture with production list
* Add scoped terminal identity acquisition and preserve crew source wakes
* Share raw crew identity inputs through scoped production readers
* Exercise crew generation retirement through actual source owners
* Retire crew inputs on consumed ownership and visibility writes
* Use typed crew mutation and fixture access
* Repair crew fixture and RPC type contracts
* Align crew integration fixtures and RPC parameter contracts
* Encapsulate terminal identity mutations and captured reader contracts
* Seed terminal identity fixtures through canonical mutations
* Fix terminal identity fixture return type
* Cover terminal identity lifecycle schedules
* Align terminal fixtures with canonical identity sources
* Repair runtime fixture source contracts
* Use checked database fixtures for federation contracts
* Update crew source inventories and exit fixtures
* Preserve crew setup outcomes at existing subscription owners
* Match managed restore fixture to its nullable async return type
* Keep absent setup observations distinct from undefined failures
* Drive pending Crew questions from existing metadata
* Preserve nested pairing repair outcomes for shared callers
* Route attached workers to explicit local recipients
* Type Crew pending-question measurement receipts
* Match SSH repair fixture target absence to store contract
* Bound cold terminal layout construction and finite pane acquisition
* test: use public runtime identity in pane acquisition fixture
* Avoid repeated searches in cold workspace layout loading
* Verify cold loader fault identity and hook claimant effects
* Revert "Route attached workers to explicit local recipients"
This reverts commit f1335d1c06.
Keep attached workers on the existing Run-home routing path for this change.
* Omit crew peer addresses outside the active home route
* Keep crew retries on the verified runtime session
* Bound cold layout retirement and recorded-key construction
* Verify original cold layout failure identity
* fix: preserve surviving layout split references
* test: use typed retirement instrumentation properties
* test: preserve pane and retirement fixture contracts with checked types
* Prepare Crew record admission and wake identity changes
* Derive Crew recipient actions from current target owners
* Keep nested Crew process facts within selected acquisition
* Defer Crew legacy facts to consumers and complete raw coverage on success
* Use deterministic time in Crew command fixtures
* Document schema-owned Dispatch row assertions
* test: align Crew authority fixtures with typed project boundaries
* test: place Crew CLI integration in cross-surface project
* Type retained identity test meters with canonical source maps
* Document suffix Dispatch row boundary and preserve fixture unbinding
* test: migrate Crew authority arguments and mailbox observations
* Derive Crew attention and actions from complete recipient authority
* Fix Crew public-command fixture type contracts
* Align Crew fixtures with runtime reader and routing contracts
* Narrow receiving fixture calls to unary RPC methods
* Age pending question fixtures from every actual answer timestamp
* Complete Crew public-command workspace fixture result
* Test delegated helper follow-up through Crew advertised address
* Qualify Crew follow-up addresses through shared command admission
* Complete finite follow-up authority and lifetime evidence
* Assert exact remote authority acquisition error identity
* Consolidate Crew SQL test fixture imports
* Trim Crew read-model tests to the high-impact set
Keep the real CLI/RPC/database command paths, one regression per review-found bug, the cross-version contracts and one N vs 10N operation contract per scaling piece. Drop permutation matrices, equivalence oracles, near-duplicate scenarios and diagnostic output, and return the SSH, managed-server and WSL test files to main, since their production changes were reverted earlier in this PR.
* Drop diagnostic output and a duplicate error case from Crew tests
Remove two leftover console.log diagnostics, an unused 2x2 sample matrix and unused return fields in the follow-up cost contract, and the subscription AbortError serialization case that the subscription identity and preload tests already cover.
* Pass the recorded-leaf reader in main's check-details loader test
* test: remove 462 low-value test declarations
* Shrink flaky test pattern baseline after audit896 test removal
* Remove two empty hook-only suites after audit896 test removal
---------
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
* fix(emulator): show a dead Android preview as disconnected so Connect restarts it
When the scrcpy session ended, the video registry dropped its subscribers silently and a later subscribe was a no-op, so the pane kept saying Connected over a blank 'Stream disconnected' screen with no way to retry. The registry now tells subscribers the session ended, the IPC relays it on the stream error channel, and the pane marks the session disconnected so the toolbar's Connect button restarts scrcpy.
* fix(emulator): retry a lost Android preview by AVD name and keep stale errors off new streams
* fix(emulator): keep a live emulator serial and fall back to its AVD name only once it is gone
* fix(emulator): keep the AVD target across failed reconnects and reused serials
* fix(emulator): reboot a vanished emulator by AVD name only when the host no longer finds its serial
Replaces the pre-attach device refresh: the live serial always goes first, and the AVD name is tried only after the host answers emulator_device_not_found.
* refactor(emulator): read the host error code plainly in the AVD fallback
* refactor(emulator): type the attach result without a cast and derive WebCodecs support in render
* fix(emulator): type the fallback test's attach result and allowlist the WebCodecs diagnostic
The PR tab and the Checks and Comments screens refresh by themselves while
they are open and the app is in the foreground, on desktop's checks-panel
cadence (policy moved to src/shared). A failed background read keeps the
PR on screen and backs off instead of replacing it with an error.
Review threads show the lines they are about: the host forwards the tail
of each thread root's diff hunk, and mobile numbers it back from the
thread's line. Bot findings get "Ask <agent> to fix", which launches
desktop's Resolve comments prompt (moved to src/shared) for that thread.
Fix and Ask buttons name the agent that would start.
* Allow automation CLI setup choices for new workspaces
* Explain automation --setup refusals and read back the saved choice
Name why --setup is refused and what to pass, show the setup choice in
text output, document --setup in the CLI guide, fail when a host drops
the choice, and cover the app-open Terminal dispatch.
* Refuse automation --setup on hosts that can't keep it, and fence the edit's mode
Explicit --setup now needs the host's new setup-choice capability, checked
before any write; commands without --setup are unchanged. An edit whose
setup choice relies on the current new-per-run mode sends a mode
precondition the store checks against the saved record, so a concurrent
switch to an existing worktree refuses the whole edit. Text output shows
the saved choice or "not set", the existing-workspace refusal offers a
remedy that works for every input, and the after-write readback is gone.
* Make the too-old --setup message true for edit and cover a saved setup edit
Omitting --setup on edit keeps the saved choice, so the refusal now says
to run the command without --setup. A new test saves a --setup run edit
through the controller into the store and reads it back after reload.
The PR tab now leads with the PR's identity, one row per merge gate
(checks, unresolved threads, approvals, conflicts) that opens the screen or
sheet that resolves it, a changes card and a collapsed description. Close,
Unlink, Auto-merge, Edit title and Copy link move into the ⋯ menu.
Checks and Comments become pushed screens: failures open with their
annotation and Fix / Rerun / Open / Log on the failure, running checks
next, passed folded; comments filter by Unresolved / All / Hide bots with
Resolve and Reply on each thread and a comment box at the bottom.
Merge opens a sheet that lists only the methods the repo allows, starting
on its default. Reviewers move into a sheet with search to add and remove.
Every Create PR entry point opens one sheet: title and description seeded
from the branch's commits (shared seed rule in src/shared, GitHub's own
default), Write with AI, base picker and draft. It pushes first when
needed, works for all five providers and lands on the PR tab for GitHub.
* fix(wsl): the Codex quota poll gates the distro it probes, not the default
The poll's gate asked whether the wsl -l default was running, then the
home lookup resolved its own default (and could name an account home in
another distro), so the probe could start a stopped distro the gate never
read. The distro is now resolved once, gated, and pinned for the home
lookup; a home in any other distro skips the poll.
* fix(wsl): pin the gated distro for paths only; keep the account lane
Pinning the resolved default into the target also moved the account
lookup off the default lane, so a default-lane account read the system
home. The distro is now pinned for paths and probes only: the account is
that distro's lane, then the default lane the target named. The default
distro comes from resolveWslDefaultDistro, as the exec gate's does.
* fix(wsl): the pinned quota poll reads the account lane launch reads
Drop the default-lane fallback: a pin names the distro, so the account is
that distro's lane, exactly as launch reads its named target. The test now
asserts the poll and launch's own home lookup agree.
* fix(chat): move forward readers to the covered tip after a no-op save
A write whose fold changes nothing stores no outcome record, so its
sequence never appears in a forward read. Readers placed themselves at
the last returned row and stayed behind the live cursor, so open chats
re-read an empty page and recomputed the prompt projection on every
later delivery until the next real save.
Forward journal reads now report the highest sequence they covered.
History pages move there when the read was complete, prompt reuse and
native responses compare against it, and a read cut short by its limit,
byte budget or damage still stops at the last returned row.
* fix(chat): append unlimited outcome reads without spreading, and report coverage from the mobile journal fake
* fix(chat): skip the retention scan for batches that change no journal items
The pane's keyboard only sent serve-sim HID frames over the iOS WebSocket.
Android sessions have no serve-sim socket, so every key was dropped and every
paste failed with "device is not ready".
Android panes now send typed characters, paste and editing keys over a new
emulator:scrcpyKeyboard IPC beside emulator:scrcpyTouch, keyed by the streamed
serial. Main writes them straight to the live scrcpy control socket (text
injection, and keycodes with SHIFT_LEFT held for Shift), so keys keep their
order with touches. iOS keeps the HID path.
* feat(mobile): one next-step bar under both Source Control tabs
Changes and Pull request are the only segments. A bar at the foot of both
shows the branch's one next action: the commit box, push or pull, create
the review, resolve or fix with the workspace's agent, merge when ready,
merge, or why it can't. Commits opens as a pushed screen.
* fix(mobile): keep Merge reachable and show bar failures on both tabs
* test(mobile): expect the two Source Control segments in the page render test
* fix(emulator): detect Android devices with only adb installed
SDK discovery required both adb and the emulator binary under an SDK
root, so hosts with platform-tools only, or a standalone adb such as a
distro android-tools package, saw no Android devices at all. Discovery
now needs only adb, falls back to adb on PATH, and AVD listing and boot
are skipped when the emulator package is missing.
Fixes#32126
Co-authored-by: s546126 <268420947+s546126@users.noreply.github.com>
* test(emulator): drop type assertion in adb-only inventory test
---------
Co-authored-by: s546126 <268420947+s546126@users.noreply.github.com>
* Show a card in the chat when its agent hands work to another agent
An agent that hands work off with 'orca agent launch' from a native chat
now leaves a 'Handed off to agent' card there, linking to the new chat or
terminal, the way a supervised worker-start leaves 'Started worker'.
The CLI names its chat on agent launches (same-host only); the host records
a display-only agent-handoff item after a successful launch with a submitted
prompt, once per launch operation. Nothing about the card can refuse or delay
the launch.
Tracked in STA-13209.
* Keep orca commands working in a native chat that has no terminal handle
The launch-caller evidence read the host stamp off an absent evidence object, so every orca command from an ordinary native chat threw before sending. Adds CLI tests for which requests name the launching chat, restores the lockfile to the base, and fixes the Korean heading.
* Read a card's heading from its creation flags together
A caller passing only the started flag drew a handoff as Started worker; the heading now takes the message's flags as one argument.
* Show the handoff card for every agent a chat launches
A launch without a delivered task now records the card too, with no task text, as the common pattern records every agent a chat creates. The handoff tests now run the real chat host and journal: one card per launch operation, none on replay, a removed card stays removed across a restart, and the clock is fixed.
* Head a launch card Started agent when no task reached the new agent
Handed off to agent now appears only when the card carries a task; a card for an agent started with no task (no prompt, a draft, or a prompt that wasn't delivered) reads Started agent. The heading is derived from the card's text, so nothing new is saved. Also drops a self-launch check the launch path already refuses first.
* Show the handoff headings on the phone's agent cards
The phone card passed only the started flag, so with the new heading rules it would draw every creation card as a plain message. It now passes the message and has a heading for every case, so a missing one fails the build. The heading function now requires the message's creation facts, so no caller can leave them out. Adds the phone strings in every language, and the Japanese "Started agent" now uses the catalog's term for agent.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Route hosted review refreshes to their owning host
* Route remote review operations to their owning host
- Refresh the correct hosted review after remote git operations
- Scope comment mutations and AI acknowledgements to the owner cache
* Route legacy paired SSH reviews through their server owner
- Recover proxied runtime owners for older SSH worktree listings
- Preserve direct and ambiguous host routing safeguards
* Preserve review ownership across remote workspace operations
- Route checks, comments, and linked-review clears through the selected repository owner
- Reject ambiguous or mismatched host context to prevent cross-machine mutations
* Keep check detail tabs scoped to their remote owner
* Preserve remote worktree ownership across reconstructed check tabs
* Preserve direct SSH check tabs when proxy listings overlap
* Scope PR refresh ownership state and safely roll back comment mutations
- Preserve linked-review clear scopes beyond cache eviction and clean them up on expiry
- Handle failed or refused comment reactions and thread resolutions without stale optimistic UI
* Preserve remote review ownership when SSH copies overlap
* Fix review routing for overlapping remote repository hosts
- Preserve server-owned review refreshes when a direct SSH copy exists
- Fail comment mutations and refetches safely when ownership becomes invalid
- Resolve check and sidebar data through the workspace’s owning host
* Relax cache-sensitive test expectations
* Route check refreshes to runtime owners and isolate restored requests
* Scope reconstructed check detail tabs by execution owner
* Fix review refresh ownership for shared remote hosts
- Prefer explicit execution owners when matching worktrees.
- Avoid repeated tab scans when restoring check details.
* Fix hosted review polling for workspaces on multiple hosts
* test: trim redundant review ownership scenarios
* Preserve rich Markdown viewport through bare focus returns
* Retire viewport ownership on editor remount
* Complete no-op navigation and body Tab coverage
* Keep patch metadata keys separate from dependency snapshots
* Retire the viewport before root detach callbacks
* Give the engine writer fixture its native selection
* Keep native focus navigation current in Markdown
* fix: leave smooth Markdown scrolling to native focus cancellation
* Cover focus wrapper removal and routed Markdown writers
* Type the viewport scroll spy and mark the focus-recovery wait as deliberate
* Scope Markdown viewport wheel and touch guards to the editor scroller
Tapping a file on the commit page now opens the shared diff screen for
that file in that commit (openDiffForFile kind 'commit'), in today's
Commits tab and inside the hub's Commits page.
Same-named simulators on different iOS runtimes looked identical, and records whose runtime is gone could be picked and then failed to connect. The pane already received runtime and isAvailable from simctl; the toolbar ignored both.