feat(copilot): let the mothership manage workspace sandboxes - #6239
feat(copilot): let the mothership manage workspace sandboxes#6239waleedlatif1 wants to merge 3 commits into
Conversation
Adds the manage_sandbox handler (add/edit/delete/list), following the manage_custom_tool precedent, plus the display title and generated catalog bindings. Sandbox create/update/delete moves out of the two REST route files into workspace-sandboxes.ts as createWorkspaceSandbox/updateWorkspaceSandbox/ deleteWorkspaceSandbox, returning a typed failure the caller renders for its own surface: the routes map it to 409/400/404, the tool to a sentence. The routes previously owned the name-conflict pre-check, the unique-index race catch, the unconditional build enqueue, and the detached image release; sharing them is what keeps the tool from drifting from the UI. The handler reproduces the routes' gate exactly — workspace admin, then the Max/Enterprise entitlement, then the same per-workspace mutation bucket — so a sandbox cannot be created through chat that the same user could not create in Settings > Sandboxes. `list` needs only read access, matching GET, because a downgraded workspace must still see what it built. workspaceId comes from server context only.
Fixes found auditing the first pass: - updateWorkspaceSandbox treated a whitespace-only name as supplied, so it trimmed to empty, skipped the falsy conflict pre-check, and wrote an unnamed sandbox the UI cannot produce. Name normalization now runs in the operations layer and reuses the contract's own sandboxNameSchema, so the tool path — which has no schema in front of it — cannot accept a name the REST path rejects. - The handler resolved permissions through ensureWorkspaceAccess while the route used getUserEntityPermissions, so the same refusal was worded two ways. Both now use the same primitive and the same SANDBOX_ADMIN_REQUIRED constant, and a DB failure no longer reads as a permission denial. - list returned errorDetail, a 4KB installer log tail per failed build, on every call. errorMessage is the classified summary and is all the tool prompt advertises. - buildSpecUpdate now returns a result instead of throwing, dropping the SandboxDependencyError class, the rethrowing bridge helper, and both try/catch blocks. - Model-supplied dependencies are type-checked once before dispatch rather than per branch; the language error copy derives from SANDBOX_LANGUAGES. - Create logging moved into the operations layer so the tool's creates are logged too, and the route no longer carries a logger. - manage_sandbox was missing from the chat tool-icon map and fell through to the mothership Blimp fallback.
- Gate writes with copilotToolCanAdmin(context.userPermission), the admin sibling of the copilotToolCanWrite helper manage_custom_tool and manage_skill already use, instead of a second DB permission read. The tool now declares RequiredPermission "write", so the executor has already resolved the caller's permission by the time the handler runs. - Trim comments that restated the code, per the family's near-zero density.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Sandbox create/update/delete logic is moved out of the API route handlers into Also wires Reviewed by Cursor Bugbot for commit df6159d. Configure here. |
|
Greptile SummaryAdds Copilot support for listing and managing workspace sandboxes while consolidating REST and Copilot mutations behind shared operations.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains; the previously reported listing restriction was explicitly confirmed as intentional and consistent with the established management-tool permission model.
|
| Filename | Overview |
|---|---|
| apps/sim/lib/copilot/tools/handlers/management/manage-sandbox.ts | Implements the Copilot-facing list and mutation handler with server-scoped workspace access and REST-equivalent mutation gates. |
| apps/sim/lib/execution/remote-sandbox/workspace-sandboxes.ts | Centralizes validated sandbox creation, update, deletion, build scheduling, cache invalidation, and typed failures. |
| apps/sim/app/api/workspaces/[id]/sandboxes/route.ts | Refactors collection routes to delegate sandbox creation and listing authorization to shared operations. |
| apps/sim/app/api/workspaces/[id]/sandboxes/[sandboxId]/route.ts | Refactors update and delete routes to use the shared mutation operations and failure mapping. |
| apps/sim/lib/copilot/generated/tool-catalog-v1.ts | Registers the new asynchronous management tool with the same intentional tool-wide write gate used by sibling management tools. |
Sequence Diagram
sequenceDiagram
participant Model as Copilot
participant Exec as Tool Executor
participant Handler as manage_sandbox
participant Gate as Auth/Billing/Rate Limit
participant Ops as Workspace Sandbox Operations
participant DB as Database
participant Registry as Image Registry
Model->>Exec: manage_sandbox(operation, arguments)
Exec->>Exec: Enforce catalog write permission
Exec->>Handler: Server execution context
alt list
Handler->>Ops: listWorkspaceSandboxes(workspaceId)
Ops->>DB: Read workspace sandboxes
DB-->>Ops: Sandbox rows
Ops-->>Handler: Sandboxes
Handler-->>Model: Sanitized list
else add/edit/delete
Handler->>Gate: Require admin, entitlement, mutation budget
Gate-->>Handler: Allowed
Handler->>Ops: Shared mutation(workspaceId, arguments)
Ops->>DB: Validate and persist
Ops->>Registry: Schedule/release image as needed
Ops-->>Handler: Sandbox or typed failure
Handler-->>Model: Tool-specific result
end
Reviews (2): Last reviewed commit: "refactor(copilot): align manage_sandbox ..." | Re-trigger Greptile
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit df6159d. Configure here.
Summary
Adds the sim-side handler for the new
manage_sandboxmothership tool, so agents can create, edit, delete, and list a workspace's sandboxes — the named dependency sets Function blocks import third-party packages from. Previously these could only be managed in Settings > Sandboxes.Companion: https://github.com/simstudioai/mothership/pull/395
Follows the
manage_custom_tool/manage_mcp_tool/manage_skillprecedent: handler underlib/copilot/tools/handlers/management/, wired throughregister-handlers.ts, title intool-display.ts, icon in the chat tool-icon map.Sandbox writes are gated exactly as the REST routes gate them — workspace admin, then the Max/Enterprise entitlement, then the same per-workspace mutation bucket — so chat cannot create a sandbox the same user could not create in the UI.
workspaceIdcomes from server context only, never from the model.Create/update/delete moved out of the two route files into
workspace-sandboxes.tsas shared operations returning a typed failure that each caller renders for its own surface: the routes map it to 409/400/404, the tool to a sentence. The routes previously owned the name-conflict pre-check, the unique-index race catch, the unconditional build enqueue, and the detached image release — sharing them is what stops the tool drifting from the UI.Type of Change
Testing
lib/copilot,lib/execution/remote-sandbox, andapp/api/workspacestsc --noEmitclean;lint:check23/23 (the 9 warnings are pre-existing inzoho-desk.test.ts)check:api-validation:strict,check:boundaries,check:utils,check:client-boundary,check:tool-registry-boundaryall passReviewers should focus on the permission gate in
manage-sandbox.tsand the name/dependency validation inworkspace-sandboxes.ts.One real bug was found and fixed during review:
updateWorkspaceSandboxtreated a whitespace-only name as supplied, so it trimmed to empty, skipped the (falsy) conflict pre-check, and wrote an unnamed sandbox the UI cannot produce. Name validation now reuses the contract's ownsandboxNameSchema, so the tool path — which has no schema in front of it — cannot accept a name the REST path rejects. The regression test was confirmed to fail against the original code.Not yet exercised against a live mothership turn; the natural check is asking Sim to add a Python sandbox with
requestsand confirming it appears in Settings > Sandboxes with a build status.Checklist