Commit Graph
524 Commits
Author SHA1 Message Date
Neil 36acde0023 feat(cloud): classic SSH agent sign-in status and code sign-in over remote exec
Spec v4 §4 annotations 4-5, Q8. Main runs the CLIs' own status commands (claude auth status --json,
codex login status) over the host's SSH exec only while it is connected, 60 s cache per target;
only verdicts reach the renderer. Code sign-in runs Claude's paste-code login and Codex's device
code over SSH exec (no callback, no forward): the pasted code goes to the CLI's stdin, never argv;
codes, tokens and CLI output are never logged. The A16 panel's classic-SSH rows get Sign in (inline
paste / device code), Sign out, the dated last report and the spec's disabled reason while
disconnected; S3 checks classic SSH hosts the same way. No #40228 file edited.
2026-11-10 10:37:31 -08:00
Neil 1ebdef8df6 feat(cloud): NP-3 build-sheet Agents row (spec v4 §5b): fixed height at mount, zero layout shift
- One row from the Orca account, never the sandbox: 32 px ready line when every agent is ready at
  mount, otherwise 48 px; every later state renders inside that height (Playwright: measured layout
  shift 0, logs toggle never moves).
- R2 Set up runs S0's setup inline for each agent in turn; device code, browser, paste, failed,
  expired, kill switch (per-workspace sign-in, queued until the sandbox answers), A6 desktop key.
- ⋯ menu: Source per agent in this workspace (new per-workspace setWorkspaceSource / workspaceSources
  IPC; main resolves the sandbox id from its own runtime records), Manage agent accounts.
- Removes the v3 'Add an agent' build step and the per-sandbox Cloud sign-in row from the sheet.
2026-11-10 08:45:38 -08:00
Neil 6973c6abe7 Merge remote-tracking branch 'private/cloud/integration' into cloud/agents-s0
# Conflicts:
#	src/renderer/src/components/new-workspace/NewWorkspaceComposerProjectSection.tsx
2026-11-10 08:11:00 -08:00
Neil 0fd423dea1 feat(cloud): S0 Orca Cloud agent accounts + onboarding Agent row (G)
Main:
- agent-credentials client for /v1/agent-credentials, /v1/agent-sources and the
  Codex broker routes; replies and errors are codes only. The shared control-plane
  request keeps the server's error name (HostedSandboxRefusalError) so newer
  routes (broker_in_progress, rate_limited, no_golden_image) map to codes.
- claude setup-token runner (pseudo-terminal in production, fake child in tests):
  captures the sk-ant-oat01 token in memory, never logs it, PUTs it from main
  with the local Claude account email as label. Capture failure or no claude
  offers "Paste the token instead"; a pasted value goes renderer -> main once.
- Codex broker driver: device code, poll until active, cancel, code expiry.
- orcaCloudAgents IPC + preload bridge: states and codes only.

Renderer:
- Settings > Agent accounts > Orca Cloud (S0, spec §5): not set up, setting up
  (browser / preparing / device code / paste / saving), state 7 Source choice,
  active, expiring, expired/revoked, kill switch, signed out, load and save
  errors; the mandatory policy line; Source via SettingsSegmentedControl.
- The composer's Agent row (cloud-start G) replaces ComposerCloudAgentHint:
  from your Orca account / team key (collapsed), Set up once -> S0, kill switch
  info, signed-out copy; hidden for members blocked by billing; never blocks.
- Telemetry cloud_first_start_agent_coverage (once per install).
- Fixtures: settings/agent-accounts/OrcaCloudAccounts:*, new-workspace/OrcaCloudAgentSetupRow:*.
2026-11-10 07:56:58 -08:00
Neil 3c368cbe52 Merge remote-tracking branch 'private/cloud/integration' into cloud/w2-d4-github-projects 2026-11-10 07:49:42 -08:00
Neil 13d6cf7e51 feat(cloud): GitHub-only projects in the Project picker (cloud-start D4) 2026-11-10 07:44:33 -08:00
Neil 67008f4515 feat(agent-api-keys): A5 follow-ups: offline last-known state, retry pending saves, remove-prompt fixture
- Signed in but Orca unreachable: rows keep their last-known state (from the per-account ledger:
  names, key ids and timestamps only) under "Can't reach your Orca account right now", with no
  account actions that would fail.
- Saves made while signed in that miss the account (offline or a transient failure) are queued in
  the ledger and retried at start, on wake and with backoff while waiting; the timer stops when
  idle. Only that key at that version: edits, removals and signed-out saves are never uploaded.
- Fixtures: removePrompt, cloudUnreachable.
2026-11-10 07:36:51 -08:00
Neil b574953493 Merge remote-tracking branch 'private/cloud/integration' into cloud/agents-a5
# Conflicts:
#	src/renderer/src/i18n/locales/en.json
2026-11-10 06:50:12 -08:00
Neil 0df70ebdf7 feat(agent-api-keys): save Agent API keys to the Orca account and import from this Mac (A5/D12)
While signed in to Orca with Orca Cloud, saving an Agent API key also writes it to the
personal Cloud secret of the same variable through /v1/secrets. The sealed vault stays the
cache and the source for non-Cloud launches; host scope stays local. Only every-host keys the
egress proxy swaps are written. A main-side ledger (names only, per account) tracks what this
computer wrote, and only those copies can be removed from the account, after confirmation.

Import from this Mac: main scans OpenCode's auth.json, ~/.gemini/.env and the login shell env;
the renderer sees names, sources and last fours only, and main re-reads values on import.
OAuth sign-ins are listed, never read.
2026-11-10 06:46:50 -08:00
Neil 3999711fc7 Merge branch 'cloud/integration' of https://github.com/nwparker/orca-private into cloud/w2-squad-delete 2026-11-10 06:40:09 -08:00
Neil d5ea304eaf Merge pull request #262 from nwparker/cloud/w6-spec-ui
feat(cloud): agent-accounts W6 UI: panel Cloud sections 2–3, S2 build-sheet Secrets, S4-b secret request card
2026-11-10 06:38:12 -08:00
Neil 5ec9ffab02 feat(cloud): Sleep and Delete in the team list row menu (control plane for workspaces this desktop does not run, confirm before delete), Running filter on Home; limit errors open Mine + Running (DS-12) 2026-11-10 06:32:39 -08:00
Neil 7c5c00331f Merge pull request #263 from nwparker/fix/billing-usage-alert-refresh
fix(billing): timely usage alerts — re-read on cloud create/wake and every 30 min while running
2026-11-10 06:26:22 -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 1b2cfb9c7d fix(billing): re-read usage on cloud create/wake and every 30 min while one runs
Usage alerts only fired on a billing read, so a team crossing 75/90/100% mid-session
wasn't alerted until a restart, a team switch or opening a billing view. Main now owns one
app-wide schedule: the hosted recipe's onReady (create and resume success) asks the main
window for a forced billing re-read, and the session registry's sync (already run on every
lifecycle change and on the existing 30 s beat) reports whether any cloud workspace is
running, which drives a 30-minute poll with no timer of its own. Requests go only to the
trusted main window so extra windows never stack reads; the per-level ledger still dedupes.
2026-11-10 06:15:39 -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 33950fa436 feat(cloud-setup): desktop side of the one-tab setup session (N1), team-first plans (O1)
- Signed out, Set up and start opens one tab. The authorize page shows the
  setup account step (A2). Once the code is exchanged, the loopback holds the tab,
  creates the billing setup session and 302s the same tab into the setup pages.
- Signed in, the session is created and its start URL is opened.
- IPC: orcaProfiles.cloudSetupStart / cloudSetupGet / cloudSetupLink (Copy setup
  link mints a fresh one-time link).
- Renderer: cloud-setup-session.ts polls the session (2 s for 3 min, then 10 s),
  keeps a snapshot for the composer and tracker, and switches the profile to the
  team setup chose.
- Plans dialog: Checkout joins the open setup session. A personal account
  (409 team_required) goes through setup instead, which makes or picks a team
  first.
- Billing: POST /v1/cloud-setup/sessions/:id/link.
2026-11-10 06:07:35 -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 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 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 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 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 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 12fe0c867f feat(cloud): sign agents out before sandbox delete, scrub env-build images, recipe env warning (A9, P-4)
- Worker: run orca-agent-signout (each agent's logout, then credential files) on a running sandbox
  before the provider delete; bounded (20 s) and best effort, never blocks the delete.
- Environment builds: scrub agent auth (--scrub-only) before the snapshot; fail closed.
- New VM script registered in VM_SCRIPTS + provision loop; vm-scripts regenerated.
- Main IPC ephemeralVm:forwardedEnvSummary returns names only, grouped by credential-looking.
- P-4 warning component (+ fixture) shown under Settings > recipes; delete dialog line for awake
  Orca Cloud sandboxes.
2026-11-10 04:07:13 -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 f364c85f87 feat(cloud): this computer's Agent API Keys never reach an Orca Cloud VM; each can be saved as a personal Cloud secret (A6)
Desktop-sealed keys (Settings → Agent API Keys) ride every agent launch as plain env on other
hosts. An Orca Cloud VM would hold them in plaintext, so they are no longer sent there: runtime
calls to Orca Cloud environments skip them (provider record; otherwise any VM-provisioned host or a
Vercel Sandbox route counts, failing closed). The Add-an-agent view and the build sheet's key step
list each every-host key no Cloud secret covers yet, with its own 'Save as personal Cloud secret'
button: main unseals that one key and writes it to the user's personal Cloud secrets; the renderer
never sees the value, and nothing is uploaded without the click. The VM then gets a placeholder
the egress proxy swaps. Readiness no longer counts desktop keys as cloud access.
2026-11-10 02:30:18 -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 7f6859f8d9 Merge pull request #159 from nwparker/cloud/w2-predict
perf(cloud): predictive wake on intent, pre-connect during resume, one handshake per wake
2026-11-09 20:32:55 -08:00
Neil a0b57b10f5 fix(cloud): an intent wake for the active workspace is claimed at once; any cloud activation claims in main (claimOnly, no wake); main activation (CLI, phone) claims; suspend clears the unopened mark 2026-11-09 20:28:26 -08:00
Neil 1bd5504707 fix(cloud): predictive wake review fixes (cap on awake-unopened sandboxes with return to sleep, shared hover/focus rate limit, no focus re-wake after a chosen sleep, quiet refusals leave no failed-resume record and back off, pre-connect bound to the wake, no pre-connect on lost-contact recovery, wheel re-arms the dwell) 2026-11-09 20:22:54 -08:00
Neil 05d43602c8 Merge pull request #149 from nwparker/cloud/delete-unconfirmed-fix
fix(cloud): P0 delete leak - never drop a row for an unconfirmed sandbox; creator can delete across teams; asleep delete without wake
2026-11-09 19:33:17 -08:00
Neil 5bdec31000 fix(cloud): address review - asleep delete needs Force delete and runs ownership checks, destroyed sandboxes forget their row, removed members get no cross-team delete, destroy errors always surface 2026-11-09 19:27:29 -08:00
Neil cb7d58bbc0 fix(cloud): deletes never drop a row for a sandbox Orca Cloud can't confirm; asleep cloud delete skips the wake; creator can delete across teams; picker sign-in selects Orca Cloud; signed-out create shows the sign-in card 2026-11-09 19:20:44 -08:00
Neil 59a628033e Merge pull request #144 from nwparker/cloud/w2-close
feat(cloud): Apply changes again after a partial move; continue an agent when its view is reopened after a restart (real-app run on m4air)
2026-11-09 19:19:35 -08:00
Neil da208a006d fix(cloud): keep the untracked archive on any skipped file, sweep temps, link fallback, Discard on the after-restart offer, disarm reaches running continue loops 2026-11-09 19:08:15 -08:00
Neil bbb035b5a4 fix(cloud): review fixes for Apply changes again and late continue (staged+unstaged re-apply, untracked files never lost, no archive with leftovers, atomic writes, per-transfer lock and worktree check, after-restart offer; one continue loop per pane, late reopen verifies session or offers Continue) 2026-11-09 18:59:48 -08:00
Neil 4abbc03f42 feat(cloud): Apply changes again after a partial or failed move (idempotent apply onto the same worktree, conflicts reported, survives restart); continue an interrupted agent when its pane is reopened later 2026-11-09 18:17:17 -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
Neil 60377d3364 feat(cloud): remote desktop Beta — single-use tickets, fit, clipboard, keyboard release (W10 RD-1..6) (#122)
* feat(cloud): remote desktop single-use tickets, fit, clipboard and keyboard release

- VM: Xvnc on a 0600 socket with no VNC auth plus an X cookie; orca-desktop-proxy (websockify
  subclass) admits one WebSocket per unused 60 s ticket from the same localhost origin, refuses
  rebinding Hosts, scrubs tickets from logs, serves the page with connect-src 'self'.
- Worker: POST /desktop mints a fresh ticket per call (schemaVersion 2).
- Desktop: no secret in the tab URL; main hands the page tickets on load and reconnect (backoff,
  floor, pause with Reconnect), only for the exact URL of a live forward it opened; keyboard stays
  in the desktop until Ctrl+Cmd / Ctrl+Alt; a paste key pushes this computer's clipboard; sandbox
  copies reach this computer after a copy gesture.
- UI: keyboard hint, asleep/starting neutral tone and mapping, persistent error toasts, Beta badge.

* fix(cloud): remote desktop review fixes

- Security review: noVNC host/port/encrypt pinned to the page's origin, CSP connect-src 'self',
  exact-URL + live-forward trust, mint floor and per-minute cap, copy gate on copy gestures only,
  X display cookie.
- Design review: archived is its own neutral state, starting covers waking, page messages say
  "Wake it in Orca", pause overlay is a status for calm states and focuses Reconnect, hint wraps
  and hides from assistive tech when faded.
- FE review: paste follows the keyboard layout, AltGr never releases, page calls settle on
  navigation, state notices only on change, hint once per load/release, paste always pushes,
  no committed bytecode, session tests.

* fix(cloud): remote desktop archived page message, hint layout, fixtures

* fix(cloud): remote desktop copy gate counts double-clicks (pointer events have no click count)

* chore(cloud): remote desktop lint (exhaustive pause reasons, no test casts or wall clock)
2026-11-09 17:36:19 -08:00
Neil 36ea9cac01 Merge stably/main into cloud/integration
# Conflicts:
#	src/main/ipc/ephemeral-vm-runtime-handlers.ts
#	src/preload/api/ephemeral-vm-api.ts
#	src/preload/api/ephemeral-vm-bridge.ts
#	src/renderer/src/components/terminal-pane/pty-connection/host-ownership/pty-connection-runtime-owner-spawn-routing.spec.ts
#	src/renderer/src/i18n/locales/en.json
2026-11-09 15:54:48 -08:00
Neil 9d48206ac8 feat(files): stream runtime file and folder downloads with progress, cancel and open-locally 2026-11-09 15:35:45 -08:00
Jinjing 3e86c5ac73 fix(i18n): translate sparse preset validation failures (#40277)
* fix(i18n): translate sparse preset validation failures

* fix: classify sparse directory validation by type
2026-11-09 15:12:50 -08:00
Neil 604ce7c913 Merge pull request #99 from nwparker/cloud/w6-mcp-final
W6: MCP config sync into Orca Cloud sandboxes (egress hosts + OAuth loopback relay)
2026-11-09 15:10:16 -08:00
Neil f4032bf36f fix(cloud): drop Start empty (a host-local project can't open on a sandbox), Try again after pushing; sidebar pending row uses sandbox wording and the card's title 2026-11-09 14:48:07 -08:00
Neil a8d6bb4698 fix(cloud): build sheet round 4: glossary cards, GitHub not connected + no GitHub remote before any sandbox, measured start hint from /v1/config, Orca Cloud host label
- Account/billing cards use glossary titles (Out of sandbox hours, Spend cap reached, Payment failed,
  running-sandbox limits), role-aware next steps, and 'Nothing was created, and you weren't charged.'
- 409 github_not_connected: 'GitHub isn't connected for <owner/repo>' + Connect GitHub (POST
  /v1/github/connect, opens the GitHub install page) + Try again.
- A repo without a GitHub remote is refused in main before the control plane is called, with
  Start empty / Push to GitHub first.
- GET /v1/config serves createTiming (p50/p95 of recent create-to-ready); the sheet's 'usually ~Ns'
  reads it and shows no hint without a measurement.
- Orca Cloud servers display as 'Orca Cloud' in sidebar host labels and the usage segment; legacy
  '<repo> VM <id>' names are renamed at startup.
2026-11-09 14:48:06 -08:00
Kelvin Amoaba 98bc1acf16 feat(dictation): pulse three dots in the pill while spoken words are still on their way (#40443)
* feat(dictation): show pending dots while the engine holds speech it hasn't committed

The VAD pause segmenter already knows when a phrase is open. The recognizer
now posts speech-pending when a phrase opens and clears it once that phrase's
text is posted, and the desktop pill shows three dots after the text while it
is on. Only pause-cut on-device streams send it, so cloud, the paired web
client and phones keep today's pill.

* fix(speech): keep a lone click from turning the pending dots on
2026-11-09 20:14:48 +00:00
Jinjing 8ef4680142 Improve project group ordering across hosts (#39816)
* Improve project group ordering across hosts

* fix(project-groups): restore each group order after a failed drop

A deleted group made the aggregate rollback stop early, leaving other groups at
the ranks from the failed drop. Restore each group independently and log the
swallowed single-update failures again.

* refactor(main): give project group RPC methods their own module

Keeps repo.ts under the 300-line cap as the project group surface grows.
2026-11-09 11:40:51 -08:00
Kelvin Amoaba 58733086c9 feat(speech): spell dictated code terms with a personal and per-repo dictionary (#40450)
* feat(speech): spell dictionary terms in dictation, with repo terms and Whisper prompt

* test(speech): pin host repo terms for phone dictation

* fix(speech): keep symbol terms whole, accept null setup params, resolve SSH repos

* refactor(speech): key transcript words once and type phone terms at the reply schema

* refactor(speech): merge speech-types imports in the speech IPC
2026-11-09 19:22:46 +00:00
Kelvin Amoaba 9a45e8bdfb feat(speech): dictate through any OpenAI-compatible transcription service (#40160)
Add an OpenAI-compatible model whose base URL, model and optional key
are set up in a Voice settings dialog and sealed together in ~/.orca,
so a key is never sent to a host it wasn't saved for. It reaches
OpenAI, Groq, Mistral and local servers, and replaces the unused
userModels setting.
2026-11-09 16:57:24 +00:00