Commit Graph
13470 Commits
Author SHA1 Message Date
Jinwoo Hong b154baf6d7 fix(relay): staging director deploys run as relay-dir with rehome identity, and can register one cell's cap (#27118)
Rebased onto main as one commit after its parent squash-merged.
2026-10-10 19:53:44 -04:00
OrcaWinandm4air 19f20c8b16 test(e2e): pass the catalog owner to the remaining fetchRepos callers (#27325)
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 16:49:47 -07:00
db2ed7ca36 perf(mac): name terminals in Orca instead of ps tty= (#27146)
Ask ps for raw terminal device numbers and name them in Orca: a verified direct lookup of /dev/ttys<minor> per distinct terminal, with an exact first-alias /dev scan fallback. Removes Apple ps's per-row /dev scan (~1 s CPU per capture on a busy Mac).

Fixes #24889

Co-authored-by: Giorgio Zamparelli <giorgio.zamparelli@gmail.com>
Co-authored-by: out-of-place <contact@outofplace.space>
2026-10-10 16:45:23 -07:00
Jinwoo Hong e9bf6d1c3f fix(relay): the cell switch tool changes only the named switches (#27056)
* fix(relay): the cell switch tool changes only the named switches and checks every key on read-back

A cell resets a key missing from its switch file to its default, so the tool now reads the
current object and changes only what --set names. The read-back compares every known key and
fails when the cell reports ignoredKeys.

* fix(relay): the cell switch tool refuses a switch the cell's image does not support

It reads supportedFlags from runtime-status (#27057). An image from before that field takes only
readinessLocal and ticketCheck off/shadow, so ticketCheck=enforce cannot void an old cell's object.

* fix(relay): the switch tool validates the whole object, refuses voided files, and records admitMode in Postgres

Every key and value of the object to be written is checked against what the image accepts (an
image without the list: only the keys it applies, ticketCheck off/shadow). A file the cell did
not apply is refused. admitMode=reserve needs a typed RESERVE <cell>; Postgres records reserve
before the file is written, and db only after the cell reports every control leased again.

* feat(relay): the switch tool knows reregisterInFlight (1-16), the flip-back pace

* fix(relay): the switch tool closes the cache gap before reserve, undoes a refused write, and has a break-glass db flip

After recording reserve in Postgres it waits past every director's 5 s cache and records it
again (re-running the open-flow check) before writing the file. A file write refused outright
(412 or 4xx) puts Postgres back to db; after a 5xx it stays reserve. An object the cell did not
apply is repaired when the new object passes the image check. Break glass (typed BREAK GLASS
<cell>) records db for a dead or unreachable reserve cell without its read-back.

* fix(relay): a director deploy refuses a traffic move across reserve-mode support while any cell is reserve

* fix(relay): the flip-back wait scales with the cell's controls and pace, and says how to finish

* fix(relay): the switch tool refuses to re-arm a tripped cell, breaks glass only on a silent one, and undoes reserve if the second post is refused

* feat(relay): director deploys set reserve placement, and refuse turning it off while any cell is reserve

* fix(relay): Terraform keeps the deploy-owned placement and shadow cells, and the deploy guard reads placement as built and refuses dropping a reserve cell from the shadow list

* fix(relay): director deploys take --admin-audience alone, name a drifted deploy identity, and carry the shadow seat-feed cells

Staging passes --admin-audience for the reserve guard without durable rehome
verification, which the parser refused. Only the generation and control
origin now travel together, and they still need the audience.

The guard decodes the caller from its token and refuses, by name, a revision
whose ORCA_RELAY_DEPLOY_SERVICE_ACCOUNT is another account, instead of
reading into a 401.

--shadow-seat-feed-cells (preserve, all, or a cell list) is a workflow input
on both director deploys; preserve keeps the serving value. A contract test
parses every workflow's real argv for both deploy scripts.

* fix(relay): the flag tool paces a flip back from the pool size the cell reports

An image from before the field falls back to the deployed sizes.
2026-10-10 19:41:47 -04:00
Jinwoo Hong 3c6c24f8fa test(relay): deterministic step-5 simulation with invariants 1-8 (#27040)
Rebased onto main as one commit after its parent squash-merged.
2026-10-10 19:41:33 -04:00
Jinwoo Hong 289586947e feat(relay): alert when a reserve-mode cell trips its dead-man (#27096)
Rebased onto main as one commit after its parent squash-merged; kept both sides of the add/add list conflicts with #27024.
2026-10-10 19:40:31 -04:00
Jinwoo HongandClaude a90e5d9de6 ci(e2e): run the layout oracle on PRs that change layout writers (#27103)
* ci(e2e): run the layout oracle on PRs that change layout writers

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

* ci(e2e): narrow the layout oracle triggers to the modules that write layout

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-10 19:28:50 -04:00
Neil 33a1ddfc26 ci(zcode): register native credential tests in the Windows lane 2026-10-10 16:24:14 -07:00
Neil 70f0b1adec ci(zcode): install the pinned test runner before native contracts 2026-10-10 16:24:14 -07:00
Neil 6de900fcc6 test(zcode): verify rollback with real Windows file permissions 2026-10-10 16:24:14 -07:00
Neil 1f6ab26ec6 fix(accounts): preserve competing keys during failed GLM saves 2026-10-10 16:24:14 -07:00
Luchong ae573a9063 fix(accounts): keep an identical plaintext key after a failed restore
A restored plaintext envelope can match the rejected replacement byte for
byte. Do not delete that file, since it is the previous key rather than a
new secret.
2026-10-10 16:24:14 -07:00
Luchong c33fa877d4 fix(accounts): remove a rejected GLM key when restore fails
A failed plaintext replacement can publish the new key before file
restriction is confirmed. If restoring the previous key fails before it
replaces that file, delete only the rejected envelope so a completed
restore is left intact.
2026-10-10 16:24:14 -07:00
Jinwoo Hong 9029e84883 feat(relay): log metric and console alert for unreadable cell switch files (evidence code) (#27024) 2026-10-10 19:22:21 -04:00
Jinwoo Hong a18883130f fix(relay): database sweeps and ops reads skip reserve-mode cells (step-5 census, inert) (#27046)
Rebased onto main as one commit after its parent squash-merged.
2026-10-10 19:22:11 -04:00
NeilandTauri-EPO a09dc9aa71 fix: honor inactive Claude account retry deadlines (#26936)
Automatic inactive Claude account refreshes now reuse each account’s existing retry deadline before sending requests. Healthy accounts keep refreshing, and manual forced refresh retains its current behavior.

Partially addresses #26588.

Co-authored-by: Tauri-EPO <enrico.pin@gmail.com>
2026-10-10 16:12:08 -07:00
Jinwoo Hong fda01facc2 feat(relay): the director that booked a join writes its row about a second later (off) (#27048)
Rebased onto main as one commit after its parent squash-merged.
2026-10-10 19:11:59 -04:00
Neil 04f8f2b5d8 feat(accounts): isolate ZCode sign-in terminal setup 2026-10-10 16:04:51 -07:00
Neil 7dfcef4e10 test(composer): reuse fixtures to restore the main lint gate 2026-10-10 16:04:08 -07:00
Neil 808c4ae9a6 test(zcode): verify read-only account contracts across platforms 2026-10-10 16:04:08 -07:00
Neil b9ea43ba9e test(accounts): keep quota fixtures consistent with saved state 2026-10-10 16:04:08 -07:00
87da8432cd fix(zcode): isolate read-only account discovery and quota ownership
Co-authored-by: Luchong <lu740528977@gmail.com>
Co-authored-by: GuanBear <guanbear@users.noreply.github.com>
2026-10-10 16:04:08 -07:00
Jinwoo Hong 3f7943c411 fix(relay): cells without a seat feed stay out of shadow coverage and switch state (#27058)
Rebased onto main as one commit after its parent squash-merged.
2026-10-10 18:54:30 -04:00
OrcaWinandm4air e7ee93e265 docs(rpc): a paired client runs commands as you; say so when pairing (#27317)
* docs(rpc): paired workspace access runs commands as the user; pairing dialogs say so

* docs(rpc): mobile is gated by its allowlist, not by tier

* docs(rpc): wrap comment

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 15:53:43 -07:00
Neil 68519e63b9 fix(composer): preserve explicit workspace names after selecting tasks (#26937)
Preserve names entered after selecting a work item in desktop, mobile and folder creation. Reuse the existing source and last-generated-name state, and avoid repeating source naming when a delayed base lookup finishes.

Verified the current-main merge composition: 70 focused tests and renderer typecheck pass; newer execution-host routing and folder launch checks remain intact. The reviewed PR head has no failed or pending CI checks and no unresolved review threads.
2026-10-10 15:32:21 -07:00
Neilandkambarakun eaf5dbed9e fix(cli): preserve alias recovery while guarding destructive suggestions (#26934)
Co-authored-by: kambarakun <kambarakun@gmail.com>
2026-10-10 15:16:18 -07:00
Neil 8ba353a1a7 [CI] Refresh unit timing weights and reduce repeated test setup (#27315) 2026-10-10 15:15:03 -07:00
OrcaWinandm4air 42be4c50d4 chore(settings): rename "Active Server" to "Default host for new projects" (#27286)
* chore(settings): rename "Active Server" to "Default host for new projects"

The setting (still activeRuntimeEnvironmentId) now only picks the host for new
projects with no source and the initial host of the Settings host picker, so
the copy says that. Refusal and help text say existing projects stay on their
own host, the provider-scope hints point at the Settings Host menu, and the
Remote Orca Servers search entry keeps "active server" as a keyword.

* fix(settings): credential hints point at the setting that still scopes them

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 15:01:12 -07:00
OrcaWinandm4air ddcbb78013 chore(lint): bypassing owner routing fails lint (#27313)
* chore(lint): delete the focus-routing helpers; bypassing owner routing fails lint

The last six renderer sites (Settings visibility defaults, preflight readiness,
Linear key dialog copy) mirror the default scope host and now say so through
defaultScopeHost. getActiveRuntimeTarget and settingsForRuntimeOwner are
deleted with their re-exports, the unused settings-fabrication helpers go with
them, and the owner-routing baseline is empty, so any new use fails lint. The
provider dispatch rationale is rewritten in neutral, shorter terms.

* test(preflight): keep the existing cast's rationale on the edited line

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 14:43:42 -07:00
OrcaWinandm4air e7d7c5bbeb refactor(worktrees): worktree create, listing, removal and repo hook/ref reads route by their owner (#27298)
* refactor(worktrees): worktree create, listing, removal and repo hook/ref reads route by their owner

Worktree create, prefetch, detected listings and missing-terminal teardown,
preserved-branch cleanup and removal follow the repo or workspace owner.
Repo hook and base-ref reads take the repo's host id instead of settings.
Composer, settings panes and the setup guide pass the selected repo's host.

* test(hooks): build the duplicate-row state without a cast

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 14:28:22 -07:00
Neil 26ee9bbfab [CI] Reduce repeated test setup and unnecessary packaging (#27308)
* [CI] Reduce repeated test setup and remove source text checks

* [CI] Consolidate transcript tests and preserve fixture-only CI routing

* [CI] Retarget reliability gate to consolidated transcript suite
2026-10-10 14:26:04 -07:00
OrcaWinandm4air 853c25de3e refactor(git): git calls route by the worktree's owner (#27291)
* refactor(git): git calls route by the worktree's owner

RuntimeGitContext carries the owner's transport (target) instead of a
settings object, so raw focus settings no longer compile at a git call.
Source control, the checks panel, diff loaders, fork sync, lineage,
worktree metadata, review push targets and diff-comment persistence derive
it from the repo or worktree rows (resolveOwner) or a captured owner.
Editor-slice remote actions take an explicit runtimeTarget and otherwise
resolve the worktree owner; an unresolved owner is refused, never sent to
the focused server. Generation preferences ride a separate prefs field.

* fix(work-items): one owner row routes direct-launch preflight, PR start point and create

* fix(review): PR dialog effects key on the host, not the target object

A fresh target literal per render re-ran base-ref discovery forever and ran the
test worker out of memory.

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 14:07:55 -07:00
Neil 0a73d1e093 [CI] Reduce repeated test setup and real CLI waits (#27297)
Combine related chat, worker-release, and filesystem tests while retaining their contracts. Replace fixed Codex terminal waits with observed readiness and hook completion. Keep runtime database contracts under Node.

Local measurements and all CI lifecycle costs are documented in PR #27297.
2026-10-10 13:09:48 -07:00
OrcaWinandm4air 4f03c23796 refactor(projects): repo, project group and folder catalog calls route by their owner (#27288)
Catalog fetches, path-status probes, project and group mutations, nested
scans and imports now take the owner's host explicitly instead of falling
back to the Active Server setting. A new project with no picked host still
goes to the default host, through defaultCreationHost.

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 12:58:09 -07:00
OrcaWinandm4air 81867c8ea0 refactor(sources): row-less sources and host-less surfaces name their host (#27290)
* refactor(sources): row-less sources and host-less surfaces name their host

Linear and Jira clients take a RowLessSource: a task-source context, an
explicit host, or defaultScopeSource(settings) when no Tasks source is
chosen, so raw settings no longer compile. defaultScopeHost joins
defaultCreationHost as the second sanctioned reader of the default-host
setting (both behind one private read, both ratchet seeds), and the status-bar
account switchers, settings navigation and the settings host picker's initial
default use it. Skill discovery routes by the owner id its install terminal
resolves, and the workspace-board Linear sync by the workspace owner.

* fix(lint): count the default scope source and assign-then-return readers

defaultScopeSource is a sanctioned read of the default host, so its call
sites count. A function that assigns a reader's result to a local and returns
that local is a reader too, which keeps the skill-discovery hook counted.

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 12:32:46 -07:00
OrcaWinandm4air ca1aac6af4 refactor(github): PR and work-item calls carry the repo owner's host (#27289)
getRuntimeRepoTarget takes the transport its caller already routed by
instead of reading the Active Server setting (with a raw focus default).
Work-item, comment, check and review-thread requests get it from
getGitHubSourceTarget (task source host, else the repo's owner); PR
lookups from the repo row; PR refreshes from the candidate's owner.
Hosted-review fetches route by hostedReviewRepoOwnerTarget. An unknown
repo stays on this computer instead of following the focused server.
Cache keys are unchanged. Deletes settingsForHostedReviewRepoOwner,
settingsForGitHubFocusedRepoOwner and getGitHubWorkItemSourceSettings.

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 12:14:05 -07:00
OrcaWinandm4air 572f178080 refactor(agents): agent, session and port calls route by their workspace owner (#27283)
Agent note sends, background agent and terminal launches, structured chat
reveal and activation, and the tab strip's Windows shell probe take their
transport from the workspace owner's environment instead of building
owner-shaped settings for getActiveRuntimeTarget. The automation observer and
the Codex selection lane read the owner from the PTY id alone, so an
ownerless remote id is never assigned the focused server. Local
advertised-URL events always rescan this computer, even when a server is
the default host.

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 12:02:01 -07:00
OrcaWinandm4air 314993c200 refactor(terminals): terminal input and inspection route by the PTY's owner (#27279)
* refactor(terminals): terminal input and inspection route by the PTY's owner

A remote PTY id already names the server that owns it. inspect, confirm,
send, verified send and the data subscription took settings only to fall
back to the focused server for an id without an owner segment, so an old
ownerless id could reach a server that does not own it. They now route by
the id alone: an ownerless remote id is never dialed and never confirmed
locally.

Dropping the parameter removes the settings plumbing the native chat,
agent draft paste and follow-up paths carried only for this, including the
raw focused-settings default in sendBracketedPasteToAgent, and deletes
getSettingsForAgentTabRuntimeOwner.

* test(e2e): native chat SSH delivery and remote completion follow the narrower terminal signatures

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 11:43:05 -07:00
OrcaWinandm4air 7de3710dbe refactor(files): file reads and edits route by the file's owner (#27278)
* refactor(files): file reads and edits route by the file's owner

The runtime file clients took a settings object and turned its Active Server
field into a connection, so any caller that passed raw settings silently read
or wrote on the focused server. They now take `target: RuntimeClientTarget`,
and every caller derives it from the owner: the tab's stamped owner, else its
worktree's owner (getRuntimeTargetForFileOwner / getRuntimeTargetForWorktreeOwner),
the file-explorer operation owner, or an already captured owner id.

Behavior: single-host (local-only) users see no change. An editor tab opened
without an owner stamp, a terminal link with no PTY owner, an OS file drop and
a notebook link now go to the workspace's owner instead of whichever server is
focused when the read happens.

Removes getEditorFileDropSettingsForWorktree and the native-chat settings clone
cache; settingsForWorktreeOperationRoute loses its editor caller.

* fix(files): file owner targets come from the rows, never the focused server

getRuntimeTargetForWorktreeOwner/getRuntimeTargetForFileOwner move to
lib/file-owner-runtime-target.ts and resolve through the focus-free
resolveOwner. A workspace with no row yet stays on this app (tabs and drops
stamp a server owner when one exists); rows that disagree return null, and
callers with an error path refuse via requireRuntimeTargetForFileOwner.

* test: keep the editor content-state fixture within the line limit

* fix(files): an unresolved document owner blocks local image reads

A null owner target became runtimeContext undefined, which image readers take
as a plain local file, so a server-owned document's images were read from this
machine. It is now runtimeContext null, the readers' do-not-load sentinel, in
the rich editor and the preview, and prewarm skips it.

* fix(files): read the image node view's storage through a named type

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 11:23:18 -07:00
OrcaWinandm4air 2eb6a920dd refactor(forge): forge reads and edits route by the repo's owner or the task source (#27276)
GitHub PR and issue dialogs, task-page cells, Project boards, slug metadata,
the repo slug index, hosted-review actions, GitLab MR base resolution and the
Settings API-budget panels now carry a RuntimeClientTarget derived from the
repo row, the row-less task source, the board row's cache key or the Settings
host scope, instead of settings-shaped objects resolved through
getActiveRuntimeTarget. A repo row with no owner stamp is local; an untracked
Project row edits on the host that loaded it.

Owner-routing ratchet 209 -> 165; focus-read ratchet 401 -> 352.

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 10:50:17 -07:00
OrcaWinandm4air 75dfd75460 refactor(runtime): owner transports, the creation default and a focus-read ratchet (#27275)
* refactor(runtime): owner transports, the creation default and a focus-read ratchet

Adds runtimeTargetForOwnerEnvironment, runtimeTargetForOwnerHostId and
runtimeTargetForWorkspaceOwner so routed call sites can get a transport from
the resource's owner, and defaultCreationHost as the one sanctioned reader of
the Active Server setting for creation flows with no source row.

The owner-routing ratchet gains a second per-file counter for reads of the
setting (member reads, the focus-routing helpers and defaultCreationHost), so
swapping a helper for a direct read can no longer lower a count. Baseline rows
may carry a trailing note that survives --prune.

* chore(lint): pin defaultCreationHost's own read in the focus-read baseline

* fix(lint): the focus-read ratchet counts shared focus helpers and destructuring reads

* fix(lint): discover functions that read the default host instead of hand-listing them

A hand list let a look-alike such as getAutomationListTarget replace
getActiveRuntimeTarget and lower both ratchets. Every exported top-level
function whose body reads the setting or calls a seed helper now counts as a
reader, and nested destructuring reads count too.

* fix(lint): readers are found through imports and returned values

Readers are keyed by defining file and resolved through imports and
re-exports, so a same-named function elsewhere is not mistaken for one, and
a function that returns a reader's result (a wrapper of a wrapper) is found
too. Components are not readers, and a declaration ends at the next
top-level statement.

* fix(lint): a reader called through a namespace or dynamic import still counts

* fix(lint): renamed, parenthesized and .then() dynamic imports bind readers too

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 10:27:37 -07:00
OrcaWinandm4air 5c7c493042 fix(sources): GitHub Projects boards read from the task page's source host (#27270)
* fix(sources): GitHub Projects boards read from the task page's source host

The Projects board, its project picker and unmatched-row edits picked their
host from the Active Server setting on their own, while the Tasks header
named the selected repositories' hosts. The board now takes the same
row-less source host that Linear and Jira use, converted through
getTaskSourceRuntimeSettings, and the header names that host in Projects
mode. fetchProjectViewTable takes the source explicitly instead of reading
settings. The ownership table marks the four board-level GitHub Projects
reads as scope-picked.

* fix(github-projects): an open unmatched-row dialog keeps writing to its row's host

The dialog took the board's live source, so a source change while it was
open sent its comment and field edits to a different host than the one the
row was loaded from. It now routes by the source encoded in its row's cache
key, like the row field edits already do.

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 09:17:11 -07:00
5b676777ba fix(web): the paired server is the web client's only host (#27266)
* fix(web): the paired server is the web client's only host

A paired web client is a browser tab with no PTYs, files, browser or
second window of its own, yet owners it read as "local" still routed to
it: setup terminals and server-local rows hit the local PTY stub, the
dashboard pop-out was a silent no-op, Open in Orca Browser threw an
uncaught error, and the macOS traffic-light inset was reserved.

Route a transport-less owner through the paired server at the shared
owner resolvers, open the in-window dashboard, refuse document previews
with a reason, and reserve no traffic-light inset in the web client.

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

* test(web): type the owner fixtures instead of casting

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

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
Co-authored-by: Claude <noreply@anthropic.com>
2026-10-10 08:57:47 -07:00
OrcaWinandm4air 865183cff9 feat(settings): host-owned settings panes choose their host explicitly (#27265)
* feat(settings): host-owned settings panes choose their host explicitly

Settings gets a Host menu (this computer or a saved server). Provider
accounts, agent detection and terminal capabilities follow it instead of
the Active Server setting, which is only the menu's starting value. A
server that is no longer saved reads unavailable and never falls back to
another host. The provider-account client now takes the owner target
instead of settings.

* chore(i18n): regenerate runtime-required English catalog

* fix(accounts): Codex restart notices follow the host the switch wrote

A Settings account switch on the chosen host flagged panes on the focused
host instead. markLiveCodexSessionsForRestart and its lane matcher now take
the owner target explicitly; Settings passes the picker's host, the status
bar its focused target, and local sign-in this computer.

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 08:47:25 -07:00
OrcaWinandm4air ba1474f960 feat(hosts): Resource Manager lists the owning host's processes (#27263)
While the Resource Manager is open, each paired server that hosts one of this
client's projects is asked for its own process samples through the existing
diagnostics.memory method, and those rows render under the server's projects,
named by host and without a kill control. A server that cannot answer is named
as unknown instead of looking idle.

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 08:09:00 -07:00
ec1a01a4bf fix(accounts): a server's late account result stays with that server (#27262)
* fix(accounts): a server's late account result stays with that server

The Accounts pane kept one roster across default-runtime changes, so a
select or remove still in flight on the previous server overwrote the new
owner's roster when it returned. Key the pane by its account owner so
rosters, account ids and in-flight results are scoped to one owner.

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

* fix(accounts): drop a stale owner's result instead of remounting the pane

Remounting lost an in-progress local login's spinner and Cancel button and
hid an account added after returning to the same owner. Guard each action's
result by the owner it was sent to instead.

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

* fix(accounts): keep the stale-owner check on the roster write only

The toast, settings refresh and restart prompt describe what happened on
the owner the action went to; only the roster belongs to the shown owner.

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

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
Co-authored-by: Claude <noreply@anthropic.com>
2026-10-10 08:07:51 -07:00
OrcaWinandm4air 6cbbe456c0 fix(hosts): agent launch platform and shell come from the execution host (#27259)
* fix(hosts): agent launch platform and shell come from the execution host

Agent startup commands were quoted for this client's OS (and its Windows shell
setting) whenever the workspace's repo row had no SSH connection, so a Windows
client driving a Linux Orca server sent PowerShell to bash. SSH hosts were
guessed from path shape.

One resolver now reads the OS from the host that runs the agent: the server's
reported hostPlatform, the relay-reported SSH remotePlatform (nested SSH read
through its server), WSL as linux, and this client only for local workspaces.
A missing fact withholds the launch with a reason. Plain-SSH mode now
publishes the OS the runtime ladder detected.

* fix(hosts): new-tab and background launches read the worktree's own host

Review follow-up: the new-tab resolver reads folder workspace paths (WSL folders),
a caller's platform only refines a local launch, background launches resolve the
worktree's host (nested SSH) and drop this client's shell setting for remote hosts.

* fix(hosts): background launches on an SSH worktree keep the relay CLI name

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 07:45:38 -07:00
OrcaWinandm4air af80ba3652 fix(skills): say an SSH repo was not scanned instead of dropping it silently (#27261)
Discovery skipped every SSH-backed repo without a trace, so the Skills page
counted only local folders and never said a repo was left out. Each skipped
SSH repo now appears as a source with skippedReason 'remote-repo', which the
Skills folder list already renders as 'Remote repo - not scanned'.

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 07:44:09 -07:00
Neil 83db5b5ec1 [CI] Reduce test teardown waits and duplicate CI setup (#27253)
* [CI] Reduce test teardown waits and duplicate CI setup

* [CI] Map browser ownership to the combined test check
2026-10-10 07:30:43 -07:00
OrcaWinandm4air 291549e83f fix(ports): the ports panel scans and stops on the workspace's own host (#27258)
* fix(ports): the ports panel scans and stops on the workspace's own host

The panel now picks its host from the workspace owner instead of the repo's
connectionId and the Active Server. A direct SSH or recipe VM workspace uses the
SSH view for its own target; an SSH target behind a paired server is scanned by
that server through workspacePorts.scanHost (workspace-ports.host-scoped.v1),
and Stop goes through killHost with the host the row was scanned on. An older
server is never asked and the panel says to update it; an unknown owner says so
instead of scanning another host.

* fix(ports): scan recipe VMs through this app's runtime so an unreachable VM reads as unavailable

Recipe VM targets publish no connection state to the renderer, so the SSH view
cannot tell a reachable VM from one whose relay is reconnecting. Route them
through workspacePorts.scanHost on this app's own runtime, which reports a
missing relay as unavailable, and keep the SSH view for user SSH targets.

* fix(ports): keep the host-scoped panel's host stable without a render-time ref

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-10 07:24:36 -07:00