Skip to content

feat(copilot): let the mothership manage workspace sandboxes - #6239

Open
waleedlatif1 wants to merge 3 commits into
stagingfrom
worktree-sandbox-crud-tools
Open

feat(copilot): let the mothership manage workspace sandboxes#6239
waleedlatif1 wants to merge 3 commits into
stagingfrom
worktree-sandbox-crud-tools

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

Adds the sim-side handler for the new manage_sandbox mothership 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_skill precedent: handler under lib/copilot/tools/handlers/management/, wired through register-handlers.ts, title in tool-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. workspaceId comes from server context only, never from the model.

Create/update/delete moved out of the two route files into workspace-sandboxes.ts as 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

  • New feature

Testing

  • 127 test files / 1516 tests pass across lib/copilot, lib/execution/remote-sandbox, and app/api/workspaces
  • New: 19 handler tests (auth, entitlement, rate limit, per-operation validation) and 8 operations tests
  • tsc --noEmit clean; lint:check 23/23 (the 9 warnings are pre-existing in zoho-desk.test.ts)
  • check:api-validation:strict, check:boundaries, check:utils, check:client-boundary, check:tool-registry-boundary all pass

Reviewers should focus on the permission gate in manage-sandbox.ts and the name/dependency validation in workspace-sandboxes.ts.

One real bug was found and fixed during review: 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 validation now 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 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 requests and confirming it appears in Settings > Sandboxes with a build status.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

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.
@vercel

vercel Bot commented Aug 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Aug 4, 2026 3:56am

Request Review

@cursor

cursor Bot commented Aug 4, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches sandbox authoring (build scheduling, image release, name conflicts) on a shared code path used by both UI and copilot; permission and entitlement gates are mirrored but worth verifying on write operations.

Overview
Adds the manage_sandbox copilot tool so agents can list, create, edit, and delete workspace sandboxes (dependency sets for Function blocks), matching what Settings > Sandboxes already allows. Writes use the same gates as the REST API: workspace admin, Max/Enterprise entitlement, and the shared mutation rate limit; workspaceId is taken only from server context, not model args.

Sandbox create/update/delete logic is moved out of the API route handlers into workspace-sandboxes.ts, returning typed SandboxWriteFailure results. Routes map those to HTTP via sandboxFailureResponse; the tool maps them to user-facing strings. Name rules reuse exported sandboxNameSchema so the tool cannot accept names the REST contract would reject (including the whitespace-only name bug on edit).

Also wires copilotToolCanAdmin, tool catalog/schemas, handler registration, chat display titles/icons, and tests for the handler and shared operations.

Reviewed by Cursor Bugbot for commit df6159d. Configure here.

@github-actions github-actions Bot added the requires-mothership-merge Has a companion PR on the mothership/copilot side — merge in lockstep label Aug 4, 2026
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

⚠️ Cross-repo companion check

One or more companion PRs aren't merged into staging yet. Merging this without them will leave copilot and sim out of sync — merge them in lockstep.

  • simstudioai/mothership#395OPEN, not merged (targets staging) — feat(tools): manage_sandbox — CRUD for workspace sandboxes

@greptile-apps

greptile-apps Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds Copilot support for listing and managing workspace sandboxes while consolidating REST and Copilot mutations behind shared operations.

  • Registers and displays the new manage_sandbox tool.
  • Enforces server-derived workspace scope, admin authorization, plan entitlement, and workspace mutation limits.
  • Extracts validated create, update, and delete behavior into shared workspace-sandbox operations.
  • Preserves REST-specific failure responses and adds handler and operation coverage.

Confidence Score: 5/5

The 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.

Important Files Changed

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
Loading

Reviews (2): Last reviewed commit: "refactor(copilot): align manage_sandbox ..." | Re-trigger Greptile

Comment thread apps/sim/lib/copilot/generated/tool-catalog-v1.ts
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

requires-mothership-merge Has a companion PR on the mothership/copilot side — merge in lockstep

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant