Commit Graph
2158 Commits
Author SHA1 Message Date
Neil 766e0b23b6 Merge remote-tracking branch 'private/cloud/integration' into cloud/read-snapshot-signed
# Conflicts:
#	cloud/apps/sandbox-control/image/vm-scripts.generated.ts
#	src/main/ipc/cloud-workspaces.ts
2026-11-10 23:20:55 -08:00
Neil 9ac48491aa chore(cloud): localization catalogs, no casts in tests, section menu button keeps its own styling 2026-11-10 20:11:33 -08:00
Neil 8f0da9a0c0 fix(cloud): design-squad notes for G13/G14 — W-number on hover, chip confirms in place, other-team copy, move announcements, phone Pin row 2026-11-10 19:56:39 -08:00
Neil 8f28913dba feat(cloud): W-numbers, org slug links, and pins/order/sections that sync across desktops and the phone (G13, G14) 2026-11-10 19:50:22 -08:00
Neil 47395617b2 Merge remote-tracking branch 'private/cloud/integration' into cloud/read-snapshot-signed
# Conflicts:
#	cloud/apps/sandbox-control/image/vm-scripts.generated.ts
2026-11-10 17:02:00 -08:00
Neil ac65f7cb09 merge integration 2026-11-10 06:57:44 -08:00
Neil 51ace4d05f feat(billing): one-time Orca Cloud trial (N11) and its desktop surfaces (T1)
Billing Worker:
- trials + trial_claims (migration 0005): 2 sandbox hours per new team, no card, no Stripe.
- POST /v1/billing/trial grants it (idempotent, any member); grantTrial/trialOffer exported for
  the setup session. offers.trial on GET entitlements only when this caller could still claim it.
- Abuse limits: once per team, Orca user, normalized verified email, GitHub user (token claim)
  and GitHub owner (POST /v1/internal/trial/github from the binding; a reused identity revokes),
  disposable-domain blocklist, 3 grants per IP per day. Keys stored as SHA-256 hashes.
- Entitlement trial {includedSeconds, usedSeconds, remainingSeconds, exhausted}; metered from
  usage_events, concurrency 1, never overage; trial_used_up (suspendRunning) / trial_unavailable.
- Any subscription ends the trial; unused trial hours lapse.
- e2e: trial path (grant, no Stripe customer, concurrency, metering to used up, once per user,
  plan ends it) with cleanup of the run's abuse keys.

Desktop: trial_used_up / trial_unavailable classify as 'plan'; copy in billing, phone and CLI;
"Trial" badge, TrialPlanSummary in Plan & billing and the plans page strip, account menu row
"Trial · {{count}} sandbox hours left" (Choose plan for owners/admins); billingClaimTrial IPC
and claimOrcaCloudTrial() for the composer.
2026-11-10 06:20:22 -08:00
Neil 86c1726454 fix(w8): DS-27 polish: share-link sign-in uses the centred state layout (Cloud, title, sentence, Sign in button); asleep host uses Cloud + hollow asleep dot instead of Moon (DS-38 parity) (#258) 2026-11-10 05:41:34 -08:00
Neil e6bb0a9a52 Merge remote-tracking branch 'private/cloud/integration' into cloud/read-snapshot-signed
# Conflicts:
#	cloud/apps/sandbox-control/image/vm-scripts.generated.ts
2026-11-10 05:34:29 -08:00
Neil 259b871992 fix(cloud): a phone whose saved host no longer matches re-pairs via a grant (no stuck 'signer changed') 2026-11-10 05:34:12 -08:00
Neil 19eaee7019 fix(w8): no-desktop Home explains Orca Cloud workspaces appear once a desktop is paired (#251)
* fix(w8): no-desktop Home says Orca Cloud workspaces show up once a desktop is paired (W9 finding; design-squad copy)

* test(w8): empty-state test without an any-typed renderer union
2026-11-10 05:17:01 -08:00
Neil 7b15ce7a12 copy(cloud): design-squad wording for unverified and signer-changed copies 2026-11-10 05:08:09 -08:00
Neil f41777d9d8 fix(cloud): no trust-anyway path; a grant re-pins a changed signer only after its E2EE pairing succeeds; serialized pin merges 2026-11-10 05:07:07 -08:00
Neil 32d6ada8bb fix(cloud): W10-1: the Orca Cloud agent picker says when it substitutes an agent; fixtures; mobile chip labels
- When the user's default or a local pick isn't on the Orca Cloud image, one muted line under the
  picker says so: '{{agent}} isn't available on Orca Cloud yet, so {{fallback}} is selected.' It
  goes away once the user picks an image agent.
- Fixtures (dark/light): closed with Orca Cloud, open with the six agents, open with two disabled,
  and the fallback line.
- Mobile chips are labelled with the catalog name plus ', selected' on the chosen one.
2026-11-10 05:01:58 -08:00
Neil 4ca180d5ae fix(w8): cloud-icon rule on the phone (paired desktop cloud rows, home label, nav glyph) (#245)
* fix(w8): cloud-icon rule on the phone: a paired desktop's Orca Cloud workspaces lead with the Cloud glyph + state dot (worktree.ps carries orcaCloud.status), home cloud rows read 'Cloud workspace, …', muted Cloud before the cloud workspace title

* fix(w8): cloud-icon review: glyph label merges into the row (no own focus stop), no filled ring behind the dot (pressed/active fills), newest VM record speaks for a workspace

* fix(w8): cloud-icon review 2: a cleaned-only workspace stays cloud (as on the desktop) with no dot, a live VM beats a cleaned one, cleanup_failed draws no forever-pulsing dot; store-order test

* test(w8): cloud-icon ps status test without a cast

* fix(w8): cloud-icon dot sits mostly outside the glyph's bottom-right (design-squad), clear of the title
2026-11-10 04:53:44 -08:00
Neil dd34314dc0 feat(billing): bill overage by the minute, put sandboxes to sleep at the cap (U22, U24)
- Overage stays $1.00 per sandbox hour (ORCA_CLOUD_OVERAGE_CENTS_PER_HOUR) and is now billed by
  the minute: a per-minute metered TEST price (unit_amount_decimal = rate / 60 to 12 decimals,
  transform_quantity divide_by 60, round up), created the same way by stripe-test-setup.ts.
  capSeconds rounds the cap down to whole minutes and spentCents mirrors the invoice, so the
  cap math matches Stripe. The meter still counts seconds.
- Opting in re-prices an overage item still on an older price (e.g. $0.75 / h) instead of adding
  a second item on the same meter, and removes any extra stale one.
- Alerts at 75%, 90% and 100% of included hours (warnAtPercent).
- New top-level entitlement.suspendRunning: payment grace expired, or at the limit (out of hours
  with overage off, or at the spend cap). The start check and usage answers carry it, so the
  control plane puts running sandboxes to sleep (snapshot kept, never deleted). Payment fields and
  /v1/internal/suspensions stay payment-only, so no data-retention clock starts at a cap.
- Copy (desktop billing panel, plan card, build sheet, phone, CLI): "billed by the minute" after
  the rate; at the limit "Running sandboxes go to sleep and new ones can't start. Nothing is
  deleted, and your files are safe."
2026-11-10 04:33:07 -08:00
Neil f0a6d9d550 feat(cloud): clients verify VM signatures and persist read-snapshot pins; wake-failed copy 2026-11-10 04:12:59 -08:00
Neil c12d99f08e fix(w8): DS-41 phone polish (grouped backdrop, amber contrast, access row labels) (#232)
* fix(w8): DS-41 phone polish: grey backdrop behind white groups in light, light amber at 3:1+, access rows read '{device}, last used {date}' with a 'Removes this phone's access' hint

* fix(w8): DS-41 review: white text on light amber badges (onStatusAmber, 5:1), grey backdrop only behind grouped lists (card screens keep white), 'connected {date}' label when a phone was never used
2026-11-10 04:05:52 -08:00
Neil 2d99d9b591 fix(w8): DS-28 new cloud workspace repo picker + idle-sleep line (#231)
* feat(w8): DS-28 new cloud workspace: pick the repository from this phone's recents and the team's projects ('Other repository…' for any other), and say 'Sleeps after N minutes idle' (new screen, empty Home)

* copy(w8): DS-28 with the picker, the note says 'Pick none for a blank project'

* fix(w8): DS-28 review: explicit 'No repository (blank project)' row, the field stays while typing an unlisted repo, choosing 'Other repository…' again keeps the text

* fix(w8): DS-28 nit: typing in the field selects 'Other repository…'
2026-11-10 04:03:15 -08:00
Neil a7989dfd1e fix(w8): DS-27 phone cloud states: sign in when not connected (returns to the link), 'Couldn't reach Orca Cloud' on errors, Not responding + owner Restart, Deleting, glossary-only headline, asleep cloud host gate (Wake), banner 'Try again'; state logic tested (#227) 2026-11-10 04:00:07 -08:00
Neil be26e2f832 copy(w8): DS-04 phone status reads "N sandbox hours so far. Uses sandbox hours while running." / "…Uses no sandbox hours while asleep." (no dollars) (#217) 2026-11-10 03:09:39 -08:00
Neil 49ce098274 Merge remote-tracking branch 'private/cloud/integration' into cloud/sleeping-read-snapshot
# Conflicts:
#	src/renderer/src/components/cloud-workspaces/CloudWorkspacesHome.fixture.tsx
#	src/renderer/src/i18n/locales/en.json
2026-11-10 02:39:02 -08:00
Neil 9dcda9941c chore(cloud): mobile switch exhaustiveness; extract the read-panel hook 2026-11-10 02:32:17 -08:00
Neil 6fb8497a1a Merge remote-tracking branch 'private/cloud/integration' into cloud/sleeping-read-snapshot
# Conflicts:
#	cloud/apps/sandbox-control/image/vm-scripts.generated.ts
#	mobile/src/cloud/cloud-control-plane-client.ts
#	mobile/src/i18n/en-runtime-required.json
#	mobile/src/i18n/locales/en.json
#	src/renderer/src/components/cloud-workspaces/CloudWorkspaceRow.tsx
#	src/renderer/src/components/cloud-workspaces/CloudWorkspacesHome.tsx
2026-11-10 02:21:17 -08:00
Neil 92142679a5 refactor(cloud): one classifyEntitlementDenial in src/shared/orca-billing.ts (DS-23); run-on access, build failure, build log, workspace errors and the phone keep their own wording 2026-11-10 02:17:30 -08:00
Neil d4653c15d3 feat(cloud): one overage constant (ORCA_CLOUD_OVERAGE_CENTS_PER_HOUR, $1) for billing and the control plane; workspaces show sandbox hours, not per-workspace dollars (desktop list, phone status) 2026-11-10 01:52:05 -08:00
Neil 7f4ff74bde Merge pull request #188 from nwparker/cloud/agents-picker
Orca Cloud agent pickers list only the agents the image ships
2026-11-10 01:28:09 -08:00
Neil ff12245a82 feat(cloud): one sandbox size (8 vCPU · 16 GB, 1×) — billing counts every size 1×, plans/usage/run-on/env/CLI/phone copy from ORCA_CLOUD_SANDBOX_SPEC, size pickers removed 2026-11-10 00:54:28 -08:00
Neil 0559156ce2 chore(cloud): read snapshot lint/quality gates (no casts, async key store, split parser, l10n) 2026-11-10 00:49:53 -08:00
Neil 3dd921f320 fix(cloud): W10 review of the read view: waking state, Wake to continue everywhere, plainer copy, agent display names 2026-11-10 00:42:30 -08:00
Neil f3510092e2 feat(cloud): Orca Cloud agent pickers list only the agents the image ships
Desktop composer with Orca Cloud selected: the picker is enabled and lists the
image agents (minus disabled ones) as terminal rows, defaulting to the user's
default when the image ships it, else claude; a local-only pick is repaired.
Phone cloud picker and composer read the same shared list and default.
2026-11-10 00:33:19 -08:00
Neil 691e428269 fix(cloud): rollback pin, reader-key revoke on sign-out, no re-register on not_sealed_for_key; read view polish 2026-11-10 00:27:19 -08:00
Neil 86aafd99c6 feat(cloud): read a sleeping workspace from an E2EE snapshot (desktop + phone clients) 2026-11-10 00:05:33 -08:00
Neil 4a1e476b38 fix(w8): long-wake note hands over to the plain note in place: no blink, announced once (iOS once; Android live region off after first) (#182) 2026-11-09 23:18:03 -08:00
Neil b6b6902f57 W8: reassure on the phone when a wake runs long (files are safe; queued prompt sends once awake) (#180)
* feat(w8): reassure after 10 s of waking (files are safe; a queued prompt sends once awake), under the steps with the timer still running

* fix(w8): wake-slow note: iOS-only announce, prompt sentence only while waking, whole-run reassurance from 20 s, fresh per run
2026-11-09 23:14:10 -08:00
Neil 850f1b8167 copy(mobile): W10 — registry-unreachable fallback without the parenthetical hedge 2026-11-09 20:16:18 -08:00
Neil 062747a768 copy(mobile): at-cap on wake names the owner's seat from the team registry (Alex is at their limit… / You're at your limit…); generic only when the owner is unknown 2026-11-09 20:14:58 -08:00
Neil 52f1ba7796 docs+copy(cloud): the per-seat running cap counts the workspace owner's seat; at-cap errors a teammate sees name the owner 2026-11-09 20:11:19 -08:00
Neil 6bc1fffc67 W8: teammates wake a team workspace from the phone (team-route wake; owner route not widened) (#155)
* feat(w8): teammates wake a team workspace from the phone (team route long-poll wake, same access/billing/cap; owner route stays the fallback)

* test(w8): team wake refuses an admin on a private row, never returns the endpoint; phone never falls back on 401/403
2026-11-09 19:59:10 -08:00
Neil 5e9fdffc41 W8: phone forgets cloud workspaces that are gone (confirmed by the registry), never on transient errors (#154)
* fix(w8): phone forgets cloud workspaces that are gone (missing from the complete registry list, or wake says not_found); never on transient errors

* fix(w8): prune only on the registry's own not_found for that workspace (lists are capped and skip hidden rows; status 404s are owner-only); restore a link whose host removal failed

* perf(w8): host prune is single-flight and remembers a confirmed-present workspace for 5 minutes
2026-11-09 19:52:06 -08:00
Neil 550a35c374 fix(mobile): subscribe to window focus/blur AppState events on Android only (iOS rejects them with a red screen in development) (#150) 2026-11-09 19:36:12 -08:00
Neil 5adc8fbf32 Merge pull request #142 from nwparker/cloud/w6-agent-firstrun
W6: agents work from the phone — pre-answer Claude/Codex first-run screens; Open terminal opens the terminal
2026-11-09 18:49:54 -08:00
Neil 0ac8bb1e79 Merge remote-tracking branch 'private/cloud/integration' into cloud-sync
# Conflicts:
#	src/renderer/src/lib/browser/navigation/remote-oauth-callback-relay.ts
2026-11-09 18:42:43 -08:00
Neil d98b730df9 fix(cloud): agents start working from the phone/API — Claude Code first-run screens and Codex trust/sandbox pre-answered in the sandbox, no self-update mid-session; 'Open terminal to sign in' opens the terminal (paneView rides with paneKey) 2026-11-09 18:42:25 -08:00
Neil cdaa328407 fix(w8): cloud row says "Created just now" (not "just now ago") and drops the repeated activity time (#139) 2026-11-09 18:27:00 -08:00
Neil e998a5ce96 W8 follow-ups: removal and role loss reach phones; role-aware plan-denial copy (#135)
* fix(w8): removing a member revokes their phones; role changes move phones too; a phone's stored role never re-syncs keys

* fix(w8): one removal path revokes keys, phones, grants and routines; stale desktop tokens can't re-sync roles or vouch phones; a grant revoked mid-issue stays revoked

* fix(w8): a removed member's unexpired desktop tokens stop working; changes count from auth's time; desktop re-mints and retries enroll on stale_token

* feat(w8): role-aware plan-denial copy on the phone (owners and admins get the fix, members who to ask)

* fix(w8): W10 copy (per-seat team limit, choose a plan) and FE review (3 s abortable role read, Android live region, more copy cases); no casts
2026-11-09 18:02:56 -08:00
Neil f7e5c8aae5 Merge stably/main into cloud/integration
# Conflicts:
#	src/renderer/src/components/native-chat-recovery/NativeChatResumeRuntimeModal.tsx
#	src/renderer/src/components/settings/page/settings-page-renderer.tsx
#	src/renderer/src/components/status-bar/NativeChatResumeStatusSegment.tsx
#	src/renderer/src/i18n/locales/en.json
2026-11-09 18:02:21 -08:00
Neil 9288e84d7a Merge remote-tracking branch 'private/cloud/integration' into cloud-sync
# Conflicts:
#	src/renderer/src/i18n/locales/en.json
2026-11-09 18:01:10 -08:00
OrcaWinandOrcaWin 894dbbd0ec test: remove low-value mobile generation and cache cases (#40571)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 17:30:34 -08:00
Neil e74d775884 feat(cloud): Orca Cloud workspaces on the phone (W8) (#113)
* feat(cloud): Orca Cloud workspaces on the phone (W8)

Home gets a Cloud section that lists the team's cloud workspaces straight from
the control plane (phone-signed device-session tokens; no desktop in the path).
A workspace screen wakes the sandbox (W2 long-poll wake), gets this phone its
own revocable orcad device through a W4 sealed grant (opened with the shared
opener on pure-JS primitives for Hermes), pairs directly over E2EE to the stable
sandbox endpoint, and delivers prompts queued on the phone while it was asleep
(agent.launchReplay, deduped by operation id). Create a workspace from the
phone (repo, branch, agent, first prompt, sandbox size), sleep, archive, live
status and spend, per-phone access management with revoke and disconnect, and
team share links (orca://cloud/w/<id>) open on the phone. Copy follows the
Orca Cloud glossary; dark/light, Reduce Motion, VoiceOver announcements.

* fix(w8): design round 2 (honest spend, can't-connect state, queue states, distinct titles, neutral archive, hairline groups)

* fix(w8): FE + W10 round 2 (retry ids, pairing give-up, create idempotency, neutral dots, waking composer, a11y values, salvage storage)

* fix(w8): tell same-named cloud workspaces apart by when they were made

* fix(w8): agent names from the shared table; localized repo placeholder

* fix(w8): round 3 (agent-started card with terminal sign-in path, transport-safe retries, open waits for the connection, single wake timer, created-ago rows)

* fix(w8): FE round 4 (open never blocked on worktree lookup, one connect deadline per run, mid-delivery prompts never stranded, no blank terminal on open session)

* fix(w8): prompts interrupted mid-delivery count as waiting (Open and retry resume them)
2026-11-09 17:29:05 -08:00