Commit Graph
8392 Commits
Author SHA1 Message Date
1e22befe17 fix(sidebar): close the workspace rename editor opened by the shortcut (#13729)
* fix(sidebar): close the workspace rename editor opened by the shortcut

The workspace.rename shortcut opened the editor with setEditing, while
every other transition went through setEditingMode, which also mirrors the
flag into editingRef and guards on it. After a shortcut-opened edit the ref
still read false, so Escape, commit, and blur all returned early and the
editor stayed on screen until the card unmounted. The borderless sidebar
editor gives no sign it is still live, so the row looked like a finished
rename.

The editing element also took its React key from the display name and the
unread flag. Neither is an edit, but both moved the key, so React remounted
the input and the ref callback re-ran focus and select over a half-typed
name. That half was never shortcut-specific: the double-click and hovercard
editors lost typed text the same way.

Remove editingRef so the editing state is the only source of truth, route
both entry points through a single openRenameEditor, and keep the key on
the rendered title where remounting is how truncation gets measured again.

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

* fix(sidebar): guard rename editor transitions

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Jinwoo-H <Jinwoo-H@users.noreply.github.com>
2026-08-10 22:53:58 -07:00
Neil ee7e743813 perf(orchestration): skip redundant federation acknowledgments (#13671) 2026-08-10 22:51:33 -07:00
NeilandOrca 23c803a1a6 perf(renderer): scope batched open-file reconciliation by worktree (#13748)
Every snapshot in a batch scanned the whole openFiles array three times and did
a linear find per editor tab, so a reconnect paid for open files those snapshots
never touched. Bucket open files by worktree for the duration of a batch, skip
the global rebuild when a snapshot has nothing to drop or mirror, and retarget
the index at the array each snapshot produced.

Per-snapshot semantics are unchanged: openFiles still flows through each patch,
so the equality bail is still evaluated per snapshot against the current array.
An earlier draft deferred that bail to the end of the batch, which let the batch
keep pre-batch file objects that sequential reconciliation rebuilds; the two
regression tests here pin both cases.

1,200 workspaces, 3,000 unrelated open files: no workspace with editors
99.7ms -> 3.1ms, 5% with editors 105.3ms -> 7.7ms. Where every workspace has
editors the array genuinely changes each snapshot, so the rebuild remains
(113.9ms -> 84.2ms).

Co-authored-by: Orca <help@stably.ai>
2026-08-10 22:21:06 -07:00
NeilandOrca 1928ca501e perf(renderer): unmount closed setup guide content (#13546)
* perf(renderer): unmount closed setup guide content

* fix(renderer): keep setup-guide progress live through the close linger

Dropping shouldRefreshCoreState on close disabled skill discovery and
computer-use permission state while the dialog was still fading out, so
'Agent capabilities' visibly un-completed mid-animation. Mirrors the
paletteStatusInputsActive guard from the worktree palette.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-08-10 22:04:56 -07:00
Brennan Benson 93e08115d0 fix(native-chat): type Codex slash commands (#13685)
* fix(native-chat): type Codex slash commands

* fix(native-chat): keep Codex skill sends pasted
2026-08-10 22:02:46 -07:00
NeilandOrca 9f8c22c7f9 perf(renderer): unmount closed workspace cleanup content (#13567)
* perf(renderer): unmount closed workspace cleanup content

* fix(workspace-cleanup): restore unconditional delete-state clear on batch error

The session extraction swapped the batch-level onError handler from an
unconditional clearWorktreeDeleteState to the conditional queued-only
helper. When the batch driver dies, nothing settles those rows later, so
a hung 'deleting' row stayed stuck in the sidebar and was permanently
excluded from retry by filterWorkspaceCleanupRemovalCandidates.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-08-10 21:59:04 -07:00
NeilandOrca aa50d8cee3 fix(ssh): release the relay-loss watcher before teardown mux writes (#13737)
* fix(ssh): release the relay-loss watcher before teardown mux writes

Cancelling the in-flight port scan emits rpc.cancel on the control lane.
If that lane is saturated, enqueue admission fails and the writer calls
fail() -> mux.dispose('connection_lost'), which fires the relay-loss
watcher during our own teardown and schedules a redundant relay redeploy.

teardownProviders already released the watcher first, but stopPortScanning
runs ahead of it and is what emits the frame. Hoist the release into a
named method and call it before stopPortScanning on all four teardown
paths.

Co-authored-by: Orca <help@stably.ai>

* fix(ssh): hoist the watcher release above abort on every teardown path

Review follow-up. Two nits from the readiness pass:

- The "stop scanning before teardownProviders" comment had drifted onto
  releaseRelayLossWatcher(); move it back above the stopPortScanning()
  call it describes.
- Release the watcher ahead of abortController.abort() too. That signal
  reaches no mux request today, so this is not a live hole, but plumbing
  it into one would have silently reopened the bug on three paths. Making
  the release first keeps the invariant structural rather than incidental.

detachSshPtyConsumerRecovery stays first on the two detach paths, per the
existing synchronous-half-first rule.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-08-10 21:50:18 -07:00
Jinwoo Hong 25f7870c58 feat(github): support stacked pull requests (#13730) 2026-08-10 21:49:30 -07:00
NeilandOrca b44df2e9f1 perf(renderer): index GitHub resume lookups (#13698)
* perf(renderer): index GitHub resume lookups

* perf(renderer): skip the resume cache sweep publication when nothing changed

Every eviction helper already returns its input reference untouched when it
evicts nothing, so the opening sweep in refreshAllGitHub can compare identities
and return the previous state. Window resume then stops waking every store
subscriber on a no-op sweep.

Folds in the remaining unique optimization from #13711, which this PR
supersedes on the lookup-indexing side.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-08-10 21:42:27 -07:00
Neil 680a9d9bc5 perf(renderer): unmount closed Quick Open content (#13618) 2026-08-10 21:38:31 -07:00
Neil 2e5f067c2e perf(renderer): unmount closed Workspace Board content (#13619) 2026-08-10 21:33:50 -07:00
NeilandOrca 34c721fc2c perf(renderer): preserve unchanged remote mirror resources (#13683)
* perf(renderer): preserve unchanged remote mirror resources

* test(renderer): restore layout-value coverage and record the workspaceId dependency

Notes why browser page identity reuse is safe: browserPageEqual must keep
comparing workspaceId, since the removed-workspace page-list cleanup gates on
it. Also re-asserts the effective active leaf that the patch-only assertion
stopped covering.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-08-10 21:20:46 -07:00
OrcaWinandOrcaWin 9deb72f9ed fix(git): support Windows-linked worktrees in WSL projects (#13483)
* fix(git): support Windows-linked worktrees in WSL projects

* fix(git): harden WSL linked worktree routing

* fix(test): defer WSL routing filesystem access

* test(git): type WSL routing probe mock

* fix(git): retry transient WSL route probes safely

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-08-10 21:19:01 -07:00
Neil 2734bccd68 refactor(stats): share usage tracking pane shell (#13472) 2026-08-10 21:13:04 -07:00
Neil 4bb7e7d050 refactor(feature-wall): remove retired onboarding preview (#13489) 2026-08-10 21:07:41 -07:00
NeilandOrca a65e0c5c97 perf(renderer): keep remote snapshot batches linear (#13676)
* perf(renderer): keep remote snapshot batches linear

* test(renderer): cover the prefix-colliding sibling worktree

The sibling-mapping test used a worktree id that shares no prefix with WT,
so it passed against the prefix-scan it was meant to pin. Use an id prefixed
by WT's and drain the new mapping index in the leak counters.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-08-10 20:55:40 -07:00
Neil 0acf04a985 perf(ssh): cancel abandoned remote port scans (#13548) 2026-08-10 20:49:21 -07:00
Neil 5538584c74 perf(git): overlap status with conflict detection (#13529) 2026-08-10 20:48:00 -07:00
Neil e33863b2a9 refactor(onboarding): remove retired repository step (#13484) 2026-08-10 20:42:43 -07:00
Neil a944905451 refactor(onboarding): remove retired repository controller (#13492) 2026-08-10 20:42:12 -07:00
Neil 9796f7dc5f refactor(mobile): use shared GitHub Project sorting (#13459) 2026-08-10 20:41:34 -07:00
Neil a321ac3c8f refactor(mobile): use shared source-control decisions (#13453) 2026-08-10 20:41:31 -07:00
Neil e671c64dea refactor(utf8): centralize byte and chunk boundaries (#13445) 2026-08-10 20:41:01 -07:00
Neil af47fa10ac refactor(comments): share PR comment core (#13457) 2026-08-10 20:40:57 -07:00
Neil 6964f75cd0 refactor(renderer): share metadata list request lifecycle (#13524) 2026-08-10 20:40:26 -07:00
Neil 8c53e9e1b6 Share usage recent-session table (#13467) 2026-08-10 20:40:23 -07:00
Neil ef19809778 refactor(renderer): share usage provider slice lifecycle (#13527) 2026-08-10 20:39:51 -07:00
Neil fc9fd7208d refactor usage provider IPC plumbing (#13543) 2026-08-10 20:39:18 -07:00
Jinwoo Hong 665e0ead83 Fix repo-scoped Quick Commands across remote hosts (#13727) 2026-08-10 20:38:40 -07:00
Neil 65e2b5b598 refactor(usage): share provider store lifecycle (#13558) 2026-08-10 20:38:31 -07:00
Neil 556f469b0b refactor(mobile): remove orphaned PR composer (#13450) 2026-08-10 20:25:54 -07:00
Neil 75c6efd48b Remove obsolete pairing connection attempt (#13460) 2026-08-10 20:25:51 -07:00
Neil f9f8d7a8bf refactor(relay): remove obsolete status parser (#13475) 2026-08-10 20:25:48 -07:00
Neil bb6f0c1cb5 refactor(renderer): remove superseded GitHub background create (#13479) 2026-08-10 20:25:45 -07:00
Neil 34f46398d7 refactor(daemon): remove superseded PTY provider (#13477) 2026-08-10 20:25:43 -07:00
Neil f805189bff refactor(automations): remove unused Hermes output limits (#13497) 2026-08-10 20:25:39 -07:00
Neil 3203b0c405 refactor(onboarding): remove retired tour outcome tracker (#13498) 2026-08-10 20:25:36 -07:00
Neil 573eace89f refactor(persistence): remove unwired state bounds (#13499) 2026-08-10 20:25:33 -07:00
Neil d19f511786 refactor(reviews): remove retired queue foundation (#13500) 2026-08-10 20:25:30 -07:00
Neil ee8b9b2cc9 refactor(profiles): remove retired switcher UI (#13502) 2026-08-10 20:25:27 -07:00
Neil 01102536c6 refactor(daemon): remove obsolete production launcher (#13504) 2026-08-10 20:25:24 -07:00
Neil aa5e275026 refactor(sidebar): remove retired activity helpers (#13505) 2026-08-10 20:25:20 -07:00
Neil 1979f5a3e3 refactor(linear): remove replaced team combobox (#13506) 2026-08-10 20:25:16 -07:00
Neil 9359edc2b0 refactor(workspaces): remove replaced host combobox (#13507) 2026-08-10 20:25:13 -07:00
Neil 837ea3feec refactor(onboarding): remove retired capability checklist (#13509) 2026-08-10 20:25:09 -07:00
Neil d5c5322442 refactor(computer): remove orphaned helpers (#13511) 2026-08-10 20:25:06 -07:00
Neil a276e54e62 refactor(relay): remove unwired PTY replay index (#13518) 2026-08-10 20:25:03 -07:00
Neil a45adcfff0 refactor(emulator): remove unwired scrcpy control encoders (#13528) 2026-08-10 20:25:00 -07:00
Neil fb39308dfe refactor(daemon): remove abandoned binary framing (#13530) 2026-08-10 20:24:56 -07:00
Brennan Benson 3e3f48fe89 fix(native-chat): restore Codex model picker dispatch (#13669)
* fix(native-chat): restore Codex model picker dispatch

* fix(native-chat): type Codex effort picker command
2026-08-10 20:03:48 -07:00