Commit Graph
21226 Commits
Author SHA1 Message Date
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
Neil ae7750b7af fix(sandbox-control): re-bind the build runner Worker (step 2 of 2 after the delete-class migration) (#240) 2026-11-10 04:24:12 -08:00
Neil 82357d8e20 Merge pull request #229 from nwparker/cloud/run-actions-design
Run actions: design review fixes (W10-4, DS-24, DS-30)
2026-11-10 04:22:51 -08:00
Neil 47dc83b869 Merge pull request #238 from nwparker/cloud/agents-copilot-ph
fix(cloud): Copilot's token stand-in looks like a GitHub token
2026-11-10 04:19:18 -08:00
Neil 6e33e0e3cb Merge remote-tracking branch 'private/cloud/integration' into cloud/run-actions-design 2026-11-10 04:17:11 -08:00
Neil 77af3b072a fix(sandbox-control): unblock dev deploy (10061): apply the build-runner delete-class migration without the binding, step 1 of 2 (#237)
* fix(sandbox-control): unblock dev deploy: apply the build-runner delete-class migration without the binding (step 1 of 2)

* test(sandbox-control): build-runner config test allows the binding-less step of the rollout
2026-11-10 04:17:03 -08:00
Neil 21212562b7 Merge remote-tracking branch 'private/cloud/integration' into cloud/run-actions-design 2026-11-10 04:15:35 -08:00
Neil 82bf5795a9 Merge pull request #236 from nwparker/cloud/run-actions-gaps
Run actions: split panes don't end a run; autoRunAfterSetup on first open for environment-built workspaces
2026-11-10 04:15:25 -08:00
Neil d323e4a20f Merge pull request #223 from nwparker/cloud/w5-cli-glossary
feat(cli): orca cloud glossary copy, workspace delete, routine list/run (DS-25, DS-36 CLI)
2026-11-10 04:09:58 -08:00
Neil dc150fa8a5 fix(run-actions): a split pane in the run tab can't end the run; autoRunAfterSetup fires on first open when the host ran setup in an environment build
- Command-finished events carry the pane's leaf; a run learns its pane while its tab has one,
  ignores other panes, and Stop interrupts the run's own pane.
- Workspaces whose setup ran in the environment build (hooks report environmentProvisioned) start
  the autoRunAfterSetup action the first time they are opened, once per workspace.
2026-11-10 04:09:36 -08:00
Neil b55b368887 fix(sandbox-control): host EnvironmentBuildRunner in its own Worker so control-plane preview URLs work (#234)
Cloudflare generates no preview URLs for a Worker that implements a Durable Object, so every
--preview-alias upload of orca-sandbox-control-dev 404ed. The runner DO moves to
orca-sandbox-build-runner-dev (wrangler.build-runner.dev.jsonc); the control plane binds it with
script_name and deletes its own class (migration env-build-runner-v2). The runner only keeps the
alarm: each step calls back into the control plane's BuildTicker RPC entrypoint, which runs the same
tickBuild with the control plane's D1, provider and secrets, so nothing is duplicated.
2026-11-10 04:08:45 -08:00
Neil 33202f5bd9 Merge remote-tracking branch 'private/cloud/integration' into cloud/w5-cli-glossary
# Conflicts:
#	src/cli/root-help-text-primary.ts
2026-11-10 04:06:22 -08:00
Neil ceea5240df Merge pull request #233 from nwparker/cloud/run-actions-semantics
Run actions: nonconcurrent = same action only; host launcher port block goes to the first workspace
2026-11-10 04:06:10 -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 298844533c fix(run-actions): nonconcurrent stops only the same action elsewhere; ports: a host launcher's block goes to the first workspace, the rest get registry blocks
- nonconcurrent now matches Conductor's run_mode: starting it stops that action in the project's
  other workspaces; the project's other actions keep running (W9 finding).
- A VM launcher's ORCA_PORT=3000 is the first workspace's block (persisted, stable across wake), so
  its agents, terminals, setup and run actions all agree; later worktrees on the VM get registry
  blocks that never overlap it. The daemon no longer hands the host's block to panes without one,
  and setup/archive hooks resolve the workspace block before they run.
2026-11-10 04:01:24 -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 55598b5432 Merge pull request #230 from nwparker/cloud/w9-eval
feat(cloud): acceptance read-asleep access control and phone protocol, triggered by W9
2026-11-10 04:00:03 -08:00
Neil adc417cae5 feat(cloud): acceptance read-asleep access (operator member removal, private prune) and phone protocol path, by W9 2026-11-10 03:54:00 -08:00
Neil 3f2b8ead4e Merge pull request #228 from nwparker/cloud/w9-eval
feat(cloud): acceptance — run actions + ports (m4air UI), read-while-asleep (live E2EE), gap rows
2026-11-10 03:51:42 -08:00
Neil f88c09c7fa Merge pull request #211 from nwparker/cloud/w2-squad-archive
fix(cloud): archive from the team list really stops the sandbox (DS-01 P0, DS-09)
2026-11-10 03:47:46 -08:00
Neil f90e3f4b51 chore(i18n): remove retired run-action keys from the nested catalog 2026-11-10 03:45:22 -08:00
Neil c14e875adc Merge pull request #225 from nwparker/fix/ds-34-44-billing-polish
fix(billing): DS-34 billing polish + DS-44 nits
2026-11-10 03:42:47 -08:00
Neil b199587d7e feat(cloud): desktop run actions + ports checks (W9D_ONLY=run-actions)
- local.run-actions: autoRunAfterSetup after a good setup and not after a failed one, Run button,
  one trust prompt, Stop -> Stopped, menu Restart replaces the tab, Cmd+Opt+Enter start/restart
- run.nonconcurrent: echo-loop started in B stops A's
- run.ports: ORCA_PORT/ORCA_PORT_COUNT/CONDUCTOR_PORT per terminal, distinct blocks, stable across
  an app restart, served locally; cloud half: the action in the VM reachable here via auto-forward
- run.cloud-resume: action back after Sleep/wake and after Restart sandbox
2026-11-10 03:42:31 -08:00
Neil 29cdd2cb99 feat(cloud): acceptance read-while-asleep (live, E2EE, no wake) plus access/phone rows (owner-reported) 2026-11-10 03:42:31 -08:00
Neil 322ba5eabb feat(cloud): acceptance catalog rows for run actions and per-workspace ports (gap 4) 2026-11-10 03:42:31 -08:00
Neil c5199433a9 Merge pull request #214 from nwparker/cloud/w6-secret-request
feat(cloud): agent secret requests: orcad RPC, orca secret request, orca-env (contract §3)
2026-11-10 03:42:02 -08:00
Neil 6b2ff92825 fix(cloud): Copilot's token stand-in looks like a GitHub token (Copilot ignored orca-ph-…)
Dry routine run on dev: Copilot CLI answered 'No authentication information found' with
COPILOT_GITHUB_TOKEN=orca-ph-…; it only takes GitHub-shaped tokens (github_pat_/gho_/ghu_; classic
ghp_ refused). The stand-in for that one credential is now github_pat_orcaph_<sandbox>, still
swapped by exact match on api.github.com (Copilot endpoints only) and the Copilot API.
2026-11-10 03:40:24 -08:00
Neil 6fa10c836b Merge remote-tracking branch 'private/cloud/integration' into cloud/w2-squad-archive
# Conflicts:
#	src/renderer/src/components/orca-cloud/cloud-workspace-actions.ts
2026-11-10 03:40:01 -08:00
Neil 018f918a8c fix(billing): usage warning states the actual share used, floored (DS-34 review) 2026-11-10 03:39:22 -08:00
Neil 01d2482a3a fix(billing): one billing store, skeleton, plurals, plans focus and billing nits (DS-34, DS-44)
DS-34:
- One billing store (billing-summary-store) replaces the summary, the hook's local state and the
  Run-on picker cache; it keeps the last good result through a failed read and still drops answers
  from before a team or account switch (DS-17).
- Skeleton while Plan & billing loads.
- '{{count}} sandbox hours left' and '{{count}} sandbox hours over the included amount this month'
  as i18n plurals; no bare 'hours'; the unreachable 100% branch is gone.
- Usage warning driven by usageWarningPercent ('Your team has used {{percent}}% of this month's
  sandbox hours.'), in Settings, the plans page and the account menu.
- capTooHigh states the maximum ('The spend cap can be at most {{max}}.'), from offers.maxSpendCapCents.
- Plans dialog focuses its heading on open, so Tab reaches the interval toggle before the cards.
- Payment notice uses InlineError; the build card's overage buttons land on the overage section.
- Account menu names the team once and adds the hours-left line.

DS-44: warning tone at 90%+, '$' as an input prefix, neutral paid check, 24px dialog close hit
area, no <p> inside the CheckoutPanel <dl>.
2026-11-10 03:39:21 -08:00
Neil e604bd4f39 Merge pull request #226 from nwparker/cloud/u22-cpu-fairuse
feat(sandbox-control): internal per-session CPU + operator fair-use report (U22)
2026-11-10 03:38:55 -08:00
Neil 7fa23b1b57 chore(i18n): drop retired run-action keys; runtime catalog 2026-11-10 03:37:31 -08:00
Neil cfb0b56118 fix(cloud): archive confirm starts focus on Cancel 2026-11-10 03:36:20 -08:00
Neil e02edd279f Merge remote-tracking branch 'private/cloud/integration' into cloud/w6-secret-request
# Conflicts:
#	cloud/apps/sandbox-control/image/vm-scripts.generated.ts
2026-11-10 03:34:32 -08:00
Neil d76cb62c57 fix(sandbox-control): keep preview URLs on for the dev Worker (preview aliases 404ed) (#224) 2026-11-10 03:34:07 -08:00
Neil 52e8dd431c fix(cli): design-squad copy nits (404 wording, cloud env build help) 2026-11-10 03:34:06 -08:00
Neil f8e362259a fix(cloud): harden agent secret requests (review of #214)
- Agent and worktree come from the terminal orcad verifies from launch
  evidence (verifiedCallerTerminalHandle, shared with turn-sender); the
  terminalHandle param is gone and a worktree hint is kept only when the
  host knows it.
- secrets.* are accepted, and their events sent, only on cloud orcad
  (ORCA_IS_CLOUD=1 + ORCA_SANDBOX_ID); already-set never reads orcad's env.
- touchRequest emits secrets.requestUpdated; natural expiry emits
  secrets.requestSettled {status: expired}.
- orca-env skips the control plane's reserved names and prefixes, with a
  test that reads them from secrets.ts.
- reason drops bidi controls and turns C0/C1 controls into spaces.
2026-11-10 03:34:04 -08:00
Neil 43aa595ee7 feat(sandbox-control): internal per-session CPU tracking and fair-use report (U22)
Customers keep flat sandbox hours. Each stopped session's activeCpuDurationMs
(from Vercel's stop response or GET session) is stored in a new session_cpu
table (migration 0042), idempotent per session. Recording is best-effort and
never blocks suspend, stop or usage reporting; a 5-minute cron sweep retries
recent sessions still missing CPU. Operator-only GET /v1/internal/fair-use
reports per-account 30-day utilisation sum(active_cpu_ms)/sum(wall_ms*vcpus)
with fairUseFlag above 60%. Nothing reaches usage_outbox, billing or clients.
2026-11-10 03:34:00 -08:00
Neil 5db739ce44 feat(run-actions): design review (W10-4, DS-24, DS-30) — accessible names, running tooltip, live region, shared focus outline, Finished, port submenu, rescan on stop
- Menu items name their action (Run/Run again/Restart/Stop/Show output <name>).
- Running tooltip 'Show <name> output' + '⌥⌘↩ restarts it'; primary label states running/stopping/
  last run failed; chevron 'Run actions, N running', min-w-6.
- Polite live region announces '<name> stopped/failed/finished'.
- Shared focus outline; name in text-foreground; hollow dot once a run ended.
- Restart and Stop disabled while Stopping…; exit 0 reads 'Finished'.
- Ports rescan as soon as a run ends; each port has Open in browser · Share… (Share opens the
  Ports panel, where forwarding and share links live).
- Fixtures: failed, exited.
2026-11-10 03:33:03 -08:00
Neil 0f8ab90314 Merge pull request #222 from nwparker/cloud/w6-agent-sources
W6: agent Source per person (/v1/agent-sources) + per-agent credential names
2026-11-10 03:31:03 -08:00
Neil bc7e012e6e Merge pull request #219 from nwparker/cloud/agents-a6
feat(cloud): this computer's Agent API Keys never reach an Orca Cloud VM; save each as a personal Cloud secret (A6)
2026-11-10 03:27:21 -08:00
Neil 18918529cf Merge pull request #218 from nwparker/cloud/read-snapshot-session-list
fix(cloud): read snapshot lists chats from orcad's session store
2026-11-10 03:24:40 -08:00
Neil 4b31500921 Merge pull request #221 from nwparker/cloud/run-actions-no-port-pin
fix(ports): each workspace keeps its own ORCA_PORT block, even on a VM whose launcher sets ORCA_PORT
2026-11-10 03:24:09 -08:00
Neil 9d9d91e875 Merge pull request #220 from nwparker/ds-35-signin-copy-team-page
fix(cloud): DS-35 sign-in copy, one unauthorized sentence, team busy row and chip contrast
2026-11-10 03:23:46 -08:00
Neil 9b56250956 feat(cloud): agent Source per person (GET/PUT /v1/agent-sources, offer answers, owner block) — 'Your sign-in' keeps that agent's credentials out of the sandbox session live; shared credential-names module + Worker mirror (migration 0041) 2026-11-10 03:21:22 -08:00
Neil c7f9f4a80b fix(cloud): DS-35 expired session is a neutral status with a LogIn Sign in action 2026-11-10 03:20:21 -08:00
Neil 8102e770dc fix(cloud): the registry edit can no longer label a workspace archived; tests for asleep archive (no wake) and creating/suspending refusals 2026-11-10 03:18:45 -08:00
Neil 97764fe305 fix(cloud): DS-35 sign-in copy, one unauthorized sentence, team busy row and chip contrast
- Orca account pane: signed-out and reconnect-required lines name Orca Cloud.
- Every unauthorized failure (lifecycle toast, cloud workspace errors, share links,
  cloud secrets) now says "Sign in to Orca again to continue." with a "Sign in" action.
- Team page busy row keeps full contrast: spinner + aria-busy, no opacity dimming.
- destructive-chip text uses a new --destructive-text token (light: 85% mix with
  foreground) so it clears AA on its tint.
- TeamDialogHost quietRefresh depends on the stable refresh callbacks.
2026-11-10 03:13:26 -08:00