Commit Graph
13398 Commits
Author SHA1 Message Date
Neil 991fd5ca4b Keep folder Git upgrades responsive and recheck project ownership (#26791)
* Keep repository detection off the main IPC thread

Share repository discovery decisions across synchronous compatibility callers and the existing asynchronous Git runner. Await discovery in project registration, nested imports, and folder upgrades, and recheck folder ownership after discovery completes.

* Make repository detection fixtures work on native Windows

* Await asynchronous Git checks in folder upgrade fixtures

* Prevent duplicate project registration after async discovery

* Check authoritative registration identity before renderer convergence

* Narrow repository responsiveness to detection and registration

* Keep one local project identity after concurrent registration

* Run registration SSH coverage in the existing Docker lane

* Keep folder upgrades responsive and recheck pending project ownership

* test(git): cover classifier failure stages and literal path identity

* test(git): use the current process host package

* test(repos): use current process host in folder upgrade fixture

* test(repos): use current process host in registration fixture
2026-10-10 02:02:16 -07:00
Neil 803ab30598 Await Git checks while discovering and importing nested projects (#26790)
* Keep repository detection off the main IPC thread

Share repository discovery decisions across synchronous compatibility callers and the existing asynchronous Git runner. Await discovery in project registration, nested imports, and folder upgrades, and recheck folder ownership after discovery completes.

* Make repository detection fixtures work on native Windows

* Await asynchronous Git checks in folder upgrade fixtures

* Prevent duplicate project registration after async discovery

* Check authoritative registration identity before renderer convergence

* Narrow repository responsiveness to detection and registration

* Keep one local project identity after concurrent registration

* Run registration SSH coverage in the existing Docker lane

* Await Git discovery when scanning and importing nested projects

* test(git): cover classifier failure stages and literal path identity

* test(git): use the current process host package

* test(repos): use current process host in registration fixture
2026-10-10 02:01:40 -07:00
Neil 4bdeff3ec3 chore: remove verified unused Orca code (#27175)
* chore: remove verified unused Orca code

* chore: remove translations orphaned by dead code cleanup
2026-10-10 02:01:24 -07:00
Neil b63d39ebe5 Keep repository detection off the main registration thread (#26760)
* Keep repository detection off the main IPC thread

Share repository discovery decisions across synchronous compatibility callers and the existing asynchronous Git runner. Await discovery in project registration, nested imports, and folder upgrades, and recheck folder ownership after discovery completes.

* Make repository detection fixtures work on native Windows

* Await asynchronous Git checks in folder upgrade fixtures

* Prevent duplicate project registration after async discovery

* Check authoritative registration identity before renderer convergence

* Narrow repository responsiveness to detection and registration

* Keep one local project identity after concurrent registration

* Run registration SSH coverage in the existing Docker lane

* test(git): cover classifier failure stages and literal path identity

* test(git): use the current process host package

* test(repos): use current process host in registration fixture
2026-10-10 02:00:15 -07:00
Brennan Benson d91921a9c6 Let a Grok chat list and stop the commands it left running in the background (#27022)
* Let a Grok chat list and stop the commands it left running in the background

A command Grok backgrounded (a dev server, a watcher, a monitor) showed only as a
transcript line: it never reached the background-tasks card above the composer, so
it could not be seen as running or stopped from Orca. Grok's subagents and Claude's
and Codex's background commands already list and stop there.

The ACP lane that publishes Grok's subagents as child records now also publishes
its background-task rows: a running task as a live background command or monitor,
an ended one as removed, derived from the rows the journal admitted. A Stop for one
of them goes through the same adapter route to Grok's own per-task kill
(x.ai/task/kill); Grok's completion notice ends the row, and a task Grok no longer
holds is removed at once. A refusal reports the task as not stopped; no answer or an
unreadable one leaves the outcome unknown.

Each Grok process is checked once at start with a no-target kill, beside the
existing subagent check. Only Grok naming the method unknown hides Stop.

* Settle a Grok task's transcript row when Stop finds it already gone

When Grok answered a Stop with already_exited or not_found, the card row was
removed out of band while the transcript row kept saying it was running, and a
later restated running notice could bring the card row back with Stop. The
answer now settles the transcript row through the translator, like the
subagent Stop, so the card row leaves because its row settled, the existing
no-relight rule keeps it gone, and a completion Grok still sends after
already_exited writes the real result. Also covers /clear being refused while
a Grok background command runs.
2026-10-10 01:59:04 -07:00
OrcaWinandm4air 180e8c186f feat(ports): host-scoped port scan and stop on the server (#27188)
* feat(ports): host-scoped port scan and stop on the server

Add workspacePorts.scanHost/killHost, addressed by workspace and resolved on the
server to the workspace's own execution host (this machine or one of its SSH
hosts). Stop is bound to the host its row was scanned on and is refused on SSH
hosts, where ownership cannot be proven. Advertised as
workspace-ports.host-scoped.v1.

* fix(ports): only this host's workspaces authorize Stop; a failed relay scan is not empty

Port ownership probes now come from host routing instead of the repo row's
connectionId, so an SSH repo that carries only executionHostId (or a runtime-
hosted repo) can no longer make a local listener look workspace-owned.

The relay's ports.detect now fails when it could not read the socket table
(unreadable /proc/net/tcp, or neither Windows scanner answering) instead of
answering an empty list, so a host scan reports unavailable rather than none.

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 01:27:49 -07:00
OrcaWinandm4air cbeb703490 feat(hosts): servers publish a host descriptor (#27193)
* feat(hosts): servers publish a host descriptor

A paired server now reports a stable installation id, created once per
profile, plus an optional machine binding (HMAC keyed by that id over
the machine id and profile path) in status.get and in runtime pairing
offers. Optional fields only: older clients ignore them and older hosts
omit them. Clients start using it in the follow-up.

* fix(hosts): serialize installation id creation so concurrent starts never fork it

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 01:26:26 -07:00
NeilandMatheus Breguêz b3aa719a57 Preserve Git history lanes through unrelated roots (#26932)
Preserve active graph lanes through unrelated root commits and share node/reference colors.

Isolate real-Git fixtures from inherited Git settings and use the existing public process-host import after the current-main package migration.

Co-authored-by: Matheus Breguêz <matbrgz@gmail.com>
2026-10-10 01:10:30 -07:00
cb69d52455 fix(repos): deleting a project with live terminals warns and needs --force (#27172)
* fix(repos): deleting a project with live terminals warns and needs --force

orca project setup-delete now refuses a repo-backed project that still has
terminals not known to have exited or saved workspace details, unless --force.
The sidebar remove dialog says how many open terminals will close.

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

* fix(repos): count a sibling host's host-qualified workspace metadata in the delete guard

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

* test(sidebar): cover the remove dialog's open-terminal warning

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

* test(sidebar): type the dialog mock state without assertions

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

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
Co-authored-by: Claude <noreply@anthropic.com>
2026-10-10 00:44:55 -07:00
NeilandYEONGUK LEE f4c4eaeece fix(i18n): correct Korean Finder menu label (#26866)
Use the approved Korean Finder wording and preserve it during locale regeneration.

Co-authored-by: YEONGUK LEE <contact@abruption.dev>
2026-10-10 00:34:58 -07:00
NeilandMatheus Breguêz e3bca6c5a8 fix(a11y): name Agent Dashboard column regions (#26865)
Name Agent Dashboard columns using their translated visible headings.

Co-authored-by: Matheus Breguêz <matbrgz@gmail.com>
2026-10-10 00:34:54 -07:00
OrcaWinandm4air b961442814 test(wire): give the preflight downgrade journey a non-Windows old host (#27177)
#27164 made an old host without a known non-Windows platform ask for an update
instead of answering its default list. The cross-version journey mocked the
capability probe but not the status read, so no request ever reached the wire.

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 00:32:53 -07:00
NeilandWooseong Kim c22f4b00f2 fix(agents): show DeepSeek icon for observed Build sessions (#26863)
Co-authored-by: Wooseong Kim <innocarpe@gmail.com>
2026-10-10 00:27:48 -07:00
Neilandkazu-42 f50b89b5f6 fix(linear): exclude label groups from assignable labels (#26861)
Co-authored-by: kazu-42 <91968271+kazu-42@users.noreply.github.com>
2026-10-10 00:26:36 -07:00
Neilandm4air 48528c0128 Fix roadmap crash with plugin language packs (#26860)
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 00:26:21 -07:00
f307391637 fix(pairing): pairing with this same Orca profile is refused (#27166)
Every add/re-pair path goes through the environment store; it now compares the
offer's public key with this profile's own runtime key before saving.

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
Co-authored-by: s546126 <s546126@users.noreply.github.com>
2026-10-09 23:46:14 -07:00
NeilandTooDeceptive 5462b5bd7a fix(browser): return JPEG bytes for JPEG viewport screenshots (#26856)
Co-authored-by: TooDeceptive <LegiTP@GMail.com>
2026-10-09 23:42:22 -07:00
Neilandggbdpq c857fcc578 Display valid multi-day automation schedules (#26850)
Co-authored-by: ggbdpq <ggbdpq@gmail.com>
2026-10-09 23:41:33 -07:00
OrcaWinandm4air 1a6d570412 fix(shell): OS open actions follow the file's owner, not the focused server (#27165)
* fix(shell): OS open actions follow the file's owner, not the focused server

Every shell open request (openPath, openInFileManager, openInExternalEditor,
openFilePath, openFileUri) now carries the path's owning host. Main allows
only a local owner, plus the SSH editor launch when the owner is that same
SSH target, and no longer consults the focused server. The renderer reveal
and Open-in checks drop their focused-server check to match.

* test(e2e): name the owner on the local editor control open

* fix(explorer): Open in follows the catalog owner for folder and host-only SSH workspaces

The explorer toolbar and the source-control Open in menu took their SSH
connection from the repo row, which a folder workspace or a host-only SSH
repo does not have, so the route read as local. Both now derive the route
from the catalog-confirmed owner.

* fix(sidebar): Open in keeps the SSH target of folder and host-only SSH rows

The row resolver now returns the SSH connection it resolved alongside the
runtime owner, so a folder workspace or host-only SSH repo with no repo
connection no longer reads as local.

---------

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-10-09 23:39:05 -07:00
OrcaWinandm4air 26e7a988b7 fix(pairing): advertise a key and fallback port the host can actually serve (#27158)
* fix(pairing): advertise the key and a fallback port the host can actually serve

* test(runtime): use a consistent keypair fixture now that the advertised key is derived

* fix(pairing): keep dev's pinned 6769 out of other instances' fallback ladder

---------

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-10-09 23:35:02 -07:00
Kelvin Amoaba f9829cd181 fix(native-chat): give each animation a reduced-motion state (#26276)
Spinners swap to a still hourglass instead of freezing; chevrons, the rail and popovers stop moving.
2026-10-09 23:33:31 -07:00
Jinwoo Hong 5493c5e815 feat(relay): directors place on reserve-mode cells from memory (off) (#27047)
Rebased onto main as one commit after its parent squash-merged.
2026-10-10 02:26:12 -04:00
OrcaWinandm4air e599ac4637 fix(relay): install the desktop Relay provider on demand (#27159)
* fix(relay): install the desktop Relay provider on demand

* fix(relay): suspend Relay installs across sign-out and bound the mint's install wait

---------

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-10-09 23:23:47 -07:00
OrcaWinandm4air 686f3de6bf fix(relay): read control-error in every state and pace repeated rate limits (#27160)
Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-10-09 23:23:43 -07:00
ebeafbd205 fix(agents): an old Windows or unknown-platform host asks to update instead of answering its default list (#27164)
* fix(agents): an old Windows or unknown-platform host asks to update instead of answering its default list

A host without preflight.workspace-scoped.v1 answers a workspace's agent
request with its own default list. On a Windows host that list misses a WSL
workspace's agents, and a host that does not report its platform may be
Windows. Only a known non-Windows host's default is still used; the others
record an empty list plus an update notice, shown in the quick-launch menu.

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

* fix(agents): decide the old-host fallback from a fresh status

Reading the platform from the shared capability cache could see a probe
another caller had just started (no status yet) and flag a Linux host. A
fresh status is race-free and also catches an in-place upgrade.

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

* test(agents): name the served host status for its role

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

---------

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
Co-authored-by: Claude <noreply@anthropic.com>
2026-10-09 23:21:39 -07:00
Jinwoo Hong abff7ab86a feat(relay): flip a reserve-mode cell back without disconnecting anyone (E-mix) (#27043)
Rebased onto main as one commit after its parent squash-merged.
2026-10-10 02:18:37 -04:00
Jinwoo Hong d488ce5bc0 feat(relay): cell reserve mode: book, admit and demote without the database (off) (#27041)
Rebased onto main as one commit after its parent squash-merged.
2026-10-10 02:11:01 -04:00
mmarabel c13745c478 fix(pi): name workflow child rows by their step key, not only the agent (#26909)
pi-subagents never sends a description, so every child row fell back to
the agent name and two children on one agent read the same. Workflow
children do carry workflowKey, a bounded slug, so use it as the label.

Fixes #26908
2026-10-09 23:08:22 -07:00
Jinwoo Hong 2f267889e8 feat(relay): step-5 reserve core: the cell's booking book and the director's placer (inert) (#27038)
Rebased onto main as one commit after its parent squash-merged.
2026-10-10 02:03:26 -04:00
OrcaWinandm4air 2b864272d4 test(tabs): mock the Copy icon the tab context menu now imports (#27162)
Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-10-09 23:03:08 -07:00
Jinwoo Hong 9c41d9e8d8 feat(relay): per-cell switches for the rejection fence and the lost-reply margin (#27057)
* feat(relay): per-cell switches for the rejection fence and the lost-reply margin, and report ignored keys

rejectionFence (default on) turns the unhandled-rejection fence off without a roll.
readTimeoutMarginMs (1-60 s) replaces the boot margin per query through pg's query_timeout.
The applied log line and flagsApplied name keys this image does not know.

* feat(relay): runtime-status names the switches and values this image accepts

The flag tool checks a write against it, so it can refuse ticketCheck=enforce (or any key)
on an image that would void or drop it.
2026-10-10 01:54:00 -04:00
OrcaWinandm4air df54bbb5ed fix(mobile): a new pairing scan supersedes a stale relay pairing journal (#27157)
* fix(mobile): a new pairing scan supersedes a stale relay pairing journal

* fix(mobile): a late recovery cannot overwrite a newer pairing; only a relay-hello 4401 abandons a journal

---------

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-10-09 22:47:08 -07:00
Jinwoo Hong 94b7936b8b fix(relay): a switch-file read cut off mid-body is asked for again (#27049)
The flag channel recorded a generation as seen before reading its body, so a
read that failed mid-body sent ifGenerationNotMatch for it on every later poll
and got 304 forever: that write was stranded until the object changed again.
The generation now counts as seen only once its body has been read and parsed.
2026-10-10 01:43:03 -04:00
OrcaWinandm4air 7a1d73576e fix(cli): orca file open and diff open name their owner (#27154)
* fix(cli): orca file open and diff open name their owner

The desktop's own catalog resolves the worktree for files.open/files.openDiff,
so the renderer notification now says so (null) instead of leaving the owner
unset, which let the focused server claim a tab the renderer could not place yet.

* fix(cli): keep a paired server's ownership on diff open

A catalog row stamped runtime:<env> names that server; null would route its diff through this desktop's git.

---------

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-10-09 22:42:34 -07:00
OrcaWinandm4air 1f5e8df421 fix(relay): wait through a scheduled reconnect and name why Relay is not ready (#27141)
* fix(relay): wait through a scheduled reconnect and name why Relay is not ready

* fix(relay): add the new mint-failure notice strings to the English catalog

---------

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-10-09 22:35:19 -07:00
Neil c527344685 fix(agent-hooks): throttle and background last-status.json writes (#26822)
The agent status recovery snapshot was rewritten whole, synchronously on the
main thread, after a 250 ms trailing debounce on almost every hook event
(about 53 new files a minute on the reporter's Windows machine).

- Leading-edge throttle: the first change after idle is written on the next
  turn; a stream gets at most one write per 5 s and cannot postpone it.
- Changes to persisted launch-token authority skip the window, since spool
  replay and restored-terminal attestation read them after a crash.
- Writes run off the event loop through the stats snapshot writer, now
  generalized as AtomicSnapshotWriter. Quit and hook-disable still flush
  synchronously; the file format is unchanged.

Fixes #26720
2026-10-09 22:33:10 -07:00
OrcaWinandm4air c0f18c2def refactor(shell): the local-open guard takes an owner, not settings (#27144)
isLocalPathOpenBlocked now takes the path's owning host (ExecutionHostId,
an ExecutionHostOwnerMatch, or 'unresolved') and allows only 'local'. The
settings parameter is gone, so every caller names its owner. Markdown link
callers resolve the document's host from the catalog instead of falling back
to the focused server; reveal keeps the focus check explicitly because the
main process still refuses reveals while a server is focused.

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-10-09 22:27:40 -07:00
Neil 915c4b74a2 Update Claude usage without rereading the whole conversation (#26967)
* Verify pinned transcript reads and stream Codex usage aggregation

* Resume Claude usage scans with compact token checkpoints

* Harden transcript snapshots and reject incomplete discovery

* Keep Codex race fixtures inside their temporary data home

* Verify pinned transcript rotation with portable file moves

* test: keep Claude usage mock registration in test suites

* Compress saved Claude usage without dropping history

* Keep Claude cache writes bound to their original request

* Register Claude contracts without conflicting with chat contracts

* Assert unchanged Claude sources skip the actual cache writer
2026-10-09 22:26:46 -07:00
OrcaWinandm4air 36d106a8bc fix(mobile-pairing): preselect LAN for a signed-out desktop (#27145)
* fix(mobile-pairing): preselect LAN for a signed-out desktop; sign-out clears the Relay region cache

* fix(mobile-pairing): give the changed Relay sign-in copy its own localization key

---------

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-10-09 22:23:10 -07:00
Neil 15717a4e53 Add CLI commands to manage and find workspace references (#26807)
* Add CLI commands to manage and find workspace references

* Fix reference review findings: source-context twins, legacy link collapse, closed chats, old-host errors

- Keep same-URL links with different source contexts separate; CLI add/remove no longer drops a twin
- Restore merging a bare legacy link into its single matching URL link (no duplicate PR rows, no resurrection on older-client removal)
- Carry absorbed data through collapse chains; resolve repoId conflicts deterministically
- Identity: ignore www., case-insensitive GitHub/GitLab/Gitea paths (stored URL keeps case), no Jira match on git hosts; find accepts self-hosted issue URLs
- reference find: skip closed native chats, require a session id for linked, include an explicitly named archived workspace, warm-cache fallback for --worktree
- Selector parity: collapse same-host duplicate paths, issue: ignores unlinked rows
- CLI: clear update-host error for hosts without reference.*, local flag checks before host probe, help text fixes

* Fix CI: add reference rm alias for verb policy; expect linkedItems in worktree ps summary

* Simplify reference CLI: share identifier/legacy-match helpers, drop redundant dedupe
2026-10-09 22:22:01 -07:00
fabricedgeandNeil 4b258b487b feat(tabs): copy stable tab references (#26881)
Add Copy Tab ID to terminal, editor and browser context menus.
Copy the clicked tab's existing workspace ID as "orcaTabId: <id>"
so agents can distinguish tab references from content IDs.

Keep inactive and pinned tabs identifiable without activating,
renaming or closing them. Reuse the native clipboard API and show
translated success or failure feedback after the write completes.

Cover clipboard failures, inactive and pinned tabs, separate editor
views, and browser content IDs that differ from workspace tab IDs.

Co-authored-by: Neil <neil@stably.ai>
2026-10-09 22:17:19 -07:00
OrcaWinandm4air 3822ad8b3a refactor(relay): share one retry schedule and identity key; extract the linger timer and pairing authorization (#27139)
Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-10-09 22:15:37 -07:00
Neil 71733ccc04 Speed up process-host import enforcement in CI (#27124)
Reduce import-scanner work by omitting unused AST parents and the duplicate traversal. Run the mandatory process-host import check alongside static work and explicitly join it before CI can succeed.

Update both workflow phase/enforcement contracts and migrate the newer benchmark to the public subprocess package API. Keep the original package build path, manifests, runtime, test selection, and shard count. Independent native review is clean; validation and timing evidence are in the PR.
2026-10-09 22:12:37 -07:00
OrcaWinandm4air 16e4d32978 fix(hosts): a server whose status answers is selectable while shared control connects (#27137)
A runtime host whose status probe verified is reachable even while its
shared-control socket is still connecting; the status owner already withdraws
that verification whenever a ready socket drops, so a status retained from a
previous socket still reads as connecting.

Fixes #10704

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-10-09 21:59:12 -07:00
Neil 8452fc3315 Keep tool results with the right command and reveal all results on mobile (#26968)
* Pair native chat tool results in linear time with provider identity

* Preserve orphan tool output and independent disclosure identity

* Keep mobile tool detail attached to its command after row changes

* Keep named mobile results open across copied history refreshes
2026-10-09 21:47:51 -07:00
OrcaWinandm4air a95006dc08 fix(persistence): a session write cannot bring back a tab its partition recorded as closed (#27125)
* fix(persistence): a session write cannot bring back a tab its partition recorded as closed

Main records every terminal close, but only PTY bindings and orphan
adoption honoured the record. A renderer save that still listed the tab
(when no topology revision fenced it yet), a relay write, or a fast
unified-tabs patch could write the closed tab back. Every full write and
unified-tabs patch now removes tabs the same partition has a live close
record for, scoped to the record's worktree. Rollback stays exempt.

* fix(persistence): the close fence accepts host slices that omit terminal maps

A host slice with no terminal rows omits tabsByWorktree, and the forced
close transform indexed it, so a browser-only save to a partition with a
live close record threw and never persisted. Close only tabs actually
listed, with the terminal maps supplied.

* refactor(persistence): the close fence reuses the shared tab-listing check

---------

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-10-09 21:38:20 -07:00
OrcaWinandm4air 7178c7ed47 fix(web): Jira reaches the server (#27136)
The web client had no Jira namespace, so every Jira call fell through to
the silent fallback and returned undefined. Forward each Jira method to the
server's jira.* RPCs, stream issue details, and warn once per namespace when
a call lands on the fallback.

Builds on #16803 by @JasonJarvan.

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-10-09 21:37:03 -07:00
9a6b5d8753 fix(web): usage and account switching come from the paired server (#27135)
The web client's usage and Claude/Codex account bridges were stubs, so the
status-bar usage bars never appeared and switching accounts did nothing.
Back them with the server's existing accounts.list / accounts.subscribe
snapshot (which already carries rate limits) and its select/remove RPCs.
Adding or re-signing accounts now fails with a reason instead of silently
returning an empty roster.

Harvests the approach and tests from #25133 by @gustavobragac.

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
Co-authored-by: gustavobragac <gustavobragac@users.noreply.github.com>
2026-10-09 21:36:28 -07:00
OrcaWinandm4air 274e2f2294 fix(terminal): closing a tab is never a silent no-op (#27132)
Clicking x did nothing when the worktree catalog had not hydrated yet or
the tab's group record was missing. The close now routes by the host the
tab's own PTY ids (or unified tab) name, and with no host at all still
prunes locally and reaches main's close record; per-PTY teardown already
fails closed for an unproven host. closeUnifiedTab closes a tab whose
group record is gone instead of returning null.

Fixes #11308

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-10-09 21:33:19 -07:00
OrcaWinandm4air 7bd3928159 fix(runtime): a terminal close commits in the session partition that holds the tab (#27119)
* fix(runtime): a terminal close commits in the session partition that holds the tab

One worktree's tabs can be split across the local and runtime:<id> saved
partitions. The host close searched only the routed partition, so a tab
in the other one was reported tab_not_found (or recorded nowhere useful)
and the next snapshot brought it back. The close now resolves every
partition that holds that exact tab id and commits there.

Fixes #18202

* fix(runtime): refuse a close when a second copy of the tab was rebound since it was asked

The owner fence checks only the first partition holding the tab, so a
second legacy copy rebound before admission was retired and its PTY
collected for kill. Owner-fenced closes now capture every holder and
refuse with terminal_pane_owner_changed when a later copy is new or
changed.

* fix(runtime): fence a close's second copies on snapshots, not live sessions

The binding writer mutates a session in place, so comparing a captured
session reference with the current one compared a replacement with
itself. Capture an immutable copy of each holder's row, bindings and
incarnations when the close is asked.

---------

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-10-09 21:20:11 -07:00