Files
openagent/docs/WORKSPACE_API.md
2026-01-18 11:25:34 +00:00

12 KiB

Workspace API

All endpoints require authentication via Authorization: Bearer <token> header.

List Workspaces

GET /api/workspaces

Response: Array of Workspace objects (see below).

Create a Workspace

POST /api/workspaces

Body:

{
  "name": "my-workspace",
  "workspace_type": "host",
  "path": "/path/to/workspace",
  "skills": ["skill-name"],
  "tools": ["tool-name"],
  "plugins": ["plugin-id"],
  "template": "template-name",
  "distro": "ubuntu-noble",
  "env_vars": {"KEY": "VALUE"},
  "init_script": "#!/bin/bash\napt install -y nodejs"
}
Field Type Required Description
name string Yes Human-readable workspace name
workspace_type string No host or chroot (default: host)
path string No Custom working directory path
skills string[] No Library skill names to sync
tools string[] No Library tool names to sync
plugins string[] No Plugin identifiers for hooks
template string No Template name (forces chroot type)
distro string No Linux distro for containers
env_vars object No Environment variables
init_script string No Script to run on container build

Distro options: ubuntu-noble, ubuntu-jammy, debian-bookworm, arch-linux

Response: Workspace object.

Get Workspace Details

GET /api/workspaces/:id

Response: Workspace object.

Update Workspace

PUT /api/workspaces/:id

Body (all optional):

{
  "name": "new-name",
  "skills": ["skill-1", "skill-2"],
  "tools": ["tool-1"],
  "plugins": ["plugin-id"],
  "template": "template-name",
  "distro": "ubuntu-noble",
  "env_vars": {"KEY": "VALUE"},
  "init_script": "#!/bin/bash\napt install -y nodejs"
}

Response: Workspace object.

Delete Workspace

DELETE /api/workspaces/:id

Deletes the workspace. For container workspaces, this also destroys the container.

Note: The default host workspace (nil UUID) cannot be deleted.

Build Container

POST /api/workspaces/:id/build

Builds or rebuilds a container workspace. Only valid for chroot type workspaces.

Body (optional):

{
  "distro": "ubuntu-noble",
  "rebuild": true
}
Field Type Description
distro string Override the distro for this build
rebuild boolean Force rebuild even if container exists

Build runs in background. Poll workspace status to check completion.

Response: Workspace object with status: "building".

Sync Skills/Tools

POST /api/workspaces/:id/sync

Manually syncs the workspace's skills and tools from the library to the .opencode/ directory.

Response: Workspace object.

Note: Mission workspaces also generate backend-specific config on execution:

  • OpenCode: .opencode/opencode.json (and opencode.json in the workspace root)
  • Claude Code: .claude/settings.local.json + CLAUDE.md

Execute Command

POST /api/workspaces/:id/exec

Execute a shell command in the workspace. For container workspaces, runs inside the container via systemd-nspawn.

Body:

{
  "command": "ls -la",
  "cwd": "subdirectory",
  "timeout_secs": 60,
  "env": {"MY_VAR": "value"},
  "stdin": "input data"
}
Field Type Required Description
command string Yes Shell command to execute
cwd string No Working directory (relative or absolute)
timeout_secs number No Timeout in seconds (default: 300, max: 600)
env object No Additional environment variables
stdin string No Input to pass to stdin

Response:

{
  "exit_code": 0,
  "stdout": "file1.txt\nfile2.txt\n",
  "stderr": "",
  "timed_out": false
}

Examples:

# List files
curl -X POST "http://localhost:3000/api/workspaces/{id}/exec" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"command": "ls -la"}'

# Run with custom environment
curl -X POST "http://localhost:3000/api/workspaces/{id}/exec" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"command": "echo $MY_VAR", "env": {"MY_VAR": "hello"}}'

# Install packages in container
curl -X POST "http://localhost:3000/api/workspaces/{id}/exec" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"command": "apt install -y nodejs", "timeout_secs": 120}'

Open Shell (WebSocket)

GET /api/workspaces/:id/shell

Opens an interactive PTY shell session via WebSocket.

Authentication: Use Sec-WebSocket-Protocol: openagent header with JWT token.

Note: For programmatic command execution, prefer the /exec HTTP endpoint.


Debug Endpoints (Template Development)

These endpoints help debug init script issues when developing workspace templates.

Get Debug Info

GET /api/workspaces/:id/debug

Returns detailed information about the container state, useful for understanding why an init script might be failing.

Response:

{
  "id": "uuid",
  "name": "minecraft",
  "status": "error",
  "path": "/root/.openagent/containers/minecraft",
  "path_exists": true,
  "size_bytes": 1234567890,
  "directories": [
    {"path": "bin", "exists": true, "file_count": 156},
    {"path": "usr", "exists": true, "file_count": 12},
    {"path": "etc", "exists": true, "file_count": 45},
    {"path": "var", "exists": true, "file_count": 8},
    {"path": "var/log", "exists": true, "file_count": 3},
    {"path": "root", "exists": true, "file_count": 2},
    {"path": "tmp", "exists": true, "file_count": 0}
  ],
  "has_bash": true,
  "init_script_exists": false,
  "init_script_modified": null,
  "distro": "ubuntu-noble",
  "last_error": "Init script failed: E: Unable to correct problems..."
}
Field Type Description
path_exists boolean Whether the container directory exists
size_bytes number Total size of container in bytes
directories array Key directories and their file counts
has_bash boolean Whether /bin/bash is available
init_script_exists boolean Whether the init script file exists
init_script_modified string Last modification time of init script
last_error string Error message from last build attempt

Get Init Script Log

GET /api/workspaces/:id/init-log

Reads the init script log from /var/log/openagent-init.log inside the container.

Response:

{
  "exists": true,
  "content": "Starting init script\nRunning apt-get update...\n...",
  "total_lines": 1234,
  "log_path": "/var/log/openagent-init.log"
}

Note: Returns the last 500 lines if the log is larger.

Re-run Init Script

POST /api/workspaces/:id/rerun-init

Re-runs the init script without rebuilding the container from scratch. This is much faster for iterating on init script development.

Requirements:

  • Workspace must be chroot type
  • Container must already exist (debootstrap completed)
  • Workspace must have an init script configured

Response:

{
  "success": false,
  "exit_code": 1,
  "stdout": "Starting init script\nRunning apt-get update...\n...",
  "stderr": "",
  "duration_secs": 45.3
}
Field Type Description
success boolean Whether the script completed successfully
exit_code number Exit code from the script
stdout string Standard output from the script
stderr string Standard error from the script
duration_secs number How long the script took to run

Debug Workflow Example

# 1. Check current container state
curl "http://localhost:3000/api/workspaces/{id}/debug" \
  -H "Authorization: Bearer <token>"

# 2. View the init script log
curl "http://localhost:3000/api/workspaces/{id}/init-log" \
  -H "Authorization: Bearer <token>"

# 3. Update the template with a fix
curl -X PUT "http://localhost:3000/api/library/workspace-template/my-template" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"init_script": "#!/bin/bash\n# fixed script..."}'

# 4. Update workspace to use new init script
curl -X PUT "http://localhost:3000/api/workspaces/{id}" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"init_script": "#!/bin/bash\n# fixed script..."}'

# 5. Re-run the init script (fast iteration)
curl -X POST "http://localhost:3000/api/workspaces/{id}/rerun-init" \
  -H "Authorization: Bearer <token>"

# 6. If it works, do a full rebuild to verify
curl -X POST "http://localhost:3000/api/workspaces/{id}/build?rebuild=true" \
  -H "Authorization: Bearer <token>"

Workspace Templates

Templates are stored in the library and define reusable workspace configurations.

List Templates

GET /api/library/workspace-template

Response:

[
  {
    "name": "nodejs-dev",
    "description": "Node.js development environment",
    "path": "workspace-template/nodejs-dev.json"
  }
]

Get Template

GET /api/library/workspace-template/:name

Response:

{
  "name": "nodejs-dev",
  "description": "Node.js development environment",
  "path": "workspace-template/nodejs-dev.json",
  "distro": "ubuntu-noble",
  "skills": ["typescript-dev"],
  "env_vars": {"NODE_ENV": "development"},
  "init_script": "#!/bin/bash\napt install -y nodejs npm"
}

Save Template

PUT /api/library/workspace-template/:name

Body:

{
  "description": "Node.js development environment",
  "distro": "ubuntu-noble",
  "skills": ["typescript-dev"],
  "env_vars": {"NODE_ENV": "development"},
  "init_script": "#!/bin/bash\napt install -y nodejs npm"
}

Delete Template

DELETE /api/library/workspace-template/:name

Workspace Object

{
  "id": "uuid",
  "name": "my-workspace",
  "workspace_type": "chroot",
  "path": "/path/to/workspace",
  "status": "ready",
  "error_message": null,
  "created_at": "2025-01-13T10:00:00Z",
  "skills": ["skill-1"],
  "tools": ["tool-1"],
  "plugins": ["plugin-id"],
  "template": "nodejs-dev",
  "distro": "ubuntu-noble",
  "env_vars": {"KEY": "VALUE"},
  "init_script": "#!/bin/bash\n..."
}

Workspace Types

Type Description
host Executes commands directly on the host machine
chroot Executes commands in an isolated container (systemd-nspawn)

Workspace Status

Status Description
pending Container not yet built
building Container build in progress
ready Workspace is ready for use
error Build failed (see error_message)

Workflow Examples

Create and Build a Container Workspace

# 1. Create the workspace
curl -X POST "http://localhost:3000/api/workspaces" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-dev-env",
    "workspace_type": "chroot",
    "distro": "ubuntu-noble",
    "skills": ["python-dev"],
    "init_script": "#!/bin/bash\napt install -y python3 python3-pip"
  }'

# 2. Build the container
curl -X POST "http://localhost:3000/api/workspaces/{id}/build" \
  -H "Authorization: Bearer <token>"

# 3. Poll until ready
curl "http://localhost:3000/api/workspaces/{id}" \
  -H "Authorization: Bearer <token>"
# Wait for status: "ready"

# 4. Execute commands
curl -X POST "http://localhost:3000/api/workspaces/{id}/exec" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"command": "python3 --version"}'

Create Workspace from Template

# 1. List available templates
curl "http://localhost:3000/api/library/workspace-template" \
  -H "Authorization: Bearer <token>"

# 2. Create workspace using template
curl -X POST "http://localhost:3000/api/workspaces" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "nodejs-project",
    "template": "nodejs-dev"
  }'

# 3. Build and use as shown above

Update Workspace Skills

# Add new skills to workspace
curl -X PUT "http://localhost:3000/api/workspaces/{id}" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"skills": ["python-dev", "rust-dev"]}'

# Force sync skills to .opencode/
curl -X POST "http://localhost:3000/api/workspaces/{id}/sync" \
  -H "Authorization: Bearer <token>"