Commit Graph
21288 Commits
Author SHA1 Message Date
Neil 3ce99fa03b fix(cloud): design-squad sign-off fixes: no section numbers, pre-save helper copy 2026-11-10 06:23:27 -08:00
Neil ea1f1a43cf fix(cloud): plain chips instead of restyled Badge (shadcn no-restyle) 2026-11-10 06:14:58 -08:00
Neil 9b1754a6d7 Merge remote-tracking branch 'private/cloud/integration' into cloud/w6-spec-ui
# Conflicts:
#	src/renderer/src/i18n/locales/en.json
2026-11-10 06:12:10 -08:00
Neil a5859bdfdc fix(cloud): W6 UI review round 2: replay pruning on ready, Dismiss focus, F6 scope, split-group visibility, lint 2026-11-10 06:07:25 -08:00
Neil 41d8bbf98d Merge pull request #243 from nwparker/cloud/usage-alerts
feat(billing): usage alerts for owners and admins at 75/90/100%
2026-11-10 06:05:30 -08:00
Neil 055428b381 feat(billing): dedicated 100% usage alert copy by overage state (design-squad) 2026-11-10 06:03:44 -08:00
Neil 6273ed88fe fix(billing): async ledger I/O behind a queue; no casts in usage alerts 2026-11-10 06:03:44 -08:00
Neil 6a8f8b2b0f test(billing): type the usage-alert show mock 2026-11-10 06:03:44 -08:00
Neil 7f5e6a9af3 feat(billing): alert owners and admins at 75/90/100% of sandbox hours
- Desktop notification (title "Orca Cloud", body reuses the in-app usage sentence) when a
  billing read crosses 75, 90 or 100%, once per level per account and billing period. Main
  owns the ledger (userData/orca-billing-usage-alerts.json), so reloads, re-renders and
  second windows never repeat it; a new period starts over. Members are never notified.
- Click opens Settings > Orca account (Plan & billing) via ui:openSettings with a target.
- The in-app usage notice (account menu, billing panel, plans page) is now owners/admins only.
- Billing panel: muted note under the Overage description that owners and admins are alerted
  at 75%, 90% and 100%.
- Fixtures: account menu at 90% (admin and member), billing panel member at 90%.
2026-11-10 06:03:44 -08:00
Neil 95bb1dd372 Merge pull request #249 from nwparker/cloud/w6-a9-recipe
A9 sign-out before delete + recipe env-forwarding warning (P-4)
2026-11-10 06:03:08 -08:00
Neil cd9f2b55ee Merge pull request #257 from nwparker/np4-shell-tracker
feat(cloud-start): setup return link, setup telemetry, X1 error model, B2 team-plans lookup (NP-4)
2026-11-10 05:59:37 -08:00
Neil 99c52ba889 Merge remote-tracking branch 'private/cloud/integration' into cloud/w6-a9-recipe
# Conflicts:
#	cloud/apps/sandbox-control/image/vm-scripts.generated.ts
2026-11-10 05:53:41 -08:00
Neil aac87b9446 fix(cloud-start): parse setup errors without type assertions 2026-11-10 05:50:29 -08:00
Neil 21ac87b972 feat(cloud-start): setup return link, setup telemetry, X1 error model, B2 team-plans lookup (NP-4)
- N9: orca://cloud/setup/return?session=cs_… is routed (open-url + second
  instance), validated, focuses Orca and fans out to renderer listeners
  (onCloudSetupReturn) so the setup session re-reads at once.
- N10: cloud_setup_step_{started,done,failed}, cloud_setup_first_sandbox and
  cloud_setup_plan_chosen, enum-only, derived from the setup rows.
- X1: setup error kinds (timed_out, checkout_canceled, bank_step,
  trial_unavailable, team_create_failed, wrong_account) and their actions.
- B2: billing POST /v1/billing/team-plans returns other teams' plan state with
  the caller's own token; auth confirms membership from that token (no new
  credential). Desktop IPC billingTeamPlans + useSwitchToPlannedTeam. The team
  switch logic moves out of SidebarTeamSubmenu so the composer can reuse it.
2026-11-10 05:50:29 -08:00
Neil 0606c25105 Merge pull request #250 from nwparker/cloud/w6-codex-broker
feat(sandbox-control): Codex account broker (contract D11, flag S2)
2026-11-10 05:49:20 -08:00
Neil 5b8bc2d479 Merge pull request #244 from nwparker/cloud/agents-a6-design
fix(cloud): A6/DS-02 design follow-ups (Save to your Orca account rows, catalog names, cloud build-sheet fixture, DS-33 hint)
2026-11-10 05:47:28 -08:00
Neil 732c04ddd7 Merge remote-tracking branch 'private/cloud/integration' into cloud/w6-a9-recipe
# Conflicts:
#	cloud/apps/sandbox-control/image/vm-scripts.generated.ts
2026-11-10 05:43:06 -08:00
Neil 7fa51b6a0b Merge pull request #246 from nwparker/np4/github-repo-access
NP-4: GitHub repo access, preselected install URLs, install requests, webhook auto-start, repository list (N2/N3/N12, D2/D3)
2026-11-10 05:42:57 -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 e897152ec4 fix(cloud): W6 UI review round 1: S4-b focus/F6, collapse, Details hook, routing, replay, shared copy 2026-11-10 05:38:20 -08:00
Neil 4c1ee40ffe Merge remote-tracking branch 'private/cloud/integration' into cloud/w6-codex-broker
# Conflicts:
#	cloud/apps/sandbox-control/image/vm-scripts.generated.ts
2026-11-10 05:32:29 -08:00
Neil 4620815e04 fix(cloud): DS-02 sign-off fixes: saved row drops 'only on this computer', a failed row's only action is Try again, the variable sits on its own line; Agent API keys scope note
Per design-squad on #244. The Agent API keys editor gets one muted line under the host scope choice,
'Not used in Orca Cloud. Save a key to your Orca account to use it in cloud workspaces.', instead of
changing #40303's own label.
2026-11-10 05:32:00 -08:00
Neil d6e36a9c38 merge integration 2026-11-10 05:31:24 -08:00
Neil 825bb88484 Merge pull request #256 from nwparker/cloud/agents-opencode-nocreds
fix(cloud): OpenCode with no credentials shows 'Connect a provider' instead of failing
2026-11-10 05:30:33 -08:00
Neil 4114eea5d0 fix(cloud): show the delete sign-out line only when the running sandbox holds a CLI login (D14) 2026-11-10 05:28:37 -08:00
Neil fed130d30a feat(cloud): orcad reports its build; desktop flags out-of-range version skew with a cloud workspace (#254)
* feat(cloud): orcad reports its build commit; desktop flags out-of-range version skew with a cloud workspace

* review: shared compat verdict, status role, retries, tests, version-skew runbook section

* fix: lint gates (async commit read, no casts, retry outside effect, surface split)

* test(cloud): status panel error action is Try again (DS-13 copy)
2026-11-10 05:27:55 -08:00
Neil 849a12773b fix(cloud): find agent CLIs in /opt/orca/tools/bin; delete note only for running sandboxes; test retry skip
Verified on a dev sandbox (Claude Code 2.1.319, codex-cli 0.166.0): runCommand runs as ubuntu with
HOME=/vercel (same user as orcad); `claude auth logout` and `codex logout` exist and exit 0; the
script reported {loggedOut:2,left:0}, removed both credential files and kept other ~/.claude.json keys.
2026-11-10 05:27:41 -08:00
Neil 5b9d2735e0 fix(cloud): OpenCode with no credentials shows 'Connect a provider' instead of failing on Copilot or Zen
With nothing configured, OpenCode picked its GitHub Copilot provider (GITHUB_TOKEN is the workspace
GitHub App stand-in: 'Authorization header is badly formatted') or OpenCode Zen (opencode.ai is not
on the egress allowlist). The VM seeding keeps both in OpenCode's disabled_providers unless the user
connected them in OpenCode (auth.json); the user's own list is kept (ledger of what Orca added).
Checked on a dev VM: the composer opens on 'Connect a provider'.
2026-11-10 05:23:31 -08:00
Neil 1bca45b536 fix(sandbox-control): Codex broker review fixes (M1-M4, L5-L8)
- M1: a permanent refresh failure revokes only the login it refreshed (CAS on updated_at).
- M2: dead logins (refresh_token_expired/reused/invalidated) are never retried; a new login clears it.
- M3: the Codex account route only carries the token to /backend-api/codex/*, the plugin catalog and
  wham/usage (GET), seen live; plain segments only.
- M4: one atomic INSERT enforces one live broker per person (409 broker_in_progress) and 6 starts/hour;
  broker sandboxes use 2 vCPUs.
- L5: auth.json is read only after Codex exited 0.
- L6: the 401 hook respects the refresher's backoff and dead logins.
- L7: a cancel while the broker is starting wins: the sandbox goes and POST answers 409 cancelled.
- L8: orca-sandbox-env writes the marker before the swap, recognises any Orca placeholder, and never
  overwrites a login already set aside.
2026-11-10 05:22:43 -08:00
Neil 367a36b679 fix(cloud): exhaustive switches, fixed clocks in repo-access tests 2026-11-10 05:19:46 -08:00
Neil 100b9d4699 feat(sandbox-control): tell billing the GitHub owner/user ids of each bind (trial abuse keys, POST /v1/internal/trial/github) 2026-11-10 05:19:45 -08:00
Neil 1746238a8a fix(cloud): repo access hook uses cloudWorkspaceApi(); test bridges gain the new methods 2026-11-10 05:19:45 -08:00
Neil 0bdf4af437 fix(cloud): D1 GitHub row drives the primary 'Give access and start' instead of an in-row button 2026-11-10 05:19:45 -08:00
Neil 521c9fe3c5 feat(cloud): desktop repo access hook, GitHub row model and repo list plumbing (NP-4 N2/N12, D2/D3) 2026-11-10 05:19:45 -08:00
Neil a4e0b7a656 feat(sandbox-control): GitHub repo access, preselected install URLs, install requests, repository list (NP-4 N2/N3/N12, D2) 2026-11-10 05:19:44 -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 4af8f7fe04 feat(sandbox-control): Codex account broker (contract D11, flag S2)
Codex signs in once via the person's Orca account:
- POST /v1/agent-credentials/codex/broker starts a short-lived broker sandbox (golden image, egress
  auth.openai.com + chatgpt.com only, non-persistent, tagged orcaCodexBroker/orcaInfra so the workspace
  orphan sweep and billing never see it) running `codex login --device-auth` (Codex 0.166), and returns
  {brokerId, verificationUrl, userCode}. GET .../broker/:id -> {status: pending|active|failed}; DELETE
  cancels. On completion the Worker reads auth.json through the files API, stores the tokens
  envelope-encrypted and Personal-only in agent_credentials, and deletes the broker sandbox.
- Lease refresher (cron, every 5 min): refreshes the access token with the refresh token before expiry,
  single-flight per person (D1 lease) with a compare-and-swap write, so a refresh token is spent once and
  a delete or new login is never overwritten (no refresh_token_reused). Failures mark expiring/expired
  (by the real access-token expiry) or revoked (refresh_token_reused/invalidated). A chatgpt.com 401
  triggers a refresh instead of revoking.
- codexAccount AccountProvider: placeholder access token bound to the sandbox id (D14), swapped for the
  real one on chatgpt.com with ChatGPT-Account-Id; never in a shared workspace (D13); kill switch
  AGENT_ACCOUNTS_CODEX_DISABLED=1.
- VM: orca-sandbox-env writes a placeholder ~/.codex/auth.json (no refresh token) from
  ORCA_CODEX_AUTH_PLACEHOLDER, sets a managed HTTPS ChatGPT provider (Codex's Responses WebSocket can't
  pass the egress proxy; verified live), and sets a person's own login aside / restores it.
- Migration 0045_codex_broker (codex_broker_sessions, codex_leases; no token columns).
- Flag S2 on in wrangler.dev.jsonc; absent in prod.
2026-11-10 05:03:50 -08:00
Neil bfa713140c fix(i18n): plural defaults for the recipe env warning; sync runtime and protected-copy catalogs 2026-11-10 05:03:10 -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 2454d31779 feat(cloud): agent-accounts W6 UI slices: panel Cloud sections 2–3, S2 build-sheet Secrets, S4-b secret request card
- Panel sections 2–3 on Orca Cloud (standalone, for gap-agents' AgentHostPanel shell):
  Cloud-secret key rows with scope chips and shadowed keys listed disabled with the reason;
  effective variables; missing names with inline Add / Add mine; asleep and shared (D13) states.
- S2: missing = environment envVarNames − effective secrets for the repo and caller; Paste .env,
  per-name scope, batch save, build-time team-only note (Q7), post-open 'secrets missing' notice.
- S4-b: card for orcad secrets.requested/requestSettled; Personal by default, Repository only if
  writable, agent scope as hint; N more requests; expired and saved-after-expiry; touchRequest at
  most once a minute; Restart {{agent}}; value saved via Cloud secrets PUT, then resolveRequest.
- Main: cloudSecrets.workspaceSharing reads GET /v1/agent-sources (owner, sharedWorkspace).
- Fixtures for every state, dark and light.
2026-11-10 04:53:42 -08:00
Neil a81afb57e0 Merge remote-tracking branch 'private/cloud/integration' into cloud/w6-a9-recipe
# Conflicts:
#	cloud/apps/sandbox-control/image/vm-scripts.generated.ts
2026-11-10 04:49:31 -08:00
Neil 40b33811b5 Merge pull request #242 from nwparker/cloud/w6-agent-accounts
W6: sign in once via your Orca account — Claude account store + egress-time Source (D10/D11/D13/D14)
2026-11-10 04:48:11 -08:00
Neil 240809a43b Merge pull request #239 from nwparker/cloud/w2-squad-p1
fix(cloud): design-squad P1s for W2 lifecycle (DS-03/05/06/08/10/11/12/13)
2026-11-10 04:43:24 -08:00
Neil aedf0809eb Merge remote-tracking branch 'private/cloud/integration' into cloud/w6-a9-recipe
# Conflicts:
#	src/renderer/src/i18n/locales/en.json
2026-11-10 04:43:10 -08:00
Neil de8a65b7f1 Merge pull request #241 from nwparker/cloud/w9-eval
feat(cloud): acceptance — phone UI read-asleep (sim), cloud run.ports headless, nonconcurrent per #233
2026-11-10 04:41:08 -08:00
Neil 0832550290 feat(cloud): provider-specific onUnauthorized hook (default: revoke) 2026-11-10 04:39:25 -08:00
Neil f236d8183e revert: keep the #40303 scope label as is (its source default lives in the held upstream PR) 2026-11-10 04:35:19 -08:00
Neil 5e1a5d7ac5 refactor(cloud): drop env-build scrub-on-clone (spec v4 D14); keep sign-out before delete 2026-11-10 04:33:45 -08:00
Neil f45bb50f14 Merge pull request #235 from nwparker/cloud/pricing-u22-u24
feat(billing): overage billed by the minute; sandboxes go to sleep at the cap (U22, U24)
2026-11-10 04:33:36 -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