feat(cloud): attach images to a cloud workspace at create
Second of three. Stacked on #7620 — review that first.
Attaching an image on mobile failed with a flat refusal, which was honest but not useful:
// useCreateCloudWorkspace.ts
throw new Error("Attachments are not supported for cloud workspaces yet");
The reason was real: an attachment is a file on a host, resolved at launch by resolveAttachmentPath(id) into a path pasted into the prompt. A cloud workspace has no host when you press send.
The change
Almost none of this needed inventing — the pieces were already there and simply weren't connected:
- the composer already PUTs attachments to R2 before the create, so the bytes are in cloud storage regardless of where they are going
- host-service already knows how to pull them back (
attachments.importFromCloud→api.attachment.resolve→ download → local attachment store) runAgentInWorkspacealready takesattachmentIdsand builds the# Attached filesblock
So the file ids travel with the launch (SUPERSET_SANDBOX_AGENT_ATTACHMENTS), and the box does its own import in launchSandboxAgentOnce once host-service is up, handing the agent in-box paths through the same prompt block every other host uses.
importFromCloud's body is extracted as importCloudAttachments, shared by the procedure and by a sandbox that has the ids in its environment and no client to call it. A failed download logs and drops the attachments — never the prompt.
On mobile, both create paths now settle uploads before branching on the target; the cloud branch previously returned ahead of awaitAttachmentUploads.
One trap worth knowing
renderSandboxConf does sandboxIdentitySchema.parse(identity), and zod strips unknown keys. A new identity variable that isn't declared in that schema is dropped on the way to the box with no error anywhere. claim.ts casts the launch env as Partial<SandboxIdentity>, so TypeScript won't catch it either. Declared it; flagging it because the next person adding a variable will hit this.
Verified
shared,trpc,host-service,sandbox,apps/mobileall typecheck cleanbun test src/runtime/sandbox-self-seed src/trpc/router/attachmentsinpackages/host-service: 22 pass / 0 fail- Not yet exercised end-to-end in a box: this needs a bundle publish + image release to reach one, same as #7620. I'll run both and verify an image actually reaches the agent before either is called done.
https://claude.ai/code/session_01FK6rLzBEUiHHXZWNmpQ2BP
Summary by cubic
Attaching images to a cloud workspace at create now works end to end; previously mobile refused with "Attachments are not supported for cloud workspaces yet".
- The attachment ids travel in
SUPERSET_SANDBOX_AGENT_ATTACHMENTS, and the sandbox pulls the bytes from cloud storage once host-service is up. importFromCloud's body is nowimportCloudAttachments, shared by the procedure and the sandbox's first-boot launch.- Both mobile create paths settle uploads before branching on the target, and the create call now actually gets the uploaded ids instead of dropping them.
- A failed download logs and drops the attachment; the prompt always launches.
Note for reviewers
- New identity env vars must be declared in
sandboxIdentitySchema;renderSandboxConfstrips unknown keys silently.
Summary by CodeRabbit
-
New Features
- Cloud workspaces can now be created with uploaded attachments, which are made available to launched agents.
- Workspace repositories now support creating working branches from specified base branches.
- Cloud workspace launches support up to 10 uploaded attachments.
-
Bug Fixes
- Attachments are uploaded before cloud workspace creation, ensuring they are included reliably.
- Failed attachment imports no longer prevent an agent from launching.
-
Documentation
- Clarified workspace checkout and branch behavior.