devboxes

Set up a Project's workspace

A Project's workspace holds what its agents need to install, build, test, and run your repository.

Give agents the tools your repository needs

A Project's workspace contains the packages and services that your repository needs, for example a database. You find packages in devboxes Nixhub, which lists the packages that a workspace can include.

To do it yourself, set the workspace with images.configure. packages lists Nixhub package names, and services lists the services that run in the workspace:

workspace.json
{
  "organizationId": "<organization id>",
  "projectId": "<project id>",
  "packages": ["nodejs_24", "pnpm_10"],
  "services": [
    { "name": "postgresql", "package": "postgresql_17" },
    { "name": "redis", "package": "redis" }
  ]
}
devboxes invoke images.configure --input @workspace.json

devboxes rejects a package that Nixhub does not list, an unfree package, and a broken or insecure package. images.inspect shows when the new workspace is ready. Until then, tasks run on the Project's current workspace. When a task needs something the new workspace adds, pass awaitWorkspaceImage: true to sessions.dispatch or sessions.continue. sessions.inspect then shows its Run as queued with queueReason set to workspace_image, and the task starts on the new workspace once it is ready. When the build fails, images.inspect says why, and the waiting tasks start on the current workspace. Their agent's first prompt says what the new workspace would have added and why it failed, so the agent can install what the work needs itself. devboxes doesn't build a failed new workspace again by itself: run images.configure again to retry or change it.

A Project's first workspace has no earlier one, so every task waits for it. When that build fails on devboxes' side, devboxes builds it again by itself while tasks wait: once whenever devboxes updates its image builder, and otherwise up to three times, 5, 15 and 45 minutes after a failure. After those tries, run images.configure with the same packages and services to try again before the next update. When the image builder rejected the packages or services, the tasks wait until a later images.configure builds; devboxes tries the rejected list once more whenever it updates its image builder. The tasks start on the first workspace that builds.

When a package has a critical security fix that Nixhub doesn't list yet, devboxes builds the fixed release into every workspace that lists the package, with the same packages and services. Tasks run on the current workspace until the rebuilt one is ready.

People in a chat channel can ask devboxes for these tools too. See Workspaces set up from Chat.

devboxes starts the services before the agent works and gives the agent their connection settings:

ServiceEnvironment variables
postgresqlDATABASE_URL=postgresql://[email protected]:5432/postgres, PGHOST, PGPORT, PGUSER, PGDATABASE
redisREDIS_URL=redis://127.0.0.1:6379

A Project variable with the same name overrides a service's value. When a service exits before it is ready, the task fails and names the service, its exit code or signal, and its last output. When a service exits after it is ready, sessions.events shows the same facts. The agent gets them during its running turn, or with the next agent node's instructions. When no agent node follows, the message starts no turn.

Keep downloaded tools between tasks

A task starts in a fresh workspace. devboxes keeps the directories in toolCachePaths for the Project, so a task doesn't download again what an earlier task already downloaded: an Android SDK, Gradle and Maven dependencies, the npm cache. Paths are relative to the home directory. A new Project caches the common SDK and dependency directories; projects.list shows the current list. A path can't contain or lie inside another listed path or one of OpenCode's own directories: .config/opencode, .local/share/opencode, .cache/opencode and .local/state/opencode.

A task that writes code or fixes a Review's findings starts with the saved directories and saves the ones that changed when it ends. A Review starts without them, because it reads only the code. When two tasks change the same directory, the first to end keeps its copy. devboxes doesn't save a directory that holds the value of a secret marked sensitive. Gradle's lock files and journal are never saved. A cancelled task saves nothing. When the task's agent starts, its first prompt says what was restored and which directories are saved. The task's events show what was saved, and why a directory wasn't, for example when its copy is larger than the object store accepts in one upload, or larger than 500 MB on Free.

projects.list shows the saved directories' copies and their sizes in toolCache. To drop a directory's saved copy, remove it from toolCachePaths with projects.configure. Add it again to start it fresh.

Terms of ServicePrivacy Policy

On this page