refactor!: rename Computer "environments" to sandbox "images"

Merged
CH
3mo ago
+1197-959

Frees the word "environment" so it means exactly one thing.

BREAKING — public v1 path, @mcpjam/sdk PlatformClient, MCP operation names, and the mcpjam env CLI command all rename with no alias and no deprecation window, per your call that this surface has no consumers.

Why

"Environment" meant two unrelated things:

  • a Project Environment — a client + server group + skill/plugin bundle that eval suites and journeys run against;
  • a Computer environment — a Dockerfile built into an immutable E2B image a Computer boots from.

The second one owned the word in the CLI, the public API, the SDK, and the MCP tool names — while the UI had already relabelled it "Sandbox images" specifically to get out of the way (SandboxImagesDrawer, and the run-detail chip). This finishes that move.

image is the OCI term and what these are; it matches Docker, Modal, Fly, AMI. Deliberately not E2B's "template" — leaking a provider's vocabulary into our public API is a liability if we move off E2B, and "template" implies something you copy and edit rather than a digest-pinned base.

What changed

surfacebeforeafter
v1 path/projects/:projectId/computer-environments/projects/:projectId/images
v1 path param:environmentId:imageId
SDK typesPlatformEnvironment*PlatformImage*
SDK methodslistEnvironments, buildEnvironment, …listImages, buildImage, …
MCP operationslist_computer_environments, …list_sandbox_images, …
CLImcpjam env, --environmentmcpjam images, --image
OpenAPIComputerEnvironment* schemas + operationIdsSandboxImage*
clientuseComputerEnvironments, EnvironmentsDrawer, EnvironmentViewuseSandboxImages, SandboxImagesDrawer, SandboxImageView

The client rename is the point, not scope creep

EnvironmentView was exported by both concepts, and suite-iterations-view.tsx imported useEnvironments (images) two lines above useProjectEnvironmentsEnabled (the new concept). That is exactly the collision this rename exists to remove, so leaving the client for later would have been a half-job.

Deliberately NOT renamed

The Convex function literals — computerEnvironments:getEnvironment and friends. That module lives in mcpjam-backend and was not touched, so these strings must keep matching it exactly. They are a cross-repo contract, not local style.

I hit this during the rename: a blanket sweep rewrote them to sandboxImages:*, which would have broken every call at runtime with no compile error. The route header now says so explicitly so nobody "tidies" them back. Renaming the Convex table is a separate, migration-bearing change.

Verification

  • SDK builds clean; client typecheck clean
  • server tsc 85 errors — byte-identical to the pre-existing baseline, measured by stashing
  • inspector suite 9,683 passed / 0 failures; v1 images route tests 22 passed
  • the one failing SDK test (browser-entry-guard, xaa import graph) fails identically on a clean tree — pre-existing

🤖 Generated with Claude Code


[!NOTE]
High Risk
Wide breaking API/CLI/SDK rename with no aliases; any external caller on old paths or field names will fail. Attach response field change (imageId) is a contract break for generated clients.

Overview
Breaking rename so “environment” is reserved for Project Environments (client + servers + skills bundles). Custom Computer Dockerfile images are now sandbox images everywhere public.

The v1 API moves from /projects/:projectId/computer-environments to /images with :imageId. OpenAPI schemas and tags become SandboxImage*. The use attach response now exposes imageId instead of environmentId (tests lock that the old field is gone).

SDK / CLI: PlatformEnvironment* → PlatformImage*, *ImageOperation / listImages, buildImage, etc. CLI is mcpjam images with --image (replacing env / --environment).

Inspector client: useSandboxImages, SandboxImagesDrawer, SandboxImageView; Computer and eval views updated to the new hooks. Convex call strings stay computerEnvironments:* — documented as a cross-repo backend contract.

Route module is images.ts; project-scope guard and guest deny behavior are unchanged in intent, with route tests updated for the new paths and imageId response shape.

Reviewed by Cursor Bugbot for commit 07b06c594b0e84681582d3ff5d6cec45c7ab39da. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Renamed Computer “environments” to sandbox “images” across API, SDK, CLI, MCP ops, and client so “environment” refers only to Project Environments. Breaking change with no aliases; this removes client naming collisions and uses the OCI term.

  • Refactors

    • API: v1 path is /projects/:projectId/images with :imageId; OpenAPI tags/schemas now SandboxImage*; attach/use now returns imageId (not environmentId).
    • SDK (@mcpjam/sdk/platform): types PlatformImage*; operations renamed to listImages, getImage, createImage, updateImage, deleteImage, buildImage, promoteImage, useImage; PlatformComputerAttached now exposes imageId.
    • MCP + CLI: ops renamed to *_sandbox_image*; CLI command is mcpjam images with --image; CLI docs updated to the new command group.
    • Client: hooks useSandboxImages; SandboxImagesDrawer; related views/tests updated.
    • Not changed on purpose: Convex function literals computerEnvironments:* remain to preserve the backend contract.
  • Bug Fixes

    • Repaired docs/sandbox-images-ui-cli.md after a blanket rename corrupted identifiers; limited changes to public surfaces and explicitly documented the unchanged computerEnvironments:* function names.
    • Completed user-facing copy in SandboxImagesDrawer (labels, toasts, empty states) and updated tests to match.