Commit Graph
8153 Commits
Author SHA1 Message Date
OrcaWinandOrcaWin 4633fa9d07 fix(sidebar): keep the workspace hover card open behind link actions (#33409)
* fix(sidebar): keep the workspace hover card open behind link actions and system-browser opens

* fix(sidebar): scope the unfocused hover hold to external opens and fix chooser dismissal edge cases

* perf(sidebar): register the refocus listener only while a hover hold is set

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 23:07:54 -07:00
OrcaWinandOrcaWin e1066973f2 fix(worktrees): never leave the create-worktree dialog stuck on a stalled preflight (#33400)
* fix(worktrees): never leave the create-worktree dialog stuck on a stalled preflight

Bound the same-repo PR branch fetch with the review-head fetch timeout, and
hand a slow composer submit off to a staged sidebar row so the dialog closes.

* fix(worktrees): harden create-worktree handoff from adversarial review

Dedupe handed-off submits against linked creations resolved during preflight,
bound the staged sidebar row with a deadline, offer Reopen on handed-off
failures, and bound the GitLab MR branch fetch.

* test(worktrees): expect the bounded PR/MR branch fetch timeout

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 23:00:47 -07:00
OrcaWinandOrcaWin 3d24e61726 test: remove self-validating checks and exercise intended boundaries (#33412)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 22:52:08 -07:00
NeilandClaude Opus 5.5 8e9f86b119 feat(managed-server): Update and Update anyway for a managed SSH server, keeping its running terminals (#33397)
* feat(managed-server): offer Update and Update anyway on a managed SSH server's row

A managed SSH server only updated on connect, and every connect deferred while
a terminal ran there. Its row now offers Update when this desktop bundles a
newer build than the Orca that runs the host. When running terminals defer it,
Update anyway restarts the server past them; the terminal daemon carries them
across the restart.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(managed-server): Update anyway passes only counted live terminals and keeps Update's version admission

Update anyway now sends the incumbent build it confirmed over; under the host
fence it is refused if another desktop activated a build since, keeps the
newer-host downgrade refusal, and never passes an uncounted terminal census.
The offer also covers hosts activated before the Orca version was recorded,
for the build this desktop already deferred there.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(managed-server): Update anyway also confirms a menu Update the row does not advertise

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(managed-server): the row shows one confirmation at a time

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* ci(e2e): route managed-server update sources to the Update anyway Docker spec

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 22:49:18 -07:00
OrcaWinandOrcaWin e7a567b178 fix(worktrees): explain the shallow-clone local base warning and let users stop the refresh (#33260)
* fix(worktrees): explain the shallow-clone local base warning and let users stop the refresh

When a shallow clone hides the shared history, the local base fast-forward
refusal now says so and shows the git fetch --unshallow command, instead of
blaming local-only commits. Every refresh-failure toast also gets a
"Stop updating local main" action that turns off Keep Local Main Up to Date.

* feat(worktrees): add an Unshallow button that runs the fetch in a new terminal tab

* feat(worktrees): rename the opt-out to Disable Check and explain it in a tooltip

* fix(worktrees): harden the Unshallow launch

Reuse createNewTerminalTab (owner-routed, no focus read) instead of a
parallel launcher, report real host-launch outcomes before dismissing,
only offer the button for shell-inert remote names, route activation by
the creation host, ignore double clicks, and treat only a silent exit 1
from merge-base as a missing merge base.

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 22:45:21 -07:00
OrcaWinandOrcaWin 1d2b5361ef test: remove duplicate assertions and repair misleading fixtures (#33394)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 21:52:14 -07:00
Neil 4fa91acb4f fix(repos): drop a paired server's old workspace rows when it relists them under new project ids (#33396)
* fix(repos): drop a repo's worktree rows when its host's catalog no longer lists it

A paired server that relists its checkouts under new repo ids (a project
copied into another profile, then that profile switched to) left the
desktop showing the old rows beside the new ones, the old under Unknown.
Every catalog fetch now drops the rows of the repo registrations it
removed, scoped to the dropped host.

Refs STA-12076

* fix(repos): purge a dropped repo's workspaces like a vanished checkout

Clears selection, tabs and per-workspace state of the dropped rows through
the same bulk purge an authoritative scan uses, flushing delayed editor
text first; the three catalog fetch paths share one finalize step.

* fix(repos): drop rows only, never a registration added after the request

Review: purging tabs and selection could race repo add/remove and lose
state. Keep the change to rows, and fence it to registrations the store
held when the catalog request went out.

* test(e2e): drop the fixed settle wait from the repo id change repro
2026-10-24 21:51:22 -07:00
OrcaWinandOrcaWin 5efcbf41f7 test: remove redundant checks and strengthen runtime regression coverage (#33385)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 21:08:47 -07:00
NeilandMinidoracat b94ad9870e fix(terminal): don't resume an agent whose spawned PTY is still live (#33380)
The daemon records each terminal's spawn pane key and reports it in session listings; the sleeping-agent activation gate uses it as an exact-match fallback to find a live agent PTY after the host re-keys its tab, so paired clients and phone wake no longer start a duplicate `claude --resume`. Fixes #21235, #24385. Supersedes #24386.

Co-authored-by: Minidoracat <11269639+Minidoracat@users.noreply.github.com>
2026-10-24 20:51:22 -07:00
7d0103e8a6 fix(jira): keep the Tasks Board view selected after you leave the page (#30588)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
2026-10-25 03:43:08 +00:00
OrcaWinandOrcaWin f392c6bd46 test: remove redundant checks and strengthen runtime regression coverage (#33373)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 20:24:40 -07:00
Kelvin Amoaba 25b9ce5168 feat(browser): show a hovered or focused link's URL in a bubble at the bottom of the page (#32978) 2026-10-25 03:09:30 +00:00
Neilandluisgonzaleznf 0fa161ba42 fix(agents): skip Codex's startup update prompt on Orca-driven launches (#33355)
Orca-driven Codex launches that type their prompt after start (workers, automations, continuation/handoff, pane-spawn and other submit-after-ready flows) pass `-c check_for_update_on_startup=false`, so Codex's "Update now" screen can't block them or be accepted by Orca's Enter. User-typed launches and resumes are unchanged. Fixes #15814, #18153. Supersedes #18156.

Co-authored-by: luisgonzaleznf <47302972+luisgonzaleznf@users.noreply.github.com>
2026-10-24 19:56:41 -07:00
Kelvin Amoaba 76f0f35bad feat(browser): speaker icon on tabs playing sound, with tab mute (#32981) 2026-10-25 02:51:37 +00:00
OrcaWinandOrcaWin b7476f5457 test: remove redundant cases and strengthen regression assertions (#33356)
* test: remove redundant cases and strengthen regression assertions

* test: let upstream empty typecheck baseline take precedence

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 19:51:11 -07:00
Kelvin Amoaba 695fc0081c feat(browser): bigger new tab tiles and roomier workspace card (#33178) 2026-10-25 02:44:03 +00:00
OrcaWinandOrcaWin fdcf887bf0 chore(lint): fix suppressed lint violations instead of ignoring them (#33294)
* chore(lint): remove disable directives that suppress nothing

Each was reported unused by the oxlint config that owns its rule (root,
casting, react-doctor, anti-slop, native-plugins), including 17 file-level
react-doctor blanket disables whose rule no longer fires. An unused
react-hooks disable was masking a react/purity finding in
useAgentBucketCounts (compiler rules skip functions with hook
suppressions); suppress that one explicitly where the code explains it.

* test(tab-bar): use typed tab/file fixtures instead of @ts-expect-error partials

* chore(lint): fix misc suppressed lint violations instead of disabling

- consistent-type-imports: the "vi.importActual requires inline import()"
  rationale was wrong; use typed vi.mock(import(...), importOriginal) or a
  type-only namespace import.
- no-control-regex: source-control commit/push failure summaries, shell PATH
  hydration, and ipynb ANSI parsing reuse the shared ansi-escape-sequences
  stripper and control-character pattern instead of private copies.
- no-explicit-any / no-useless-spread / no-this-alias: typed `this` in
  bridge test mocks, drop blanket file-level disables, drop a this-alias.

* refactor(main): replace avoidable type assertions with checked narrowing

17 production cast suppressions in main/wsl-guest removed: untrusted IPC
and RPC payloads (Jira issue update, WSL guest plugin install, handshake
type) now narrow through isRecord/type guards and build typed results;
redundant casts dropped; hand-rolled object checks and errno casts use the
existing isRecord / hasErrorCode helpers.

* refactor(renderer,mobile): replace avoidable type assertions with checked types

13 production cast suppressions removed: RPC failures read through the
`ok` discriminant instead of casting to RpcFailure; react-native-web host
refs narrowed with instanceof HTMLElement; redundant reply/diff casts
become checked annotations; the TUI agent param uses z.custom(isTuiAgent)
like its sibling schemas; the agent-status slice cast that hid missing
actions is gone so the creator's return type checks the whole slice.

* chore(lint): drop dead tiptap wrapper; scope anti-slop mocking rule to test support

- safe-react-node-view-renderer patched handleSelectionUpdate, which
  @tiptap/react 3.31.3 no longer has, so it always returned early. Use the
  stock ReactNodeViewRenderer.
- The anti-slop test override only matched *.test.{ts,tsx}, forcing
  file-level no-module-mocking disables in test harnesses and fixtures.
  Match *-test-harness, *-test-fixture(s), .test-fixture and *.test.mjs,
  then drop those disables and the now-redundant per-file exemptions.

* test: replace repeated cast suppressions with typed fixtures (main/shared/e2e)

Net -119 cast directives. Typed fixtures replace recurring casts:
unusedSshConnection/unusedOrcadHostTransport placeholders, a typed
readPersistedState harness read (exposed a test treating optional
httpProxyUrl as always set), real Response objects in fetch spies, an
updater main-window fixture, a CDP webContents adapter, one shared
releaseModuleExport for cross-version tests, and requireOverlayDir in
place of `as string` on possibly-undefined overlay paths.

* fix(runtime): validate loaded device rows and host scope instead of casting

Two cast suppressions claimed checks that did not happen:
- device-registry-file-read: "normalizeLoadedDeviceRow re-validates every
  field" was false; deviceId, token, name and timestamps were never
  checked. Rows without an identity are now dropped and the file is set
  aside through the existing corrupt-file path (registry reads as
  doubtful, so no revocation verdicts); a non-string token is stripped
  so the row stays listed but cannot authenticate.
- client-ui: "only optionality differs" was false; any string reached
  persisted workspaceHostScope. Narrow it with isWorkspaceHostScope and
  ignore unknown scopes (wire schema unchanged for mixed versions). The
  remaining cast now states what it actually covers.

* test(runtime,ipc): drop redundant cast suppressions; typed runtime store fixture

-98 cast directives across runtime/ipc tests: 61 casts that typecheck
without the assertion; a typed vi.fn for scoped invalidation; a
partialRuntimeStore fixture in place of `store as never` for
OrcaRuntimeService; typed worker terminal/authority builders in the
incarnation-fallback suite (the old stub lacked runtimeId, ptyId,
worktreeId and launchTokenHash) plus removal of stacked duplicate
directives there.

* chore(lint): typed vi.mock imports and explicit listener snapshot in shared-bucket tests

Remaining files from the misc-rule pass that overlapped other buckets:
codex-accounts mocks use the typed vi.mock(import(...)) form instead of
a consistent-type-imports disable; the daemon late-exit fixture copies
its listener set with Array.from instead of a no-useless-spread disable.

* refactor(github,mobile): narrow routing settings type; drop remaining avoidable casts

- work-item-routing cast a one-field object to AppState['settings'] under
  a claim that readers only consume activeRuntimeEnvironmentId. Return the
  existing RuntimeFocusSettings pick instead and narrow the cache-key
  chain's parameters, so the compiler enforces that claim.
- mobile file preview reads refusals through the RpcResponse `ok`
  discriminant rather than a cast.
- terminal document host-notify accepts `unknown` errors, removing the
  message-bridge cast.
- native chat readability drops a redundant repo-list cast.

* test(renderer): replace repeated cast suppressions with typed fixtures

-140 cast directives (and ~150 unsuppressed casts of the same shapes):
- mockPanePtyArgs owns the connectPanePty fixture casts, so a wrong
  argument order or fixture is now a type error; drop binding casts for
  members PanePtyBinding already declares.
- Seed AppState tab rows with the typed makeTerminalTab; this exposed a
  split direction 'row' that is not a TerminalPaneSplitDirection.
- Partial GlobalSettings use getDefaultSettings overrides; Jira-only
  stores use createTestStore; runtime environment rows/statuses come from
  a typed paired-runtime-environment fixture.

* chore(lint): drop no-module-mocking disable now covered by the test-fixture glob

* test(e2e): fix all 221 grandfathered e2e type errors; baseline to zero

The e2e typecheck baseline grandfathered 221 errors in 119 files. About a
third were tests drifted from the current API, several of which would
fail or mislead at runtime:
- terminal-shortcuts called a nonexistent xterm buffer method;
- the daemon-lifecycle fake lacked terminateOwnedTree, hidden by importing
  its type from a module that does not export it;
- arguments in the wrong position (listProcesses(hostId, opts), a dropped
  pty.write inputKind, an extra toWebTerminalSurfaceTabId argument);
- removed enum values ('drawer', 'idle', 'editor',
  'session-insecure-origin') and a launch_source the telemetry schema
  rejects;
- missing required fields (turnScope, childWorkOpen, providerIdentity,
  reviewLookupOutcome, runtimeServiceAccount behind an `as RelayConfig`);
- dead reads (tab.customTitle, bucket.targets, changedPixels).
Also lifts variables that narrowed to `never` after poll-callback
assignment, and adds a typed xterm render-dimensions accessor. Includes
the cross-version suites' shared releaseModuleExport adoption.

* chore(typecheck): gate the now-clean e2e typecheck in local lint

The e2e baseline is empty, so the ratchet now rejects any tests/ type
error. CI already runs it via run-ratchets; add it to pnpm lint's
explicit ratchet list and replace the stale 'not yet clean' note.

* test(mobile): typecheck every mobile test; baseline 105 files -> 0

mobile/tests-typecheck-baseline.txt grandfathered 105 test files (531
errors) whose types CI never checked. Contract changes had landed without
these tests following, and type pins in them silently checked nothing.

- Root cause: salvagedOptional (src/shared/zod-salvage.ts) cast away
  zod's optional marker, so every reply type built on it claimed
  salvaged fields were always present. Return a real ZodOptional;
  runtime is unchanged (the outer optional short-circuits undefined).
- Production now takes the port it uses: RpcOperationSender instead of
  RpcClient for send-only callers, a narrow fetch signature, and only the
  request fields push-receive reads.
- findAllByHostType/findByHostType replace `'Text' as never` lookups;
  stubRpcClient gives tests a typed RpcClient.
- Real test bugs: settings-host-client-lifecycle "relay" hosts were
  direct hosts (relayHostId no longer exists); two toEqualTypeOf pins
  could never hold; a recovery hook ran with an undefined scope key;
  a create-PR test cast to a never-imported type; "no URL" assertions
  passed on null; plus stale required props, args and enum values.

* test(e2e): parse workerStart result instead of casting it

* test(runtime): typed partial runtime stores with production-shaped fixture data

Route every partial store passed to OrcaRuntimeService through
partialRuntimeStore with typed row builders, removing 60 cast directives
that hid fixture data production never produces:
- paired-client-navigation-test-harness keyed setWorktreeMeta writes by
  `[object Object]` (it took an id where the store takes a target), so
  reads never saw them;
- invalid worktree lineage origin/capture and incomplete workspace lineage;
- getWorkspaceSession returning null where the store returns the default
  session; getGitHubCache returning undefined;
- orcad migration states missing migrationId/manifest/receipt, with a
  toEqual pinned to that incomplete shape;
- partial repos, metadata, folders, project groups and notification rows.

* refactor(renderer): resolve suppressed React hook lint instead of disabling it

109 of 187 react-hooks/react-doctor suppressions fixed:
- ~95 exhaustive-deps disables only hid stable refs and setters passed
  through controller objects; list them (identity never changes, so
  nothing re-runs), plus a few real stale closures (tabId/worktreeId).
- Effects keyed on one value that read the latest props now use
  useEffectEvent (WebConnect, skill freshness, Bitbucket dialog seeding,
  Landing preflight, automation catalog, structured-session recovery,
  file explorer).
- The conditional layout-owner hook is selected once at module load from
  the build constant instead of a rules-of-hooks disable that also hid
  the whole controller from compiler and react-doctor rules.
- A hook disable was masking a react/purity Date.now() in the palette's
  recent-tabs memo; sample it when the snapshot is captured.
- Three identical debounced-search effects share
  useTaskSearchDebouncedApply; layout snapshot merge helpers move out to
  stay under max-lines.
Remaining suppressions are mount-once resources, invalidation epochs,
deliberately keyed fields, and test harnesses that mock the dispatcher.

* chore(ratchet): exempt test harnesses and fixtures from the focus-read ratchet

The ratchet skipped *.test-fixture.ts but scanned *-test-harness,
*-test-fixture(s) and *.test-support files. Those seed settings with
getDefaultSettings (which the ratchet discovers as a focus reader) and
never route host work, so 17 baseline entries were false positives, and
replacing a test's `settings: {...} as never` with typed defaults tripped
it. Match the repo's test-support names and prune (which also drops one
stale entry), and rename the frame-ordering harness to *-test-harness like
its siblings. A blanket "-harness" match would also exempt
e2e-terminal-pty-harness, which production imports, so the names stay
explicit.

* test: merge duplicate shared/constants imports

* revert(file-explorer): restore original tree load effects pending SSH e2e investigation

* test(runtime): drop RuntimeStore cast now that the fixture is typed

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 19:37:19 -07:00
Neil 219ad610a4 fix(terminal): keep keys typed into a starting agent pane as an unsubmitted draft (#33315)
* fix(terminal): keep keys typed into a starting agent pane as an unsubmitted draft

* fix(terminal): keys typed after the bind always go live; never paste over a driven screen

* test(terminal): a deferred split with late startup work drops its held keys

* fix(terminal): capture only before the first bind; drop drafts on attach or reattach binds

* fix(terminal): leave paired-server panes' type-ahead to their own transport
2026-10-24 19:35:48 -07:00
OrcaWinandOrcaWin 886ac45c67 test: remove duplicate checks and repair weak fixtures (#33353)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 19:14:30 -07:00
Neilandggbdpq 456c7bf1f7 fix(runtime): deliver Devin launch prompts via argv instead of stdin-after-start (#33349)
Devin launch prompts are delivered as argv (`devin [flags] -- '<prompt>'`, Devin's documented interactive-prompt form) instead of typed after start, where they were lost before Devin was ready. Fixes #26302. Supersedes #26387.

Co-authored-by: ggbdpq <67929842+ggbdpq@users.noreply.github.com>
2026-10-24 19:06:04 -07:00
Pr1p a289c98f24 fix(terminal): preserve OpenCode Ctrl+Enter on Windows (#33149)
OpenCode Ctrl+Enter sends CSI-u on local Windows ConPTY so it inserts a newline instead of submitting (as on other platforms). Fixes #25372.
2026-10-24 18:59:57 -07:00
Neil 471b13a995 test(terminal): load the alt-screen chain's host graph at collection (#33343)
The suite loaded the main runtime graph in beforeAll; run beside the rest of
terminal-pane at six workers, that cold load passed the 60s hook default and
failed the suite before any case ran. Loading it at module scope, as other
terminal-pane suites do, takes it off any per-hook timer.
2026-10-24 18:52:44 -07:00
Neil db8fc6d0cc refactor: group agent-session conversation and message identity (#33324) 2026-10-24 18:43:40 -07:00
NeilandFrederic Barthelemy e199f9d412 fix(native-chat): commit Claude AskUserQuestion preview answers with Enter (#33332)
Claude AskUserQuestion with option previews: Orca's ask answers now send digit (focus wiggle for option 1 with a note), optional `n`+note, then Enter, since a digit only moves the highlight in Claude's preview layout. A bare digit on a preview question no longer clears waiting. Fixes #16865.

Co-authored-by: Frederic Barthelemy <209712+fbartho@users.noreply.github.com>
2026-10-24 18:31:44 -07:00
Neil 10ef68f01e fix(terminal): keep keys typed before a pane's terminal exists (#33281)
* fix(terminal): keep keys typed before a pane's PTY exists

* fix(terminal): hold pre-spawn keys only in panes with no startup work

* fix(terminal): no pre-spawn hold for live-entry resumes or main-started panes

* fix(terminal): keep the deferred-split hold exactly as before

* fix(terminal): drop held keys if a resume or startup work appears before the bind
2026-10-24 18:31:31 -07:00
OrcaWinandOrcaWin 8eea0c0d5b test: remove redundant cases and repair audit assertions (#33334)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 18:26:35 -07:00
Neil 537f561d58 Revert "fix(terminal): a file link opens in the workspace it was clicked in (#32320)" (#33304)
* Revert "fix(terminal): a file link opens in the workspace it was clicked in (#32320)"

This reverts commit 359fec1a09.

* test: drop redundant openFiles cast restored by the revert
2026-10-24 18:01:06 -07:00
Neilanddavidwis b5f9e06164 fix(editor): highlight Zig source and diffs (#32705)
* fix(editor): add bounded Zig syntax highlighting

Recognize .zig files and load the existing pinned Shiki Zig grammar through
the lazy TextMate provider. Map its scopes to stock Monaco theme categories
while preserving the shared tokenizer state and per-line bounds. Keep .zon
and formatting outside this lexical-only change.

Reuse the optional scope-mapping hook reviewed in Haskell PR #25411 and
its refreshed candidate 12908d0341,
retaining the original contribution credit from #25315. Ship the existing
grammar package MIT notice in renderer public assets for desktop and web.

Requested by @thinkAfCod in issue #11313. This addresses highlighting only;
it does not close the formatting portion of the issue title.

Co-authored-by: davidwis <davidwis000@gmail.com>

* fix(build): serve Zig grammar notices through allowed assets

Move the unchanged Shiki notices beneath assets/ and reference both files
with relative HTML metadata links. Preserve reverse-proxy prefixes and let
the existing projection and serving allowlists accept the browser client.
Do not expand either allowlist.

Exercise real Vite output, projection, manifest validation, and static HTTP
serving at root and /orca paths. Follow the relative-assets notice strategy
used by the coauthored Haskell adaptation and retain its contribution credit.

Co-authored-by: davidwis <davidwis000@gmail.com>

* test(editor): verify Zig source and diff highlighting

* chore(editor): drop Zig grammar notice assets

Zig grammar comes from the existing shiki dependency (already shipped via
syntax-highlighter's bundled-language loader), so no separate notice is needed.

---------

Co-authored-by: davidwis <davidwis000@gmail.com>
2026-10-24 17:48:38 -07:00
OrcaWinandOrcaWin e8a18a03d5 test: remove redundant cases and strengthen persistence, terminal and mobile checks (#33318)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 17:35:35 -07:00
Neil 584f2714b9 fix(terminal): keep Mac trackpad flicks continuous in fullscreen TUIs (#33313)
* fix(terminal): keep Mac trackpad flicks continuous in fullscreen TUIs

Chromium reports wheelDelta = -3 x deltaY for continuous devices, so a fast
trackpad event crossed the 100-unit 'notched wheel' threshold and switched to
the compressed, burst-boosted wheel curve mid-flick (2 -> 6 -> 2 reports per
event). Classify the gesture instead: an off-120-grid wheelDelta marks a
continuous device and the verdict sticks until the gesture goes idle.

* fix(terminal): end a trackpad gesture when a Mac wheel notch arrives

An on-grid event now continues the continuous gesture only with the trackpad's
3x wheelDelta shape and only shortly after off-grid input, so a notched wheel
used right after the trackpad keeps its discrete feel.

* fix(terminal): match wheel notches on the zoomed grid and require the trackpad ratio

Chromium divides both deltaY and wheelDelta by page zoom, so a notch reports
120/zoom; derive the grid from the UI zoom. An on-grid event now continues a
trackpad gesture only when 3 x |deltaY| is close to |wheelDelta|, so a
Windows/Linux notch (100 px per 120) right after trackpad input stays discrete.

* refactor(terminal): classify trackpad gestures without zoom or a notch grid

Keep the base rule (a small wheelDelta is continuous) and extend it across the
gesture: a large event within 300 ms of continuous input stays continuous only
while it keeps Chromium's continuous delta shape (wheelDelta about 3x deltaY on
macOS, 1x on Windows/Linux). Both deltas scale with zoom, so the shape check
needs no zoom factor; notches never match it.

* fix(terminal): only small wheel events extend the trackpad gesture window

A notch that happens to match the continuous delta ratio (40 px per 120 on
macOS) is now captured for at most 300 ms after trackpad input instead of
renewing the window indefinitely.

* fix(terminal): keep the whole trackpad gesture continuous through long momentum

Restore the approved rule where every continuous event extends the gesture
window, so a hard flick whose momentum stays above notch size for over 300 ms
keeps its 1:1 row distance. Pins that with a long-momentum fixture.
2026-10-24 17:33:16 -07:00
OrcaWinandOrcaWin ca3b0fdb02 test: remove redundant cases and strengthen state-transition assertions (#33309)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 17:05:58 -07:00
Neil ba43f8539c fix(runtime): a cold-restored terminal keeps its agent session without showing the old Done (STA-12043) (#33302)
* fix(runtime): a pane's new process does not wear its previous run's Done (STA-12043)

* fix(runtime): keep the superseded turn's segment and date process start at spawn request

* fix(runtime): take the identity row's segment from the turn clients were shown
2026-10-24 17:00:48 -07:00
Hoang Le QuocandNeil c580d7f2d3 fix(terminal): stop "104;255" leaking onto agent prompts after a tab switch (#31411)
A CSI scan now stops at ESC/CAN/SUB (as xterm's parser does), so a hidden-startup carry ending mid-CSI no longer swallows the next OSC's introducer and leaks `104;255` onto the prompt. Fixes #31410.

Co-authored-by: Neil <neil@stably.ai>
2026-10-24 16:59:59 -07:00
OrcaWinandOrcaWin 45bc63a187 test: strengthen persistence, session and failure-result assertions (#33303)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 16:40:41 -07:00
OrcaWinandOrcaWin 2479c5e20f test: consolidate redundant checks and verify behavioral boundaries (#33292)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 16:09:45 -07:00
Pr1p 04e07a6643 fix(opencode): prevent stale credential status after save (#33081)
OpenCode Go credential status: a late initial read can no longer overwrite a save/clear result, and pending/failed reads show Checking…/Status unavailable instead of Not saved. Fixes #33068.

Co-authored-by: Pr1p <48266347+Pr1p@users.noreply.github.com>
2026-10-24 16:08:47 -07:00
Neil 9c8ce8d818 refactor: group repository execution settings (#33261) 2026-10-24 15:46:51 -07:00
OrcaWinandOrcaWin c1a33b7372 test: assert persisted state and observable terminal and mobile behavior (#33282)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 15:30:18 -07:00
OrcaWinandOrcaWin 6b469405ec test: expose masked persistence and send-handler regressions (#33276)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 15:10:18 -07:00
Neil 2679464ead fix: let capable paired hosts plan composer terminal agent launches (#32192)
A workspace created from the composer on a paired host launched its terminal
agent with the desktop's command, arguments and environment. Hosts that
negotiate agent.launch.v2 now get startupAgent (and startupPrompt) and build
the launch through their own planner and settings. Older hosts, failed probes,
hosts that predate the agent's name, linked-item drafts and VM recipes keep the
desktop-built command. When the host planned the launch, the window never runs
the desktop plan or its own agent recovery, and says it couldn't confirm the
agent started if the host reported no agent terminal.
2026-10-24 15:01:29 -07:00
Neil c197b9f3f1 fix(new-workspace): search and offer Linear on the same host in Create worktree (#33270)
* fix(new-workspace): read Linear status on the host the search runs on

Create worktree searched Linear on the selected repo's host but offered the
Linear tab from the focused host's status. With Linear connected only on the
desktop and a project on a paired server, the tab appeared and every search
silently came back empty. The repo-derived Linear source now reads its own
host's status, as explicit sources already did, so the tab and the selected
workspace follow the host that will answer.

* fix(new-workspace): keep Linear status per host while it re-reads, and treat loading as unknown

The host status read is keyed by host, not project scope, and a same-host
re-read (repo switch, workspace change, reconnect) keeps the last status
instead of reading as disconnected, so the Linear tab and the chosen mode no
longer reset. While the first read is pending, a chosen Linear tab stays
selected and a pasted Linear URL keeps blocking Enter. The credential-error
test now stubs the repo host's status read it depends on.
2026-10-24 14:49:24 -07:00
Neil e2b0e9a19e fix(runtime): a host status publication keeps the probed capability readable (STA-11921) (#33263)
* fix(runtime): a status publication that answers a pending probe leaves the capability readable (STA-11921)

* fix(runtime): keep negative-capability re-probe across a published replacement; split the test

* refactor(runtime): one compatibility-entry factory keeps the cache under max-lines
2026-10-24 14:45:31 -07:00
OrcaWinandOrcaWin 621a09def5 test: repair masked assertions and remove eight low-value checks (#33268)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 14:43:09 -07:00
Neil 333be496a4 fix(ssh): Reconnect & Delete only deletes the workspace you selected (STA-11912) (#33253)
* fix(ssh): Reconnect & Delete stays pinned to the workspace the user selected (STA-11912)

* fix(ssh): say the workspace list changed and clear the shared delete state on a send-time refusal
2026-10-24 14:33:56 -07:00
NeilandBearMett 917899bf8d fix(runtime): stop paired desktops republishing mirrored editor tabs (#33259)
* fix(runtime): stop paired desktops republishing mirrored editor tabs

When two desktops pair both ways, B mirrored A's editor tabs and then
published them in its own session inventory as if B had opened them. A
then applied B's copy, which took over A's own tab.

isMobilePublishableOpenFile now skips rows marked
mirroredFromRuntimeSession, the marker is part of the open-files sync
projection so a flip republishes, and the marker is saved with the
session and restored so a relaunched client does not republish its
restored mirrors before the host's first snapshot.

Based on #25877 by BearMett.

Co-authored-by: BearMett <agomdole@gmail.com>

* fix(runtime): keep restored mirrors through unpublished frames and out of headless publication

A restored mirror now carries its marker, so an unpublished host frame
must not cull it (and its recovered draft). The windowless publication
skips persisted mirrored rows for the same reason the window does.

Co-authored-by: BearMett <agomdole@gmail.com>

---------

Co-authored-by: BearMett <agomdole@gmail.com>
2026-10-24 14:28:33 -07:00
Neilandethereal49 976fa11e81 fix(github): send a paired server its own repo id when an SSH row shares the path (#33257)
* fix(github): route runtime repo paths by execution host

When a repo path is registered on both SSH and a paired runtime, path-only lookup could send the SSH-side repo ID to the runtime. Prefer the row owned by the target runtime, then retain the original first-path fallback.

AI-Assisted: OpenAI Codex

Signed-off-by: ethereal49 <hongyeluo49@gmail.com>

* fix(github): resolve the runtime repo on the target host by the caller's repo id

getRuntimeRepoTarget now takes the caller's repo identity and resolves the
row through the repo lookup index, preferring the row on the target runtime
with that id, then the row on that runtime for the path. This keeps the
refresh sweep's repo reads linear (a per-call list scan broke that ratchet).
Legacy rows with no host stamp still fall back to id-or-path lookup.

Removes the test that pinned the off-host fallback; it asserted sending
another host's repo id to the server.

---------

Signed-off-by: ethereal49 <hongyeluo49@gmail.com>
Co-authored-by: ethereal49 <hongyeluo49@gmail.com>
2026-10-24 14:13:50 -07:00
OrcaWinandOrcaWin 5be204618a test: strengthen rejection and callback coverage, remove redundant checks (#33256)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 14:09:35 -07:00
OrcaWinandOrcaWin c90d0f93c0 test: exercise real mobile controller and repair weak assertions (#33248)
* test: exercise mobile controller and strengthen audit assertions

* test: use array syntax required by React Doctor

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 13:54:31 -07:00
OrcaWinandOrcaWin e802f4db7c test: repair behavioral coverage and remove export inventory (#33246)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-24 13:22:32 -07:00
Neil a1246ea166 refactor: colocate Task Page source availability hook (#33245) 2026-10-24 13:21:58 -07:00