The root pnpm typecheck covers no cloud/ package and vitest strips types, so cloud
packages' own type errors went unseen (261 in sandbox-control). premerge-check.sh now
runs the own pnpm typecheck of every touched cloud/apps or cloud/packages package listed
in premerge-typecheck-packages.txt, after installing the cloud workspace and building its
packages. The list holds the 11 packages that are clean today; sandbox-control joins once
its errors are fixed.
* fix(cloud): Orca Cloud on a remote-server project whose GitHub repository it can't reach says so with More access, not the folder wording (UNREACHABLE-REPO-NO-ROUTE)
* fix(cloud): UNREACHABLE-REPO-NO-ROUTE design-squad: 'Give Orca access' link, muted (not red) precondition line, fixture
* test(cloud): OrcaCloudNeedsRepoSubmit fixtures press the footer's Create
* fix(cloud): UNREACHABLE-REPO-NO-ROUTE the Project field's ring is amber while Orca Cloud waits for a GitHub repository (design-squad); aria-invalid kept
* fix(cloud): UNREACHABLE-REPO-NO-ROUTE ring classes stay literal (localization audit), drop the unreferenced remoteServerDetail key
* fix(cloud): a refused create's row offers Retry and Dismiss, and a new create replaces it (REFUSED-CREATE-ROW-STICKY)
* fix(cloud): REFUSED-CREATE-ROW-STICKY a billing or limit refusal's cloud glyph is amber, a real failure stays red (design-squad)
* fix(cloud): a project cloned only on a remote server offers Orca Cloud in Run on and starts it from its GitHub repository (RUNON-NO-NEW-SANDBOX)
* fix(cloud): RUNON-NO-NEW-SANDBOX design-squad wording for an unreachable repository
The team-switch leave fired only for an owned workspace's host going from
the team's (+) to hidden (-); a paired one's host is ~ since #690, so the
main pane kept showing another team's workspace after the switch (n57).
It leaves for ~ to - too. The status bar's host list and count now drop
another team's cloud servers, the same scope as the sidebar (#722).
useCloudRecoveryContext counted only owned workspaces as cloud, so for a
paired one its asleep and waking states were unknown to the recovery
notices: the remote-server outage notice ('Reconnecting to ... (cloud)',
role=status, aria-live=polite) stayed up under the asleep view, where a
screen reader would announce it (n56 DOM dump). Paired rows count as cloud
there too, so the notice stays silent while asleep or waking.
Right after pairing, the server can answer the project and worktree reads
before it lists the workspace's own row; the row lands a moment later.
connectAndReveal looked once, found nothing, toasted 'is connected' and
returned, so the picker closed and nothing was selected (n48, n55). It now
waits a bounded 15 s for the row (the picker spinner and #710's Opening
toast cover the wait), then reveals it as before.
* fix(cloud): a Restart's own transport invalidate never shows 'This operation was aborted'; a stream mid-setup fails as recoverable and the pane resubscribes (RESTART-ABORT-BANNER)
* test(cloud): RESTART-ABORT-BANNER type the subscribe result as a promise
* test(cloud): RESTART-ABORT-BANNER no type assertions in the invalidate test
The waking overlay moved focus to itself when it mounted (~0.3 s into a
wake) unless the wake had failed, the type-through pill included: the
first key reached the terminal and was held, every later key went to the
overlay and was lost (n53: 'e' held, 22 lost). The pill now leaves focus
where it is while typing goes through. The reconnect banner was held while
waking or going to sleep but not once asleep; asleep holds it too.
- Make owner confirmation lists what happens (sleeps, share links stop, the
disk goes with it, shared mode for good), stays open while the workspace
goes to sleep, and shows a refusal in place.
- Whoever made the change is told whether the previous owner will see a notice.
- The previous owner gets a notice (until dismissed) advising them to rotate
personal secrets; the new owner is told once that it runs like a shared
workspace.
- "Owner changed" chip in the top bar and a line in the sidebar hover card.
- Audit log words Orca's "previous owner told" row, and a row cut short shows
its whole sentence on hover (AUDIT-TRUNC-HOVER).
Sleeping a paired cloud workspace on screen left for Home (n49/n51): the
asleep-view hold only knew owned workspaces, and the host's sleep stops the
workspace's terminals (or its chat), so its last tab closed and every
'emptied workspace' path landed on Home within half a second. The hold now
takes paired rows too, and the store's last-tab close, the emptied reaction
and the terminal tab close all stay on a workspace held asleep on screen.
The asleep view is the workspace's, not a tab's, so it covers a workspace
with no tab left (terminal-only and chat-only alike).
#692 began the typing hold at the press, but the 'waking' report (which
moves the paired surface from its asleep cover, inert over the pane, to
the type-through waking layer) still came after an awaited bindings read.
Keys typed in that first second hit the inert pane and were lost (n49:
2/2, n51: 1/2). The wake now reports waking at the press; a row whose
sandbox can't be found still ends with its not-linked card.
* fix(cloud): EP-4 a secret with no ending says why: too short, or only owners and admins see it (tooltip and screen-reader label)
* fix(cloud): EP-4 design-squad wording: 'last characters', 'Short values are fully hidden'
Main's paired unarchive reported waking (source unarchive) but never
ready on success. The control plane answers once the VM is up, so the
window's open found it running and started no wake of its own, and
nothing settled the event: the row stayed waking (Archive disabled) until
the overlay called it stalled ('stopped responding while waking'). Main
now reports ready when the paired unarchive succeeds, and the renderer
settles a still-pending unarchive wake from a fresh read that says ready.
An open could wait up to 120 s (a grant or wake timing out, or a workspace
created, slept or deleted on another device mid-open) with nothing on
screen, then drop the person on Home. While an open runs, a loading toast
appears after 3 s ('Opening {{name}}...'); a timeout is a warning with Try
again; a workspace the server no longer has (not_found) fails at once with
'Couldn't find {{name}}' and Show cloud workspaces. The picker's own row
spinner holds the toast back until the picker closes; a GitHub-only
create's pending row keeps its own progress. design-squad copy.
* fix(cloud): GRANT-ID-TRACKING pairing recovery tracks every grant it leaves behind (owned re-grants, failed binds) and retries transient failures twice, spaced out
* fix(cloud): GRANT-ID-TRACKING a grant for a different server is final; a failed tracking write keeps the grant tracked for this run (sso-scim review)
* fix(cloud): a member's Sleep on a teammate's shared workspace never hangs; Sleep shows who can (SHARED-MEMBER-SLEEP-HANG)
#690 registers a shared workspace's linked row as the paired workspace,
but the paired sleep target still required the main checkout, so a
member's Sleep skipped the sandbox silently and 'Saving copy...' never
cleared. The sleep target now follows the paired registry; every paired
target ends slept, still running or refused (the saving state always
clears). The control plane lets only the owner or a team admin sleep it:
a refusal is a warning toast saying so, and a member known not to be an
admin sees Sleep disabled with the reason (design-squad copy).
* test(cloud): refusal toast fixture waits for the Toaster and uses a full-size frame
* fix(cloud): lint (no cast in the registry mock; the menu item keeps its own spacing)
A paired workspace's going-to-sleep mark was cleared before its sandbox
slept through the control plane, and it has no local record that flips
to suspended, so while the connection dropped the pane showed
'Reconnecting... Down for N sec'. Paired ids now stay going to sleep until
their control-plane sleep and status re-read finish, and the reconnect
banner and outage notice hold while a sleep is in progress.