Skip to content

Sandbox Internal API #283

@jrf0110

Description

@jrf0110

Part of #271 — Gastown Cloud Proposal A (Sandbox-per-Town)

Goal

Build a lightweight HTTP server that runs inside the gastown sandbox, providing control-plane communication between the cloud app and the gt binary / tmux / Dolt.

Context

The cloud app needs to send commands to the sandbox (add rig, send message to Mayor, query Dolt, stream terminal output). KiloClaw uses SSH + Fly proxy for this. For gastown, a purpose-built API server is cleaner and gives structured access to gastown state.

Requirements

Endpoints

Route Method Description Implementation
/health GET Daemon running? Dolt healthy? Tmux alive? Check PID files, dolt sql -q "SELECT 1", tmux ls
/rigs GET List rigs from gt config Parse gt rig list --json
/rigs POST Add a rig Run gt rig add <repo> --name <name>
/rigs/:name/beads GET Query beads for a rig SQL query against Dolt: SELECT * FROM beads WHERE ...
/rigs/:name/convoys GET Query convoys for a rig SQL query against Dolt
/rigs/:name/polecats GET List active polecats Parse tmux ls filtered by rig prefix
/message POST Inject text into a tmux session tmux send-keys -t <session> <text> Enter
/sessions GET List all tmux sessions with pane content tmux ls + tmux capture-pane -p -t <session>
/sessions/:name/stream WebSocket Stream tmux pane output Placeholder — implemented in PR 7
/sync POST Trigger immediate R2 backup Signal the R2 sync daemon (placeholder until PR 4)
/config PATCH Update gt config (models, max_polecats, etc.) Write to ~/gt/settings/config.json and rig configs

Auth

  • x-internal-api-key header — shared secret provisioned as encrypted env var
  • Reject all requests without valid key
  • Same pattern as KiloClaw's internal API auth

Implementation

  • Language: Node.js (already in the sandbox image) or Go (if we want a small static binary)
  • Runs on a fixed port (e.g., 8080) inside the sandbox
  • Started by startup.sh (from PR 1)
  • Dolt queries via dolt sql -q CLI or direct SQL connection to Dolt server (localhost:3306)

Files

  • cloud/infra/gastown-sandbox/internal-api/ (new directory)
    • server.ts or main.go — HTTP server
    • routes/ — route handlers
    • package.json or go.mod

Error Handling

  • All endpoints return structured JSON: { ok: boolean, data?: ..., error?: string }
  • If gt commands fail, return stderr in the error field
  • If Dolt is unreachable, /health reports it and Dolt-dependent endpoints return 503

Acceptance Criteria

  • Server starts on port 8080 and responds to /health
  • /health reports daemon status, Dolt status, and tmux session count
  • /rigs GET returns rig list from gt config
  • /rigs POST successfully adds a rig (or returns error if gt fails)
  • /rigs/:name/beads returns beads from Dolt
  • /message injects text into a tmux session
  • /sessions lists tmux sessions with current pane content
  • /config PATCH updates gt config files
  • All endpoints reject requests without valid x-internal-api-key
  • Structured JSON error responses on failure
  • Server is added to the Docker image (PR 1) and started by startup.sh

Dependencies

  • PR 1 (Sandbox Docker Image) — startup.sh launches this server
  • PR 2 (Provisioning API) — cloud app calls this server via Fly proxy

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions