Commit Graph
22899 Commits
Author SHA1 Message Date
Neil ce321f0bb5 feat(open-external): Copy link split button on every sign-in, account, billing and GitHub browser hop
Every button that opens a URL in the external browser gets a chevron with
"Copy link" that copies the exact URL (minted the same way for lazy links),
for incognito windows or another browser profile.
2026-11-12 17:36:32 -08:00
Neil 00205419f8 fix(cloud): PAIRED-WAKE (1/2) a sleeping paired cloud workspace wakes when opened, on focus and on hover (#571)
* fix(cloud): PAIRED-WAKE (1/2) a sleeping paired cloud workspace wakes when opened (sidebar, Home), on focus and on hover, like an owned one

cloudWorkspaces:wake wakes a paired workspace's sandbox through the control plane (this desktop has
no VM record to resume) and reconnects its bound server at once. Opening its sidebar row wakes it
when asleep (waking overlay, failure card), and Home > Open wakes it before connecting to the saved
pairing. Predictive wake treats a sleeping paired workspace as a candidate with the same preflight
(fresh status + billing caps) and wakes it quietly (coordinator decision). Wake progress never adds
a paired row to the owned ids.

* fix(cloud): PAIRED-WAKE localize the not-paired message; test uses fixed timestamps

* fix(cloud): PAIRED-WAKE design-squad copy for the not-linked wake failure
2026-11-12 15:27:56 -08:00
Neil 433add6c42 fix(cloud): copy workspace link through the main-process clipboard (#573)
The W-number chip, Home's Copy link, the menu items and the copy-link
shortcut all went through navigator.clipboard.writeText after an awaited
control-plane lookup. Electron rejects that write once the document has
lost focus or user activation (always true from the menu or a shortcut),
so the copy failed with "Couldn't copy the link". Use
window.api.ui.writeClipboardText like every other renderer copy, make the
link lookup never reject (3s cap, sandbox-id link fallback for paired or
offline devices), and keep the error toast for real clipboard failures.

The chip tooltip now also says who the link is for.
2026-11-12 15:19:05 -08:00
Neil 09ed99034e fix(cloud): PAIRED-NO-ROW a paired cloud workspace keeps its sidebar row (P0 regression from #562) (#570)
* fix(cloud): PAIRED-NO-ROW a paired cloud workspace keeps its sidebar row (paired servers left out of team scoping)

Since #562 a paired "<name> (cloud)" server counts as Orca Cloud, so selectOrcaCloudHostScopeKey
scoped it by team. Its owner is never in cloudAccountIdByEnvironmentId (this desktop's own runtimes
only), so it landed in hiddenHostIds and every row and project of a paired workspace vanished, a
GitHub-only create included (n37 P-paired). Paired servers are left out of that scoping, as before
#562.

* test(cloud): PAIRED-NO-ROW typed repo literal
2026-11-12 15:05:52 -08:00
Neil 77efed3630 fix(cloud): PAIRED-STATUS one status path for paired cloud workspaces (#566)
* fix(cloud): PAIRED-STATUS one status path for paired cloud workspaces (main resolves a bound pairing; store registers paired rows)

getStatus/getArchive take { workspaceId, environmentId? }: main resolves this desktop's own runtime
first, else a paired server bound to a sandbox (findCloudSandbox), never an arbitrary sandbox.
The window registers each paired cloud workspace's own row (main checkout on a server the catalog
marks orcaCloudPaired) in the cloud workspace store's `paired` map, apart from the owned ids, so its
status lands in status[worktreeId] and every status surface reads it unchanged.

* fix(cloud): PAIRED-STATUS read worktrees through selectWorktreesByRepo (workspace-record ratchet)
2026-11-12 14:42:59 -08:00
Neil b7289bd34e Merge pull request #567 from nwparker/cloud/chat-cancel-error
fix(cloud): CHAT-CANCEL-ERROR held structured chats show no error cards; Cancel keeps the chat held
2026-11-12 14:38:42 -08:00
Neil 17d0405965 fix(cloud): CHAT-CANCEL-ERROR held structured chats show no launch/session error cards; Cancel keeps the chat held 2026-11-12 14:30:09 -08:00
Neil 06cb139a57 Merge pull request #561 from nwparker/cloud/v3-01b-structured-restore
fix(cloud): V3-01b a held structured chat keeps its hold across a restart; DUP-EXPIRED-STRIP
2026-11-12 14:29:52 -08:00
Neil 0fd98c5c2a fix(cloud): PAIRED-SLEEP sleep a paired cloud workspace's sandbox through the control plane; paired-from-birth rows are cloud rows from the catalog mark (#565)
Sleep on a paired cloud workspace's own row (no local VM record) now stops its sandbox via
cloudWorkspaces.sleep(sandboxId), so it stops billing; failures reuse the cloud sleep toast.
useIsCloudHostRow / isCloudPrimaryRowNow also read the runtime catalog's orcaCloudPaired mark,
so a GitHub-only create loses its "primary" badge and gets "Delete workspace…" and Sleep without
waiting for the pairing bindings to load.
2026-11-12 14:26:49 -08:00
Neil 0bab6a9c4c fix(cloud): PAIRED-CHROME paired rows get the cloud context menu (Copy workspace link, Delete alone, no Lineage/Project group) (#564) 2026-11-12 14:16:56 -08:00
Neil 1eb74abddf fix(cloud): NAME-DROPPED a GitHub-only cloud create keeps the typed name as the workspace title (#563) 2026-11-12 14:11:51 -08:00
Neil 511047b5fd fix(cloud): V3-01b an unread restored hold takes the account read once it lands (found in the real proof)
The proof's first restart showed "couldn't check your sign-in" on a chat whose
account read returned 'none' a moment later: a hold restored before the read
landed stayed 'unread'. The account watch now turns it into the read's answer
(isn't set up / expired / covered); it still never starts.
2026-11-12 14:07:08 -08:00
Neil d04cbb4da1 fix(cloud): PAIRED-AWARE (1/3) paired Orca Cloud servers count as Orca Cloud for every check (#562)
* fix(cloud): PAIRED-AWARE paired Orca Cloud servers count as Orca Cloud everywhere (catalog marks bound servers; shared check and sandbox map include them)

* fix(cloud): PAIRED-AWARE paired-server mark held in memory from bindings reads and writes (no sync fs on main); catalog republishes on change
2026-11-12 14:04:45 -08:00
Neil 585c163ae1 fix(cloud): V3-01b review: one hold per key from the moment it is asked for; joined marks only for restored holds; only the sign-in verdict gives way
- holdCloudAgentLaunch registers its outcome before awaiting the account read,
  so startup and the launch's retry asking at once share one hold (no orphaned
  hold, no hung launch). resumeChat leaves a hold the retry already owns.
- joinedSessions is marked only when the joined hold was put back at startup.
- useCloudHeldChatUnavailable hides only the not-signed-in verdict.
2026-11-12 13:37:44 -08:00
Neil 1c58febcf0 Merge pull request #560 from nwparker/lc2/cloud-primary-delete
fix(cloud): CLOUD-PRIMARY-DELETE a cloud workspace on its default branch is deletable (Delete workspace… destroys the sandbox)
2026-11-12 13:34:37 -08:00
Neil 42f62ba4ff Merge pull request #559 from nwparker/cloud/w6-setup-paste-focus
fix(cloud): SETUP-PASTE P0 strip code field paste never reaches the terminal
2026-11-12 13:28:27 -08:00
Neil 958de6c246 fix(cloud): V3-01b a held structured chat on Orca Cloud keeps its hold across a restart; DUP-EXPIRED-STRIP
- cloud-structured-held-launch-memory: one record per held structured chat
  (session, workspace, environment, agent), per Orca profile; never prompts
  or secrets; bounded, ages out.
- holdStructuredCloudLaunch remembers a chat while it holds and forgets it on
  settle; a chat with a record holds as restored (a failed or covered read
  waits as awaitingStart, never creates signed out); a launch joins a hold
  already placed for its key (joinCloudAgentHold) instead of holding twice.
  In-session launches are unchanged.
- cloud-held-launch-resume: at the host subscription, each held chat's hold is
  put back as soon as its tab is in the store, whatever becomes of its
  launch's retry (probes that throw leave the hold and strip up). If no retry
  joined it, Start retries the launch once and Cancel abandons it.
- While a chat is held on its cloud strip, the host's not-signed-in verdict is
  the strip's to explain (useCloudHeldChatUnavailable in the structured pane
  notices); unheld chats keep the generic notice.
- DUP-EXPIRED-STRIP: CloudRunningStripPortal yields to a tab-key hold too, so
  a host-published held strip never stacks with the running strip.
2026-11-12 13:21:32 -08:00
Neil ee2aad2740 test(cloud): SETUP-PASTE test doubles through one documented stub (no inline casts) 2026-11-12 13:19:45 -08:00
Neil b8ebb8afea fix(cloud): CLOUD-PRIMARY-DELETE a cloud workspace on its default branch (owned or paired) is deletable: Delete workspace… opens the cloud delete dialog and destroys the sandbox; no primary rule, no Remove Project, no primary badge 2026-11-12 13:18:57 -08:00
Neil 9a0c331dac fix(cloud): SETUP-PASTE P0 a paste into the cloud strip's code field stays in the field; the terminal never takes it (Cmd+V, app menu, paste event, right-click) 2026-11-12 13:14:49 -08:00
Neil 456ae5d4e5 Merge pull request #555 from nwparker/cloud/v3-01-held-restore
fix(cloud): V3-01 a held Orca Cloud launch survives a restart
2026-11-12 13:14:42 -08:00
Neil 20aea027f7 fix(cloud): an expired hold starts only on real coverage (account or key), never while the agent is paused or withdrawn
composer-redo's #555 note: cloudAgentHoldReason returns null for killSwitch and
unavailable, so the account watch started an expired hold while the agent was
paused or withdrawn. Proceed only when coverage is 'account' or 'key'.
Tests: kill switch keeps it held, a renewal then starts it; the in-session
cases move to their own describe.
2026-11-12 11:57:25 -08:00
Neil df079c08a9 Merge pull request #558 from nwparker/cloud/v3-08-signed-out-cloud-card
feat(landing): signed-out cloud workspaces sign-in card (V3-08)
2026-11-12 11:55:32 -08:00
Neil c072f6eae9 fix(cloud): an expired hold never auto-starts when its sign-in is removed rather than renewed (found in the V3-01 proof)
holdCloudAgentLaunch's account watch treated any change away from 'expired'
as a renewal, so removing the credential ('none' -> notSetUp) started the
agent with nothing covering it. Proceed only when the account now covers the
agent; a removed sign-in turns the hold into the one-time setup.
2026-11-12 11:53:32 -08:00
Neil 02a2204c16 test(cloud): V3-01 a failed sign-in read after restart waits as unread; card row agentNotStarted label/tone/rank 2026-11-12 11:47:47 -08:00
NeilandClaude 978da57505 copy(landing): session-ended card says why (V3-08 review)
Co-Authored-By: Claude <noreply@anthropic.com>
2026-11-12 11:47:14 -08:00
Neil 8b09b2ef02 Merge pull request #557 from nwparker/punchlist/v3-06-dup-names
fix(billing): V3-06b duplicate workspace titles get their W-number in Top workspaces
2026-11-12 11:46:58 -08:00
NeilandClaude 4a67fcdbde feat(landing): signed-out cloud workspaces sign-in card (V3-08)
In builds that offer Orca Cloud, when signed out (never, or the session
ended) with projects and no cloud list, Home shows a quiet 'Cloud
workspaces · Sign in to see your team's cloud workspaces' card where the
list would be. It stands in for the trial card while signed out. The base
landing (wordmark, no-project Home) is unchanged pending FR1.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-11-12 11:46:13 -08:00
Neil 7fbd6f9b61 copy(cloud): V3-01 awaiting-start composer hint is 'Start {{agent}} above to begin' 2026-11-12 11:45:13 -08:00
Neil 9e0af9c017 fix(cloud): V3-01 held mark imports cn from class-names 2026-11-12 11:41:09 -08:00
Neil a57aecc3f8 Merge pull request #544 from nwparker/cloud/entitlements-f
feat(cloud): ENTITLEMENTS-F Contact us uses the plan's supportUrl (fallback: Enterprise contact)
2026-11-12 11:34:57 -08:00
Neil bac96ce153 Merge pull request #534 from nwparker/cloud/entitlements-g
fix(cloud): ENTITLEMENTS-G grants start when the subscription is live (test-clock shadow diff); includes #529
2026-11-12 11:32:36 -08:00
Neil 61cfcfd984 fix(billing): V3-06b Top workspaces adds the W-number to workspaces that share a title 2026-11-12 11:31:36 -08:00
Neil 1089461b4d feat(cloud-auth): plain sign-in asks for auth's branded page (V3-04) (#550)
* feat(cloud-auth): plain sign-in asks for auth's branded page (V3-04)

Settings › Sign in to Orca opened the bare provider page while cloud setup opened the
branded page. A plain sign-in now sends signin_page=1, so auth (stablyai/orca-cloud#758)
shows the same shell with only its Account step. Servers that don't know the flag ignore
it.

* fix(cloud-auth): keep profile-cloud-service under 300 lines; no wall clock in the new test

* fix(cloud-auth): profile-cloud-service back to 300 lines

* refactor(cloud-auth): set the V3-04 sign-in flag in the PKCE flow, not the service

profile-cloud-service.ts sits at the 300-line cap; the plain-sign-in default
(signin_page=1) now lives where the authorize parameters are applied. Cloud setup still
passes its own parameters, which never include it. Tests at the PKCE level.
2026-11-12 11:29:11 -08:00
Neil b8d7df27cc fix(cloud): V3-01 review: awaitingStart reason (neutral), restored holds never auto-start, fixtures 2026-11-12 11:26:50 -08:00
Neil 7253d59f1f Merge pull request #552 from nwparker/punchlist/v3-06-top-workspaces
fix(billing): V3-06 Top workspaces show live workspaces by name
2026-11-12 11:23:56 -08:00
Neil f4746cee1b Merge pull request #554 from nwparker/cloud/v3-02-host-history-dedup
fix(cloud): V3-02 follow-up — divider back in place when the host restored pre-sleep history (no duplicate)
2026-11-12 11:19:49 -08:00
Neil c255fec664 fix(cloud): V3-02 follow-up: when the host restored pre-sleep history, re-insert the divider where it ends (no duplicate); merge against the host's whole image 2026-11-12 11:14:34 -08:00
Neil 06c9408634 Merge pull request #551 from nwparker/cloud/v3-02-restart-history
fix(cloud): V3-02 a woken cloud pane keeps its pre-sleep history across an app restart
2026-11-12 11:10:58 -08:00
Neil 0f59f74980 fix(cloud): V3-01 a held Orca Cloud launch survives a restart
The hold on a not-set-up/expired Claude or Codex launch lived only in memory
(cloud-agent-launch-hold) with the launch's args in a pending promise; a quit
dropped both and the placeholder came back as a plain shell: no strip, no key
mark, no way to start the agent.

- cloud-held-launch-memory: one record per held placeholder (environment,
  workspace, tab, agent, prompt, cwd, group), per Orca profile in localStorage;
  never env, command or secrets. Bounded (50) and aged out after 7 days.
- createWithCloudAgentHold remembers the placeholder; the hold's settle
  (settleHeldPlaceholder, shared) forgets it on Start, cancel or tab gone.
- cloud-held-launch-resume: when a host's session subscription opens, each
  record's hold is put back once its placeholder tab is in the store again
  (bounded wait; a tab that never returns is dropped and logged). A restored
  hold waits for the person's Start even if the account now covers the agent
  (holdCloudAgentLaunch restored: true): nothing launches unasked. Start
  launches the original agent and prompt and closes the placeholder.
2026-11-12 11:02:01 -08:00
Neil e29780b1fa fix(cloud-setup): the web setup names the Mac by its Computer Name (V3-09) (#549)
The setup page said 'Orca on m4airs MacBook Air': the desktop sent the hostname
with hyphens turned to spaces, which loses the apostrophe macOS drops from the
hostname. On macOS send scutil's ComputerName (the shared runtime lookup), exactly
as System Settings shows it; fall back to the cleaned hostname off macOS or if
scutil can't answer.
2026-11-12 11:01:58 -08:00
Neil 5a6cceca7d fix(billing): V3-06 Top workspaces names up to 5 live workspaces, then one deleted line, then others; billing sends the top 20 so deleted ones don't crowd out live ones 2026-11-12 11:01:01 -08:00
Neil 08b73a32ed test(cloud): V3-02 two sleeps before a restart keep both dividers, nothing doubled 2026-11-12 10:59:35 -08:00
Neil 913d973a01 fix(cloud): V3-02 a woken pane keeps its pre-sleep history across an app restart (merge at the wake divider) 2026-11-12 10:58:10 -08:00
Neil 154574c740 Merge pull request #548 from nwparker/cloud/structured-running-strip
feat(cloud): CHAT-BANNERS B2 running structured chat: sign-in expired · Renew, and a Renew-pointing 401 card
2026-11-12 10:55:15 -08:00
Neil 79bb08d97d feat(cloud): CHAT-BANNERS B2 a running structured chat on Orca Cloud shows sign-in expired · Renew, and its 401 card points at Renew
- RA-11's running strip on a structured chat (useCloudChatRunningStrip,
  mounted in CloudStructuredChatBanners): expired shows Renew; renewed only
  confirms ("Your next message uses it.") with a dismiss, no Restart - the
  chat's next message goes out with the renewed sign-in (the proxy swaps it in
  per request; live-checked). A held launch's strip wins.
- cloudRunningStrip: turnEndedFallback for structured chats (their status has
  no turnEndedAt; done-since dates the clean turn), terminal panes unchanged.
- On an Orca Cloud chat, the agent's not-signed-in card says "Renew it above,
  then send your message again." instead of the CLI login advice and its
  terminal Sign in button (private cloud-chat-sign-in-notice + a render-time
  hook in NativeChatNoticeRow; shared copy untouched).
2026-11-12 09:50:32 -08:00
Neil 2780e7cc53 Merge pull request #547 from nwparker/lc2/chat-zero-width
fix(tabs): CHAT-ZERO-WIDTH a new tab in a workspace whose layout outlived its groups becomes the layout
2026-11-12 09:41:16 -08:00
Neil 7a840b84ec fix(tabs): a new tab in a workspace whose layout outlived its groups becomes the layout (was invisible: empty strip, 0-size pane until a workspace switch) 2026-11-12 09:34:53 -08:00
Neil dda7d26a20 Merge pull request #546 from nwparker/cloud/strip-expired-fullstop
copy(cloud): held-expired strip detail ends with a full stop
2026-11-12 09:11:27 -08:00
Neil d268ec2e04 Merge pull request #545 from nwparker/cloud/structured-chat-gate
feat(cloud): CHAT-BANNERS PR-B structured chat on Orca Cloud holds its launch on the chat's strip
2026-11-12 09:05:07 -08:00