Documentation
¶
Overview ¶
Package boxxkite is a Go client for a hosted boxxkite control-plane -- the same v1 HTTP API sdk-python's BoxxkiteClient and sdk-js's BoxxkiteClient wrap (see docs/API.md in the boxxkite repo). It is a thin request/response client: create sandboxes, run commands, edit files, stream the audit log, take over a sandbox's shell over a WebSocket -- all over HTTP against *someone else's* running control-plane. It is not a client for the boxxkite package itself (SandboxManager, embedded directly against a Kubernetes cluster).
Index ¶
- Constants
- func Ptr[T any](v T) *T
- type APIError
- type Account
- type AllowedCommandRule
- type AllowedCommandsResponse
- type CapabilityDeniedError
- type Client
- func (c *Client) Account(ctx context.Context) (*Account, error)
- func (c *Client) ClearAllowedCommands(ctx context.Context) error
- func (c *Client) ConfirmPasswordReset(ctx context.Context, token, newPassword string) (*MessageResponse, error)
- func (c *Client) CreateImage(ctx context.Context, req CreateImageRequest) (*Image, error)
- func (c *Client) CreateMCPConnection(ctx context.Context, label, catalogID string) (*MCPConnection, error)
- func (c *Client) CreatePreviewURL(ctx context.Context, sessionID string, port int, ttlSeconds *int) (*PreviewURL, error)
- func (c *Client) CreateSandbox(ctx context.Context, req CreateSandboxRequest) (*Sandbox, error)
- func (c *Client) CreateSandboxes(ctx context.Context, req CreateSandboxRequest) ([]Sandbox, error)
- func (c *Client) CreateSecret(ctx context.Context, req CreateSecretRequest) (*Secret, error)
- func (c *Client) CreateVolume(ctx context.Context, req CreateVolumeRequest) (*Volume, error)
- func (c *Client) CreateWebhook(ctx context.Context, req CreateWebhookRequest) (*Webhook, error)
- func (c *Client) DeleteImage(ctx context.Context, imageID string) error
- func (c *Client) DeleteMCPConnection(ctx context.Context, connectionID string) error
- func (c *Client) DeleteSecret(ctx context.Context, secretID string) error
- func (c *Client) DeleteVolume(ctx context.Context, volumeID string) error
- func (c *Client) DeleteWebhook(ctx context.Context, subscriptionID string) error
- func (c *Client) DesktopTakeover(ctx context.Context, sessionID string) (*websocket.Conn, error)
- func (c *Client) DestroySandbox(ctx context.Context, sessionID string) error
- func (c *Client) Exec(ctx context.Context, sessionID, command string, opts *ExecOptions) (*ExecResult, error)
- func (c *Client) ExportMemories(ctx context.Context, scope string) (map[string]any, error)
- func (c *Client) FileCreate(ctx context.Context, sessionID, path, content string, opts *FileOptions) (*FileCreateResult, error)
- func (c *Client) ForgetMemory(ctx context.Context, memoryID string) error
- func (c *Client) GetAllowedCommands(ctx context.Context) (*AllowedCommandsResponse, error)
- func (c *Client) GetImage(ctx context.Context, imageID string) (*Image, error)
- func (c *Client) GetLog(ctx context.Context, sessionID string, opts *GetLogOptions) (*GetLogResult, error)
- func (c *Client) GetMemory(ctx context.Context, memoryID string) (*Memory, error)
- func (c *Client) GetProcessOutput(ctx context.Context, sessionID, processID string, sinceOffset int64) (*ProcessOutputResult, error)
- func (c *Client) GetSandbox(ctx context.Context, sessionID string) (*Sandbox, error)
- func (c *Client) GetVolume(ctx context.Context, volumeID string) (*Volume, error)
- func (c *Client) Glob(ctx context.Context, sessionID, pattern string, path string) (*GlobResult, error)
- func (c *Client) Grep(ctx context.Context, sessionID, pattern string, opts *GrepOptions) (*GrepResult, error)
- func (c *Client) HTTPRequest(ctx context.Context, sessionID, method, targetURL string, ...) (*HTTPRequestResult, error)
- func (c *Client) ImportMemories(ctx context.Context, req ImportMemoriesRequest) (*MemoryIngestResponse, error)
- func (c *Client) IngestMemory(ctx context.Context, req IngestMemoryRequest) (*MemoryIngestResponse, error)
- func (c *Client) ListImages(ctx context.Context) ([]Image, error)
- func (c *Client) ListMCPConnections(ctx context.Context) ([]MCPConnection, error)
- func (c *Client) ListMemories(ctx context.Context, opts ListMemoriesOptions) ([]Memory, error)
- func (c *Client) ListProcesses(ctx context.Context, sessionID string) (*ProcessListResult, error)
- func (c *Client) ListSandboxes(ctx context.Context, activeOnly bool) ([]Sandbox, error)
- func (c *Client) ListSecrets(ctx context.Context) ([]Secret, error)
- func (c *Client) ListVolumes(ctx context.Context) ([]Volume, error)
- func (c *Client) ListWebhookDeliveries(ctx context.Context, subscriptionID string, opts *ListWebhookDeliveriesOptions) ([]WebhookDelivery, error)
- func (c *Client) ListWebhooks(ctx context.Context) ([]Webhook, error)
- func (c *Client) Logout(ctx context.Context, refreshToken string) error
- func (c *Client) Ls(ctx context.Context, sessionID string, path string) (*LsResult, error)
- func (c *Client) MemoryProfile(ctx context.Context, scope string, limit int) (*MemoryProfileResponse, error)
- func (c *Client) MemoryRelations(ctx context.Context, memoryID string, limit int) (*MemoryRelationsResponse, error)
- func (c *Client) Recall(ctx context.Context, query string, opts RecallOptions) (*MemorySearchResponse, error)
- func (c *Client) RefreshToken(ctx context.Context, refreshToken string) (*TokenPair, error)
- func (c *Client) Remember(ctx context.Context, req RememberRequest) (*Memory, error)
- func (c *Client) RequestPasswordReset(ctx context.Context, email string) (*MessageResponse, error)
- func (c *Client) ResendVerification(ctx context.Context, accessToken string) (*MessageResponse, error)
- func (c *Client) RevokePreviewURL(ctx context.Context, sessionID string, port int, tokenID string) (*PreviewRevokeResult, error)
- func (c *Client) SendProcessInput(ctx context.Context, sessionID, processID, data string) (*ProcessInputResult, error)
- func (c *Client) SetAllowedCommands(ctx context.Context, rules []AllowedCommandRule) (*AllowedCommandsResponse, error)
- func (c *Client) StartProcess(ctx context.Context, sessionID, command string, opts *StartProcessOptions) (*ProcessStartResult, error)
- func (c *Client) StopProcess(ctx context.Context, sessionID, processID string) (*ProcessStopResult, error)
- func (c *Client) StrReplace(ctx context.Context, sessionID, path, oldStr, newStr string, ...) (*StrReplaceResult, error)
- func (c *Client) StreamProcessOutput(ctx context.Context, sessionID, processID string, sinceOffset int64) (*ProcessStream, error)
- func (c *Client) Takeover(ctx context.Context, sessionID string) (*websocket.Conn, error)
- func (c *Client) Usage(ctx context.Context) (*Usage, error)
- func (c *Client) VerifyEmail(ctx context.Context, token string) (*MessageResponse, error)
- func (c *Client) View(ctx context.Context, sessionID, path string, opts *ViewOptions) (*FileViewResult, error)
- func (c *Client) Watch(ctx context.Context, sessionID string) (*LogWatcher, error)
- func (c *Client) WithSandbox(ctx context.Context, req CreateSandboxRequest, fn func(*Session) error) error
- type ConnectionError
- type CreateImageRequest
- type CreateSandboxRequest
- type CreateSecretRequest
- type CreateVolumeRequest
- type CreateWebhookRequest
- type DirEntry
- type EgressDeniedError
- type ExecOptions
- type ExecResult
- type FileCreateResult
- type FileOptions
- type FileViewResult
- type GetLogOptions
- type GetLogResult
- type GlobResult
- type GrepMatch
- type GrepOptions
- type GrepResult
- type HTTPRequestOptions
- type HTTPRequestResult
- type Image
- type ImportMemoriesRequest
- type IngestMemoryRequest
- type ListMemoriesOptions
- type ListWebhookDeliveriesOptions
- type LogEntry
- type LogWatcher
- type LsResult
- type MCPConnection
- type Memory
- type MemoryIngestResponse
- type MemoryProfileResponse
- type MemoryRelation
- type MemoryRelationsResponse
- type MemorySearchHit
- type MemorySearchResponse
- type MessageResponse
- type Option
- type PreviewRevokeResult
- type PreviewURL
- type ProcessInfo
- type ProcessInputResult
- type ProcessListResult
- type ProcessOutputResult
- type ProcessStartResult
- type ProcessStopResult
- type ProcessStream
- type ProcessStreamEvent
- type QuotaExceededError
- type ReadonlyFilesystemError
- type RecallOptions
- type RememberRequest
- type RetryConfig
- type Sandbox
- type SandboxConnectInfo
- type SandboxCrashedError
- type SandboxNotReadyError
- type Secret
- type ServiceUnavailableError
- type Session
- func (s *Session) CreatePreviewURL(ctx context.Context, port int, ttlSeconds *int) (*PreviewURL, error)
- func (s *Session) DesktopTakeover(ctx context.Context) (*websocket.Conn, error)
- func (s *Session) Exec(ctx context.Context, command string, opts *ExecOptions) (*ExecResult, error)
- func (s *Session) FileCreate(ctx context.Context, path, content string, opts *FileOptions) (*FileCreateResult, error)
- func (s *Session) GetLog(ctx context.Context, opts *GetLogOptions) (*GetLogResult, error)
- func (s *Session) GetProcessOutput(ctx context.Context, processID string, sinceOffset int64) (*ProcessOutputResult, error)
- func (s *Session) Glob(ctx context.Context, pattern, path string) (*GlobResult, error)
- func (s *Session) Grep(ctx context.Context, pattern string, opts *GrepOptions) (*GrepResult, error)
- func (s *Session) HTTPRequest(ctx context.Context, method, targetURL string, opts *HTTPRequestOptions) (*HTTPRequestResult, error)
- func (s *Session) ListProcesses(ctx context.Context) (*ProcessListResult, error)
- func (s *Session) Ls(ctx context.Context, path string) (*LsResult, error)
- func (s *Session) RevokePreviewURL(ctx context.Context, port int, tokenID string) (*PreviewRevokeResult, error)
- func (s *Session) SendProcessInput(ctx context.Context, processID, data string) (*ProcessInputResult, error)
- func (s *Session) StartProcess(ctx context.Context, command string, opts *StartProcessOptions) (*ProcessStartResult, error)
- func (s *Session) StopProcess(ctx context.Context, processID string) (*ProcessStopResult, error)
- func (s *Session) StrReplace(ctx context.Context, path, oldStr, newStr string, opts *StrReplaceOptions) (*StrReplaceResult, error)
- func (s *Session) Takeover(ctx context.Context) (*websocket.Conn, error)
- func (s *Session) View(ctx context.Context, path string, opts *ViewOptions) (*FileViewResult, error)
- func (s *Session) Watch(ctx context.Context) (*LogWatcher, error)
- type StartProcessOptions
- type StrReplaceOptions
- type StrReplaceResult
- type TokenPair
- type Usage
- type ViewOptions
- type Volume
- type Webhook
- type WebhookDelivery
Examples ¶
Constants ¶
const DefaultTimeout = 30 * time.Second
DefaultTimeout is the default per-request timeout, matching sdk-python/sdk-js's 30-second default.
const ExecTimeoutHeadroom = 15 * time.Second
ExecTimeoutHeadroom is added on top of a caller-supplied exec/http-request timeout so the HTTP client's own deadline never fires before the control-plane's -- mirrors sdk-python's EXEC_TIMEOUT_HEADROOM / sdk-js's EXEC_TIMEOUT_HEADROOM_MS.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type APIError ¶
type APIError struct {
StatusCode int
Code string
Message string
Retryable bool
Remediation string
Details any
Taxonomy string
}
APIError is returned when the control-plane responds with a non-2xx status and an `{"error": {code, message}}` envelope (or, failing that, a synthesized code/message from the bare HTTP status). Mirrors sdk-python's BoxxkiteApiError / sdk-js's BoxxkiteApiError.
type Account ¶
type Account struct {
ID string `json:"id"`
Email string `json:"email"`
CreatedAt string `json:"created_at"`
}
Account is the identity for the API key in use (GET /v1/account).
type AllowedCommandRule ¶
type AllowedCommandRule struct {
Command string `json:"command"`
ArgsAllow []string `json:"args_allow,omitempty"`
ArgsDeny []string `json:"args_deny,omitempty"`
}
AllowedCommandRule is one account-level command allowlist rule -- either a bare command name (Command set, ArgsAllow/ArgsDeny both empty) or a command name plus argument allow/deny regex lists. The control-plane's own schema (AllowedCommandsRequest.rules: list[str | AllowedCommandRule] in control-plane/src/control_plane/schemas.py) accepts and returns rules in either shape -- UnmarshalJSON below decodes both into the same Go struct; MarshalJSON always emits the object form, which the control-plane accepts identically to the bare-string form for a rule with no argument constraints.
func (*AllowedCommandRule) UnmarshalJSON ¶
func (r *AllowedCommandRule) UnmarshalJSON(data []byte) error
UnmarshalJSON accepts either a bare JSON string (a plain command name, no argument constraints) or a JSON object ({"command", "args_allow"?, "args_deny"?}).
type AllowedCommandsResponse ¶
type AllowedCommandsResponse struct {
Rules []AllowedCommandRule `json:"rules"`
}
AllowedCommandsResponse is the body shape shared by GetAllowedCommands/SetAllowedCommands.
type CapabilityDeniedError ¶ added in v0.6.0
type CapabilityDeniedError struct{ APIError }
func (*CapabilityDeniedError) Error ¶ added in v0.6.0
func (e *CapabilityDeniedError) Error() string
func (*CapabilityDeniedError) Unwrap ¶ added in v0.6.0
func (e *CapabilityDeniedError) Unwrap() error
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a synchronous client for a hosted boxxkite control-plane. Safe for concurrent use by multiple goroutines (it holds no mutable state beyond a shared *http.Client).
func NewClient ¶
NewClient constructs a Client for a hosted control-plane at baseURL, authenticating every request with apiKey (a boxxkite account API key, `bxk_live_...`, sent as `Authorization: Bearer <apiKey>`).
baseURL must be https://, or http://localhost (local dev only) -- an apiKey is a full-privilege, long-lived credential, so anything else would put it on the wire in cleartext. Mirrors sdk-python's _validate_base_url_scheme / sdk-js's validateBaseUrlScheme.
func (*Client) ClearAllowedCommands ¶
ClearAllowedCommands removes the per-account command allowlist (DELETE /v1/account/allowed-commands), back to the unrestricted default.
func (*Client) ConfirmPasswordReset ¶
func (c *Client) ConfirmPasswordReset(ctx context.Context, token, newPassword string) (*MessageResponse, error)
ConfirmPasswordReset consumes a single-use token minted by RequestPasswordReset and sets a new password (POST /v1/auth/password-reset/confirm). Also revokes every outstanding refresh token for the account, if refresh tokens are enabled server-side.
func (*Client) CreateImage ¶
CreateImage queues a build of a custom sandbox image (POST /v1/images). Always asynchronous -- returns immediately with Status "queued"; poll GetImage for progress. 404s ("feature_disabled") if the deployment hasn't enabled the declarative builder (BOXXKITE_IMAGE_BUILDER_ENABLED).
func (*Client) CreateMCPConnection ¶
func (c *Client) CreateMCPConnection(ctx context.Context, label, catalogID string) (*MCPConnection, error)
CreateMCPConnection grants this account access to one curated outbound-MCP catalog entry (POST /v1/mcp-connections). label is a unique (per-account) name for this connection -- pass it in CreateSandboxRequest.MCPConnectionNames to grant a session network egress to it. catalogID is one of "slack", "notion", "linear", "github" -- restricted to boxxkite's own reviewed allowlist, never a caller-supplied hostname.
Note: this only widens a granted session's per-pod NetworkPolicy egress allowlist to the connection's catalog hostname -- there is no MCP-proxy transport yet, so this does not yet let an agent speak MCP protocol to the destination.
func (*Client) CreatePreviewURL ¶
func (c *Client) CreatePreviewURL(ctx context.Context, sessionID string, port int, ttlSeconds *int) (*PreviewURL, error)
CreatePreviewURL mints a signed, time-limited URL that proxies HTTP traffic to a port a background process opened inside this session (see StartProcessOptions.ExposePort) (POST /v1/sandboxes/{id}/preview/{port}). The returned URL carries its own authorization -- no API key is required to use it, only to mint it.
ttlSeconds bounds how long the minted URL stays valid (30-86400). Defaults to 900 (15 minutes) server-side when nil.
func (*Client) CreateSandbox ¶
CreateSandbox creates a new sandbox session (POST /v1/sandboxes), or a batch of sandbox sessions when req.Count is greater than 1. Each session in a batch is created and limit-checked one at a time, so a later item can still fail the concurrent-sandbox or monthly-usage cap even if earlier items succeeded -- see CreateSandboxes for the batch form.
Example ¶
mux := http.NewServeMux()
mux.HandleFunc("/v1/sandboxes", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, `{"id":"sbx_123","status":"running","label":"demo","created_at":"2026-01-01T00:00:00Z"}`)
})
client, server := exampleServer(mux)
defer server.Close()
sandbox, err := client.CreateSandbox(context.Background(), CreateSandboxRequest{Label: Ptr("demo")})
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println(sandbox.Status)
Output: running
func (*Client) CreateSandboxes ¶
CreateSandboxes creates a batch of sandbox sessions in one call (POST /v1/sandboxes with req.Count > 1) and decodes the resulting array response. Use CreateSandbox instead for the common req.Count == 1 (or unset) case, which returns a single object rather than an array.
func (*Client) CreateSecret ¶
CreateSecret registers a new org-scoped secret for the proxy-substitution secrets broker (POST /v1/secrets, docs/SECRETS-DESIGN.md). Returns the created secret's metadata -- never the raw value.
func (*Client) CreateVolume ¶
CreateVolume creates an independent, PVC-backed storage volume (POST /v1/volumes) that can later be mounted into one or more sandboxes via CreateSandboxRequest.VolumeMounts. Always asynchronous -- returns immediately with Status "queued"; poll GetVolume for progress. 404s ("feature_disabled") if the deployment hasn't enabled volumes (BOXXKITE_VOLUMES_ENABLED).
func (*Client) CreateWebhook ¶
CreateWebhook registers a webhook subscription (POST /v1/webhooks). Returns the subscription plus a Secret field -- the raw signing secret, shown exactly once.
func (*Client) DeleteImage ¶
DeleteImage deletes a custom sandbox image (DELETE /v1/images/{id}).
func (*Client) DeleteMCPConnection ¶
DeleteMCPConnection deletes an outbound-MCP connection grant owned by this account (DELETE /v1/mcp-connections/{id}). 404s if already gone or never owned by this account.
func (*Client) DeleteSecret ¶
DeleteSecret deletes a secret owned by this account (DELETE /v1/secrets/{id}). 404s if already gone or never owned by this account.
func (*Client) DeleteVolume ¶
DeleteVolume deletes a storage volume (DELETE /v1/volumes/{id}).
func (*Client) DeleteWebhook ¶
DeleteWebhook deletes a webhook subscription owned by this account (DELETE /v1/webhooks/{id}). 404s if already gone or never owned by this account.
func (*Client) DesktopTakeover ¶
DesktopTakeover opens WS /v1/sandboxes/{id}/desktop -- interactive GUI/remote-desktop human takeover of a sandbox session (VNC over a raw duplex byte stream, proxied straight through to the sidecar's own WS /desktop), structurally identical to Takeover but bridging a full desktop instead of a shell (see docs/API.md and SECURITY.md's "New trust boundary: remote desktop takeover" section).
Like Takeover, this authenticates with a normal `Authorization: Bearer <apiKey>` header on the upgrade request. It reuses Takeover's can_initiate_takeover RBAC gate as-is -- requires an "admin"-role API key; a "member"-role key closes the connection with WS close code 4403. There is no dedicated can_initiate_desktop permission yet, and no read-only variant of this connection. A missing/invalid API key closes with 4401; an unowned or already-destroyed sessionID closes with 4404 -- both surface as an error from the first ReadMessage/WriteMessage call, since the close happens after the opening handshake completes. This route also closes with 4404 when the deployment has not set BOXXKITE_DESKTOP_ENABLED.
The caller must call Close on the returned *websocket.Conn once done.
func (*Client) DestroySandbox ¶
DestroySandbox tears down a sandbox session (DELETE /v1/sandboxes/{id}).
func (*Client) Exec ¶
func (c *Client) Exec(ctx context.Context, sessionID, command string, opts *ExecOptions) (*ExecResult, error)
Exec runs a shell command inside the session's sandbox and returns its exit code, stdout, and stderr (POST /v1/sandboxes/{id}/exec). Commands run synchronously; there is no streaming of partial output.
Example ¶
mux := http.NewServeMux()
mux.HandleFunc("/v1/sandboxes/sbx_123/exec", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, `{"exit_code":0,"stdout":"2\n","stderr":""}`)
})
client, server := exampleServer(mux)
defer server.Close()
result, err := client.Exec(context.Background(), "sbx_123", "python3 -c 'print(1 + 1)'", nil)
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println(strings.TrimSpace(result.Stdout))
Output: 2
func (*Client) ExportMemories ¶ added in v0.7.0
ExportMemories exports live memories (and their relations) for this account, for backup or migration (GET /v1/memory/export).
func (*Client) FileCreate ¶
func (c *Client) FileCreate(ctx context.Context, sessionID, path, content string, opts *FileOptions) (*FileCreateResult, error)
FileCreate creates or overwrites a file in the session's sandbox workspace (POST /v1/sandboxes/{id}/files).
func (*Client) ForgetMemory ¶ added in v0.7.0
ForgetMemory permanently deletes one memory (DELETE /v1/memory/{id}). Not a soft-delete -- a forgotten memory cannot be recalled again.
func (*Client) GetAllowedCommands ¶
func (c *Client) GetAllowedCommands(ctx context.Context) (*AllowedCommandsResponse, error)
GetAllowedCommands returns the current per-account command allowlist (GET /v1/account/allowed-commands). An empty Rules means unrestricted -- the default for every account. This allowlist is an opt-in guardrail, not a sandbox-escape boundary.
func (*Client) GetImage ¶
GetImage fetches one custom sandbox image's build status and details (GET /v1/images/{id}).
func (*Client) GetLog ¶
func (c *Client) GetLog(ctx context.Context, sessionID string, opts *GetLogOptions) (*GetLogResult, error)
GetLog returns a page of audit-log entries for this session, oldest first (GET /v1/sandboxes/{id}/log).
func (*Client) GetMemory ¶ added in v0.7.0
GetMemory fetches one live memory owned by this account (GET /v1/memory/{id}).
func (*Client) GetProcessOutput ¶
func (c *Client) GetProcessOutput(ctx context.Context, sessionID, processID string, sinceOffset int64) (*ProcessOutputResult, error)
GetProcessOutput polls a background process's output since a given byte offset (GET /v1/sandboxes/{id}/processes/{processId}/output). Polling-style, not streaming. sinceOffset (from a previous call's NextOffset, or 0 the first time) lets you fetch only the new output since your last check.
func (*Client) GetSandbox ¶
GetSandbox fetches one sandbox session by id (GET /v1/sandboxes/{id}). Unlike the exec/file routes, this resolves destroyed sessions too -- it is a lookup, not an operational route that requires a live pod.
func (*Client) GetVolume ¶
GetVolume fetches one storage volume's status and details (GET /v1/volumes/{id}).
func (*Client) Glob ¶
func (c *Client) Glob(ctx context.Context, sessionID, pattern string, path string) (*GlobResult, error)
Glob finds files matching a glob pattern (e.g. "**/*.py") under a directory in the session's sandbox workspace (POST /v1/sandboxes/{id}/files/glob). path defaults to "/".
func (*Client) Grep ¶
func (c *Client) Grep(ctx context.Context, sessionID, pattern string, opts *GrepOptions) (*GrepResult, error)
Grep searches file contents by regex pattern under a directory in the session's sandbox workspace, optionally restricted to files matching opts.Glob (POST /v1/sandboxes/{id}/files/grep).
func (*Client) HTTPRequest ¶
func (c *Client) HTTPRequest(ctx context.Context, sessionID, method, targetURL string, opts *HTTPRequestOptions) (*HTTPRequestResult, error)
HTTPRequest issues the secrets-broker HTTP request (POST /v1/sandboxes/{id}/http-request, docs/SECRETS-DESIGN.md). opts.Headers/opts.Body may contain a literal `{{secret:name}}` reference for a secret granted to this session via CreateSandboxRequest.SecretNames; the sidecar substitutes the real value in-process -- this SDK never sees it.
func (*Client) ImportMemories ¶ added in v0.7.0
func (c *Client) ImportMemories(ctx context.Context, req ImportMemoriesRequest) (*MemoryIngestResponse, error)
ImportMemories imports memories (and optionally their relations) previously produced by ExportMemories (POST /v1/memory/import).
func (*Client) IngestMemory ¶ added in v0.7.0
func (c *Client) IngestMemory(ctx context.Context, req IngestMemoryRequest) (*MemoryIngestResponse, error)
IngestMemory splits a bounded document or conversation into atomic memories (POST /v1/memory/ingest). Works with no model provider configured -- the default extractor is deterministic.
func (*Client) ListImages ¶
ListImages lists every custom sandbox image built for this account (GET /v1/images).
func (*Client) ListMCPConnections ¶
func (c *Client) ListMCPConnections(ctx context.Context) ([]MCPConnection, error)
ListMCPConnections lists outbound-MCP connection grants for this account (GET /v1/mcp-connections).
func (*Client) ListMemories ¶ added in v0.7.0
ListMemories lists live memories for this account (GET /v1/memory).
func (*Client) ListProcesses ¶
ListProcesses returns every background process currently tracked for this session (GET /v1/sandboxes/{id}/processes).
func (*Client) ListSandboxes ¶
ListSandboxes lists sandbox sessions owned by the authenticated account (GET /v1/sandboxes). Pass activeOnly=true to restrict to currently-active sessions.
func (*Client) ListSecrets ¶
ListSecrets lists secrets registered for this account (GET /v1/secrets). Raw values are never returned here.
func (*Client) ListVolumes ¶
ListVolumes lists every storage volume created for this account (GET /v1/volumes).
func (*Client) ListWebhookDeliveries ¶
func (c *Client) ListWebhookDeliveries(ctx context.Context, subscriptionID string, opts *ListWebhookDeliveriesOptions) ([]WebhookDelivery, error)
ListWebhookDeliveries returns recent delivery attempts (pending/delivered/failed) for this subscription, newest first (GET /v1/webhooks/{id}/deliveries).
func (*Client) ListWebhooks ¶
ListWebhooks lists webhook subscriptions for this account (GET /v1/webhooks). The signing secret is never returned here.
func (*Client) Logout ¶
Logout revokes one refresh token immediately (POST /v1/auth/logout), opt-in (BOXXKITE_REFRESH_TOKENS_ENABLED). Always succeeds (204) whether or not the token was valid -- never leaks which.
func (*Client) Ls ¶
Ls lists the direct children of a directory in the session's sandbox workspace (POST /v1/sandboxes/{id}/files/ls). path defaults to "/".
func (*Client) MemoryProfile ¶ added in v0.7.0
func (c *Client) MemoryProfile(ctx context.Context, scope string, limit int) (*MemoryProfileResponse, error)
MemoryProfile builds a compact memory profile: stable, long-lived memories separated from recently-touched ones (GET /v1/memory/profile).
func (*Client) MemoryRelations ¶ added in v0.7.0
func (c *Client) MemoryRelations(ctx context.Context, memoryID string, limit int) (*MemoryRelationsResponse, error)
MemoryRelations lists other memories related to this one (GET /v1/memory/{id}/relations -- updates/extends/related/derives edges).
func (*Client) Recall ¶ added in v0.7.0
func (c *Client) Recall(ctx context.Context, query string, opts RecallOptions) (*MemorySearchResponse, error)
Recall ranks live account memories against a query using lexical evidence, phrase match, recency, and importance (GET /v1/memory/search).
func (*Client) RefreshToken ¶
RefreshToken exchanges a still-valid refresh token for a brand new access_token + refresh_token pair (POST /v1/auth/refresh), opt-in (BOXXKITE_REFRESH_TOKENS_ENABLED). Revokes the presented token in the same request (rotation, not reuse) -- store the new RefreshToken from the response and discard the one presented here.
func (*Client) Remember ¶ added in v0.7.0
Remember stores one durable, account-scoped memory directly (POST /v1/memory). See the MemoryBase developer guide for the full model (opt-in, self-hosted retrieval by default, no third-party memory API).
func (*Client) RequestPasswordReset ¶
RequestPasswordReset requests a password-reset email (POST /v1/auth/password-reset/request). Opt-in on the control-plane (BOXXKITE_PASSWORD_RESET_ENABLED); returns an *APIError with StatusCode 404 and Code "feature_disabled" if the deployment hasn't enabled it. Always returns the same message whether or not the email is registered, so this call can never be used to enumerate accounts.
func (*Client) ResendVerification ¶
func (c *Client) ResendVerification(ctx context.Context, accessToken string) (*MessageResponse, error)
ResendVerification re-sends the verification email for the dashboard-JWT-authenticated account (POST /v1/auth/resend-verification). accessToken is a dashboard session token (the JWT returned by /v1/auth/login or /v1/auth/signup) -- a different, non-interchangeable credential type from this Client's own apiKey, so it overrides this call's Authorization header rather than using the Client's apiKey.
func (*Client) RevokePreviewURL ¶
func (c *Client) RevokePreviewURL(ctx context.Context, sessionID string, port int, tokenID string) (*PreviewRevokeResult, error)
RevokePreviewURL invalidates one specific preview-URL token (its TokenID from CreatePreviewURL) before its TTL expires, without tearing down the sandbox session and without affecting any other preview token minted for the same session/port (POST /v1/sandboxes/{id}/preview/{port}/revoke). Idempotent: revoking an already-revoked, already-expired, or unrecognized tokenID still returns Revoked=true rather than erroring.
func (*Client) SendProcessInput ¶
func (c *Client) SendProcessInput(ctx context.Context, sessionID, processID, data string) (*ProcessInputResult, error)
SendProcessInput writes to a tracked background process's stdin pipe (POST /v1/sandboxes/{id}/processes/{processId}/input).
func (*Client) SetAllowedCommands ¶
func (c *Client) SetAllowedCommands(ctx context.Context, rules []AllowedCommandRule) (*AllowedCommandsResponse, error)
SetAllowedCommands replaces the per-account command allowlist wholesale (PUT /v1/account/allowed-commands). rules must be non-empty -- use ClearAllowedCommands to reset to unrestricted.
func (*Client) StartProcess ¶
func (c *Client) StartProcess(ctx context.Context, sessionID, command string, opts *StartProcessOptions) (*ProcessStartResult, error)
StartProcess starts a background process that keeps running after this call returns (POST /v1/sandboxes/{id}/processes). Distinct from Exec, which is one-shot request/response bounded by its own timeout: poll the returned ProcessID's output with GetProcessOutput, feed it input with SendProcessInput, and stop it with StopProcess.
func (*Client) StopProcess ¶
func (c *Client) StopProcess(ctx context.Context, sessionID, processID string) (*ProcessStopResult, error)
StopProcess stops a tracked background process (SIGTERM, then SIGKILL if it doesn't exit within a short grace period) (POST /v1/sandboxes/{id}/processes/{processId}/stop).
func (*Client) StrReplace ¶
func (c *Client) StrReplace(ctx context.Context, sessionID, path, oldStr, newStr string, opts *StrReplaceOptions) (*StrReplaceResult, error)
StrReplace replaces oldStr with newStr in a file; oldStr must appear exactly once unless opts.ReplaceAll is set (POST /v1/sandboxes/{id}/files/str-replace).
func (*Client) StreamProcessOutput ¶
func (c *Client) StreamProcessOutput(ctx context.Context, sessionID, processID string, sinceOffset int64) (*ProcessStream, error)
StreamProcessOutput opens the SSE output stream for a background process. The caller must call Close on the returned *ProcessStream once done.
func (*Client) Takeover ¶
Takeover opens WS /v1/sandboxes/{id}/takeover -- interactive human takeover of a sandbox session's shell: a raw duplex byte stream proxied straight through to the sandbox's PTY (see docs/API.md). There is no message envelope -- send and receive raw bytes on the returned connection exactly as you would over a local terminal (conn.WriteMessage(websocket.BinaryMessage, data) / conn.ReadMessage()).
Like sdk-python's takeover() (and unlike sdk-js's, which is constrained by the browser WebSocket API's inability to set a custom header), this authenticates with a normal `Authorization: Bearer <apiKey>` header on the upgrade request -- Go's websocket.Dialer, like Python's `websockets` library, can set arbitrary headers on the handshake. Requires an "admin"-role API key; a "member"-role key closes the connection with WS close code 4403 (see SECURITY.md's "Human takeover" section). A missing/invalid API key closes with 4401; an unowned or already-destroyed sessionID closes with 4404 -- both surface as an error from the first ReadMessage/WriteMessage call, since the close happens after the opening handshake completes.
The caller must call Close on the returned *websocket.Conn once done.
func (*Client) VerifyEmail ¶
VerifyEmail consumes a single-use email-verification token (POST /v1/auth/verify-email), opt-in (BOXXKITE_EMAIL_VERIFICATION_ENABLED).
func (*Client) View ¶
func (c *Client) View(ctx context.Context, sessionID, path string, opts *ViewOptions) (*FileViewResult, error)
View reads a text file's contents (optionally a line range), or lists a directory's entries (POST /v1/sandboxes/{id}/files/view). Binary/image files are not supported.
func (*Client) Watch ¶
Watch opens the audit-log SSE stream for a session (GET /v1/sandboxes/{id}/watch). The caller must call Close on the returned *LogWatcher once done.
func (*Client) WithSandbox ¶
func (c *Client) WithSandbox(ctx context.Context, req CreateSandboxRequest, fn func(*Session) error) error
WithSandbox is the create-on-enter, destroy-on-exit convenience -- mirroring sdk-python's `with client.sandbox() as sb:` context manager / sdk-js's withSandbox. It creates a sandbox from req, invokes fn with a *Session bound to it, and destroys the sandbox when fn returns (even if fn returns an error) -- teardown itself is best-effort, mirroring both sibling SDKs' "an already-gone session shouldn't raise on cleanup" behavior.
Example ¶
mux := http.NewServeMux()
mux.HandleFunc("POST /v1/sandboxes", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, `{"id":"sbx_123","status":"running","created_at":"2026-01-01T00:00:00Z"}`)
})
mux.HandleFunc("POST /v1/sandboxes/{id}/exec", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, `{"exit_code":0,"stdout":"2\n","stderr":""}`)
})
mux.HandleFunc("POST /v1/sandboxes/{id}/files", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, `{"path":"hello.txt","size":32,"created":true}`)
})
mux.HandleFunc("POST /v1/sandboxes/{id}/files/view", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, `{"content":"hello from boxxkite-client (go)\n","lines":1,"is_directory":false}`)
})
mux.HandleFunc("DELETE /v1/sandboxes/{id}", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNoContent)
})
client, server := exampleServer(mux)
defer server.Close()
ctx := context.Background()
err := client.WithSandbox(ctx, CreateSandboxRequest{Label: Ptr("sdk-go-example")}, func(sb *Session) error {
result, err := sb.Exec(ctx, "python3 -c 'print(1 + 1)'", nil)
if err != nil {
return err
}
fmt.Println(strings.TrimSpace(result.Stdout))
if _, err := sb.FileCreate(ctx, "hello.txt", "hello from boxxkite-client (go)\n", nil); err != nil {
return err
}
viewed, err := sb.View(ctx, "hello.txt", nil)
if err != nil {
return err
}
fmt.Println(strings.TrimSpace(viewed.Content))
return nil
})
if err != nil {
fmt.Println("error:", err)
return
}
Output: 2 hello from boxxkite-client (go)
type ConnectionError ¶
ConnectionError wraps a failure to reach the control-plane at all (DNS, TLS, timeout, connection refused) -- as opposed to a reachable server returning an error response (see APIError). Mirrors sdk-python's BoxxkiteConnectionError / sdk-js's BoxxkiteConnectionError.
func (*ConnectionError) Error ¶
func (e *ConnectionError) Error() string
func (*ConnectionError) Unwrap ¶
func (e *ConnectionError) Unwrap() error
type CreateImageRequest ¶
type CreateImageRequest struct {
// Label is an optional human-readable label for the image.
Label *string `json:"label,omitempty"`
// Base is one of "boxxkite-default", "boxxkite-minimal", "boxxkite-node",
// "boxxkite-go". Defaults to "boxxkite-default" server-side when empty.
// "boxxkite-node" drops Python entirely (no PythonPackages installable,
// only AptPackages/NpmPackages); "boxxkite-go" drops both Python and
// Node entirely (no PythonPackages or NpmPackages installable, only
// AptPackages).
Base string `json:"base,omitempty"`
// PythonPackages are exact-version-pinned packages ("name==version",
// no ranges) to install into the image.
PythonPackages []string `json:"python_packages,omitempty"`
// AptPackages are exact-version-pinned apt packages ("name==version",
// no ranges) to install into the image.
AptPackages []string `json:"apt_packages,omitempty"`
// NpmPackages are exact-version-pinned npm packages ("name==version"
// or "@scope/name==version", no ranges) to install into the image. Not
// supported on Base="boxxkite-go".
NpmPackages []string `json:"npm_packages,omitempty"`
}
CreateImageRequest is the request body for CreateImage (POST /v1/images). All fields are optional -- a zero-value CreateImageRequest{} builds an unmodified "boxxkite-default" image.
type CreateSandboxRequest ¶
type CreateSandboxRequest struct {
// Label is an optional human-readable label for the sandbox.
Label *string `json:"label,omitempty"`
// Size is one of "small", "medium", "large". Defaults to "small"
// server-side when omitted.
Size *string `json:"size,omitempty"`
// StorageGB is the requested persistent storage in GB.
StorageGB *float64 `json:"storage_gb,omitempty"`
// LifetimeMinutes is the maximum lifetime of the sandbox in minutes
// before automatic teardown.
LifetimeMinutes *int `json:"lifetime_minutes,omitempty"`
// Count is the number of sandboxes to create in this request.
Count *int `json:"count,omitempty"`
// SecretNames names this account's secrets (see docs/SECRETS-DESIGN.md)
// this session should be granted access to via the sidecar's
// secrets-broker HTTPRequest tool. A name that doesn't exist for this
// account 404s before any sandbox is created.
SecretNames []string `json:"secret_names,omitempty"`
// ImageID is the id of a completed custom image built via CreateImage.
// If set, the sandbox uses that digest-pinned image instead of the
// operator's default. 404s if not owned by this account or not yet
// status "completed".
ImageID *string `json:"image_id,omitempty"`
// MCPConnectionNames names this account's outbound-MCP connections
// (see CreateMCPConnection) this session should be granted network
// egress to. A name that doesn't exist for this account 404s before
// any sandbox is created, same precedent as SecretNames.
MCPConnectionNames []string `json:"mcp_connection_names,omitempty"`
// VolumeMounts is an optional {volume_id: mount_path} mapping of
// independent PVC-backed volumes (see CreateVolume) to mount into
// this sandbox.
VolumeMounts map[string]string `json:"volume_mounts,omitempty"`
// GPUCount is opt-in and experimental (docs/GPU-SUPPORT-SCOPING.md) --
// it requests this many GPUs as a Kubernetes extended-resource limit.
// 422s (gpu_support_disabled) unless the deployment has
// BOXXKITE_GPU_ENABLED set and a GPU-equipped node pool with a device
// plugin provisioned; not verified against real GPU hardware in this
// codebase.
GPUCount *int `json:"gpu_count,omitempty"`
}
CreateSandboxRequest is the request body for CreateSandbox (POST /v1/sandboxes). All fields are optional -- a zero-value CreateSandboxRequest{} creates one default "small" sandbox. Use Ptr(...) to populate the pointer-typed fields, e.g. boxxkite.CreateSandboxRequest{Size: boxxkite.Ptr("medium")}.
type CreateSecretRequest ¶
type CreateSecretRequest struct {
// Name is the unique (per-account) name used to reference this secret
// from CreateSandboxRequest.SecretNames and from an agent tool call as
// {{secret:name}} in a POST /http-request body/header.
Name string `json:"name"`
// Value is the real credential value. Write-only -- accepted here and
// never returned by this or any other route, including this response.
Value string `json:"value"`
// AllowedHosts are the destination hostnames this secret may be used
// against via POST /http-request. Required, not optional -- an
// unscoped secret usable against any destination defeats the point of
// this feature. A host that resolves to a private/link-local/loopback/
// metadata address is rejected at creation time (a best-effort
// backstop; see docs/SECRETS-DESIGN.md §5 for why the real control is
// the sidecar's request-time check).
AllowedHosts []string `json:"allowed_hosts"`
// TrustTier is only meaningful for wallet/private-key-style secrets
// (docs/WALLET-SECRETS-DESIGN.md) -- omit for an ordinary API-key-style
// secret. The only accepted value today is "testnet"; "mainnet" is
// refused (422).
TrustTier *string `json:"trust_tier,omitempty"`
}
CreateSecretRequest is the request body for CreateSecret (POST /v1/secrets).
type CreateVolumeRequest ¶
type CreateVolumeRequest struct {
// Label is an optional human-readable label for the volume.
Label *string `json:"label,omitempty"`
// SizeGB is the requested volume size in GB (max 1024).
SizeGB float64 `json:"size_gb"`
}
CreateVolumeRequest is the request body for CreateVolume (POST /v1/volumes).
type CreateWebhookRequest ¶
type CreateWebhookRequest struct {
// URL is the HTTPS (or HTTP, for local testing) URL the control plane
// will POST events to. Checked at registration time against the same
// private/link-local/loopback/metadata-address denylist
// CreateSandboxRequest's secrets use for allowed_hosts.
URL string `json:"url"`
// EventTypes are the event types this subscription should receive (at
// least one required) -- "sandbox.created", "sandbox.destroyed", or
// "audit_log.entry" (added per GitHub issue #125 for SIEM/audit-log
// export). See docs/WEBHOOKS-DESIGN.md for the full event catalog.
EventTypes []string `json:"event_types"`
// Description is an optional caller-supplied label for this
// subscription (e.g. "Slack notifier").
Description *string `json:"description,omitempty"`
}
CreateWebhookRequest is the request body for CreateWebhook (POST /v1/webhooks).
type DirEntry ¶
type DirEntry struct {
Path string `json:"path"`
IsDir bool `json:"is_dir"`
Size int64 `json:"size"`
}
DirEntry is one entry returned by View (for a directory path), Ls, or Glob.
type EgressDeniedError ¶ added in v0.6.0
type EgressDeniedError struct{ APIError }
func (*EgressDeniedError) Error ¶ added in v0.6.0
func (e *EgressDeniedError) Error() string
func (*EgressDeniedError) Unwrap ¶ added in v0.6.0
func (e *EgressDeniedError) Unwrap() error
type ExecOptions ¶
type ExecOptions struct {
// Timeout bounds the command's runtime in seconds (1-100, server
// default 30). A command that outlives it is killed and reported as
// failed.
Timeout *int
// Description is an optional caller-supplied label for this exec call,
// surfaced in the audit log (GetLog/Watch).
Description *string
}
ExecOptions carries the optional parameters for Exec.
type ExecResult ¶
type ExecResult struct {
ExitCode int `json:"exit_code"`
Stdout string `json:"stdout"`
Stderr string `json:"stderr"`
}
ExecResult is the response shape from Exec (POST /v1/sandboxes/{id}/exec).
type FileCreateResult ¶
type FileCreateResult struct {
Path string `json:"path"`
Size int `json:"size"`
Created bool `json:"created"`
}
FileCreateResult is the response shape from FileCreate.
type FileOptions ¶
type FileOptions struct {
Description *string
}
FileOptions carries the optional description field shared by every file operation below.
type FileViewResult ¶
type FileViewResult struct {
Content string `json:"content"`
Lines int `json:"lines"`
IsDirectory bool `json:"is_directory"`
Entries []DirEntry `json:"entries"`
}
FileViewResult is the response shape from View. Entries is populated (Content/Lines left zero) when the target path is a directory.
type GetLogOptions ¶
GetLogOptions carries the optional pagination parameters for GetLog.
type GetLogResult ¶
type GetLogResult struct {
Entries []LogEntry `json:"entries"`
Limit int `json:"limit"`
Offset int `json:"offset"`
Total int `json:"total"`
}
GetLogResult is the response shape from GetLog.
type GlobResult ¶
type GlobResult struct {
Matches []DirEntry `json:"matches"`
}
GlobResult is the response shape from Glob.
type GrepMatch ¶
type GrepMatch struct {
Path string `json:"path"`
Line int `json:"line"`
Text string `json:"text"`
}
GrepMatch is one match returned by Grep.
type GrepOptions ¶
type GrepOptions struct {
// Path defaults to "/".
Path string
// Glob optionally restricts matches to files whose name matches this
// glob pattern.
Glob string
// MaxMatches defaults to 500 and is capped at 5000 server-side.
MaxMatches int
}
GrepOptions carries the optional parameters for Grep.
type GrepResult ¶
type GrepResult struct {
Matches []GrepMatch `json:"matches"`
Error *string `json:"error"`
Truncated bool `json:"truncated"`
}
GrepResult is the response shape from Grep.
type HTTPRequestOptions ¶
HTTPRequestOptions carries the optional parameters for HTTPRequest.
type HTTPRequestResult ¶
type HTTPRequestResult struct {
StatusCode int `json:"status_code"`
Headers map[string]string `json:"headers"`
Body string `json:"body"`
Truncated bool `json:"truncated"`
}
HTTPRequestResult is the response shape from HTTPRequest (POST /v1/sandboxes/{id}/http-request).
type Image ¶
type Image struct {
ID string `json:"id"`
Label *string `json:"label"`
Base string `json:"base"`
PythonPackages []string `json:"python_packages"`
AptPackages []string `json:"apt_packages"`
NpmPackages []string `json:"npm_packages"`
Status string `json:"status"`
Digest *string `json:"digest"`
RegistryRef *string `json:"registry_ref"`
ScanResult map[string]any `json:"scan_result"`
FailureReason *string `json:"failure_reason"`
CreatedAt string `json:"created_at"`
CompletedAt *string `json:"completed_at"`
}
Image is a custom sandbox image, as returned by CreateImage/GetImage/ ListImages.
type ImportMemoriesRequest ¶ added in v0.7.0
type ImportMemoriesRequest struct {
Memories []map[string]any `json:"memories"`
Relations []map[string]any `json:"relations,omitempty"`
}
ImportMemoriesRequest is the request body for ImportMemories (POST /v1/memory/import).
type IngestMemoryRequest ¶ added in v0.7.0
type IngestMemoryRequest struct {
Content string `json:"content"`
Scope string `json:"scope,omitempty"`
SourceSessionID *string `json:"source_session_id,omitempty"`
Metadata map[string]any `json:"metadata,omitempty"`
}
IngestMemoryRequest is the request body for IngestMemory (POST /v1/memory/ingest).
type ListMemoriesOptions ¶ added in v0.7.0
ListMemoriesOptions configures ListMemories.
type ListWebhookDeliveriesOptions ¶
type ListWebhookDeliveriesOptions struct {
// Limit is the maximum number of entries to return (server default
// 20, max 100).
Limit *int
// Offset is the number of entries to skip, newest-first.
Offset *int
}
ListWebhookDeliveriesOptions carries the optional pagination parameters for ListWebhookDeliveries.
type LogEntry ¶
type LogEntry struct {
ID string `json:"id"`
SessionID string `json:"session_id"`
Source string `json:"source"`
Operation string `json:"operation"`
Detail json.RawMessage `json:"detail"`
ExitCode *int `json:"exit_code"`
OutputTruncated string `json:"output_truncated"`
StartedAt string `json:"started_at"`
DurationMs *int64 `json:"duration_ms"`
RowHash *string `json:"row_hash"`
PrevHash *string `json:"prev_hash"`
}
LogEntry is one row of a session's exec/file-operation audit trail, as returned by GetLog and streamed by Watch (docs/SANDBOX-OBSERVABILITY-DESIGN.md).
type LogWatcher ¶
type LogWatcher struct {
// contains filtered or unexported fields
}
LogWatcher streams new audit-log entries for a session as they're written (GET /v1/sandboxes/{id}/watch), one LogEntry per Server-Sent Event `data:` line. Use it like bufio.Scanner:
watcher, err := client.Watch(ctx, sessionID)
if err != nil { ... }
defer watcher.Close()
for watcher.Next() {
entry := watcher.Entry()
// ...
}
if err := watcher.Err(); err != nil { ... }
Next blocks until either a new entry arrives, the stream ends, or ctx is canceled. This is a live feed of exec/file operations as the control-plane logs them, not a live terminal -- see Takeover for that.
func (*LogWatcher) Close ¶
func (w *LogWatcher) Close() error
Close closes the underlying HTTP response body, ending the stream.
func (*LogWatcher) Entry ¶
func (w *LogWatcher) Entry() LogEntry
Entry returns the most recent entry produced by Next.
func (*LogWatcher) Err ¶
func (w *LogWatcher) Err() error
Err returns the first error encountered while streaming, if any (nil if the stream simply ended).
func (*LogWatcher) Next ¶
func (w *LogWatcher) Next() bool
Next advances to the next streamed LogEntry, blocking until one arrives. It returns false when the stream ends (server closed it, context canceled, or a decode error) -- check Err to distinguish a clean end from an error.
type LsResult ¶
type LsResult struct {
Entries []DirEntry `json:"entries"`
}
LsResult is the response shape from Ls.
type MCPConnection ¶
type MCPConnection struct {
ID string `json:"id"`
Label string `json:"label"`
CatalogID string `json:"catalog_id"`
Host string `json:"host"`
CreatedAt string `json:"created_at"`
LastUsedAt *string `json:"last_used_at"`
}
MCPConnection is an outbound-MCP connection grant, as returned by CreateMCPConnection/ListMCPConnections (GitHub issues #116/#117, docs/OUTBOUND-MCP-DESIGN.md).
type Memory ¶ added in v0.7.0
type Memory struct {
ID string `json:"id"`
Scope string `json:"scope"`
Kind string `json:"kind"`
Content string `json:"content"`
Metadata map[string]any `json:"metadata"`
SourceSessionID *string `json:"source_session_id"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
ExpiresAt *string `json:"expires_at"`
SourceContent *string `json:"source_content"`
DocumentDate *string `json:"document_date"`
EventDates []string `json:"event_dates"`
Importance float64 `json:"importance"`
AccessCount int `json:"access_count"`
LastAccessedAt *string `json:"last_accessed_at"`
SupersededAt *string `json:"superseded_at"`
SupersededByID *string `json:"superseded_by_id"`
}
Memory is one durable, account-scoped memory (MemoryBase -- POST/GET /v1/memory).
type MemoryIngestResponse ¶ added in v0.7.0
type MemoryIngestResponse struct {
SourceSessionID *string `json:"source_session_id"`
Memories []Memory `json:"memories"`
}
MemoryIngestResponse is the response from IngestMemory and ImportMemories.
type MemoryProfileResponse ¶ added in v0.7.0
type MemoryProfileResponse struct {
Static []Memory `json:"static"`
Dynamic []Memory `json:"dynamic"`
}
MemoryProfileResponse is the response from MemoryProfile (GET /v1/memory/profile) -- stable, long-lived memories separated from recently-touched ones.
type MemoryRelation ¶ added in v0.7.0
type MemoryRelation struct {
SourceMemoryID string `json:"source_memory_id"`
TargetMemoryID string `json:"target_memory_id"`
RelationType string `json:"relation_type"`
Confidence float64 `json:"confidence"`
CreatedAt string `json:"created_at"`
}
MemoryRelation is one edge from MemoryRelations.
type MemoryRelationsResponse ¶ added in v0.7.0
type MemoryRelationsResponse struct {
MemoryID string `json:"memory_id"`
Relations []MemoryRelation `json:"relations"`
}
MemoryRelationsResponse is the response from MemoryRelations (GET /v1/memory/{id}/relations).
type MemorySearchHit ¶ added in v0.7.0
MemorySearchHit is a memory returned from Recall, with its retrieval score.
type MemorySearchResponse ¶ added in v0.7.0
type MemorySearchResponse struct {
Query string `json:"query"`
Memories []MemorySearchHit `json:"memories"`
}
MemorySearchResponse is the response from Recall (GET /v1/memory/search).
type MessageResponse ¶
type MessageResponse struct {
Message string `json:"message"`
}
MessageResponse is a generic ack body (e.g. password-reset request, which always returns the same message regardless of whether the email is registered).
type Option ¶
type Option func(*Client)
Option configures a Client constructed via NewClient.
func WithHTTPClient ¶
WithHTTPClient overrides the *http.Client used for requests. Primarily useful for tests (point it at an httptest.Server) or for customizing transport-level behavior (proxies, custom TLS config).
func WithRetry ¶
func WithRetry(cfg RetryConfig) Option
WithRetry enables automatic retry of transient failures. Retry is off by default -- pass this option (ideally starting from DefaultRetryConfig()) to turn it on. Only idempotent verbs are retried, and only on a connection failure or a retriable status (429 + transient 5xx); a non-idempotent POST is never retried, so this cannot double-create a resource. Zero-valued BackoffBase/BackoffMax/Statuses/ Methods fields are filled in from the defaults, so WithRetry(RetryConfig{MaxRetries: 3}) is valid -- but RespectRetryAfter stays false unless set, so prefer DefaultRetryConfig() as a base.
func WithTimeout ¶
WithTimeout overrides the default per-request timeout (DefaultTimeout).
func WithWebSocketDialer ¶
WithWebSocketDialer overrides the *websocket.Dialer used by Takeover. Primarily useful for tests.
type PreviewRevokeResult ¶
PreviewRevokeResult is the response shape from RevokePreviewURL.
type PreviewURL ¶
type PreviewURL struct {
URL string `json:"url"`
ExpiresAt string `json:"expires_at"`
TokenID string `json:"token_id"`
}
PreviewURL is the response shape from CreatePreviewURL.
type ProcessInfo ¶
type ProcessInfo struct {
ProcessID string `json:"process_id"`
Command string `json:"command"`
Description *string `json:"description"`
Status string `json:"status"`
StartedAt string `json:"started_at"`
ExitCode *int `json:"exit_code"`
}
ProcessInfo is one tracked background process, as returned by ListProcesses.
type ProcessInputResult ¶
type ProcessInputResult struct {
BytesWritten int `json:"bytes_written"`
}
ProcessInputResult is the response shape from SendProcessInput.
type ProcessListResult ¶
type ProcessListResult struct {
Processes []ProcessInfo `json:"processes"`
}
ProcessListResult is the response shape from ListProcesses.
type ProcessOutputResult ¶
type ProcessOutputResult struct {
Status string `json:"status"`
StdoutChunk string `json:"stdout_chunk"`
NextOffset int64 `json:"next_offset"`
Truncated bool `json:"truncated"`
ExitCode *int `json:"exit_code"`
}
ProcessOutputResult is the response shape from GetProcessOutput.
type ProcessStartResult ¶
type ProcessStartResult struct {
ProcessID string `json:"process_id"`
Status string `json:"status"`
StartedAt string `json:"started_at"`
}
ProcessStartResult is the response shape from StartProcess.
type ProcessStopResult ¶
ProcessStopResult is the response shape from StopProcess.
type ProcessStream ¶
type ProcessStream struct {
// contains filtered or unexported fields
}
ProcessStream streams a background process's stdout as Server-Sent Events (GET /v1/sandboxes/{id}/processes/{processId}/stream), the streaming counterpart to GetProcessOutput. Use it like bufio.Scanner:
stream, err := client.StreamProcessOutput(ctx, sessionID, processID, 0)
if err != nil { ... }
defer stream.Close()
for stream.Next() {
ev := stream.Event()
// ev.Type == "output" | "exit"
}
if err := stream.Err(); err != nil { ... }
func (*ProcessStream) Close ¶
func (s *ProcessStream) Close() error
Close closes the underlying HTTP response body, ending the stream.
func (*ProcessStream) Err ¶
func (s *ProcessStream) Err() error
Err returns the first error encountered while streaming, if any.
func (*ProcessStream) Event ¶
func (s *ProcessStream) Event() ProcessStreamEvent
Event returns the most recent event produced by Next.
func (*ProcessStream) Next ¶
func (s *ProcessStream) Next() bool
Next advances to the next streamed event, blocking until one arrives. It returns false when the stream ends -- check Err to distinguish a clean end from an error.
type ProcessStreamEvent ¶
type ProcessStreamEvent struct {
Type string `json:"type"`
StdoutChunk string `json:"stdout_chunk"`
NextOffset int64 `json:"next_offset"`
Truncated bool `json:"truncated"`
Status string `json:"status"`
ExitCode *int `json:"exit_code"`
}
ProcessStreamEvent is one event from StreamProcessOutput. Type is "output" (StdoutChunk/NextOffset/Truncated populated) for each new chunk, then "exit" (Status/ExitCode populated) once the process finishes.
type QuotaExceededError ¶ added in v0.6.0
type QuotaExceededError struct{ APIError }
Named errors allow callers to use errors.As for the most actionable sandbox failures while APIError remains the common compatibility shape.
func (*QuotaExceededError) Error ¶ added in v0.6.0
func (e *QuotaExceededError) Error() string
func (*QuotaExceededError) Unwrap ¶ added in v0.6.0
func (e *QuotaExceededError) Unwrap() error
Unwrap lets errors.As(err, &apiErr) reach the embedded APIError, which is what sdk-go's README promises ("Every non-2xx response returns a *boxxkite.APIError"). Without it the typed errors embed APIError by value with no link in the chain, so errors.As failed for exactly the codes callers branch on -- quota, egress, not-ready -- and they lost access to StatusCode and Code.
type ReadonlyFilesystemError ¶ added in v0.6.0
type ReadonlyFilesystemError struct{ APIError }
func (*ReadonlyFilesystemError) Error ¶ added in v0.6.0
func (e *ReadonlyFilesystemError) Error() string
func (*ReadonlyFilesystemError) Unwrap ¶ added in v0.6.0
func (e *ReadonlyFilesystemError) Unwrap() error
type RecallOptions ¶ added in v0.7.0
RecallOptions configures Recall.
type RememberRequest ¶ added in v0.7.0
type RememberRequest struct {
Content string `json:"content"`
Scope string `json:"scope,omitempty"`
Kind string `json:"kind,omitempty"`
Metadata map[string]any `json:"metadata,omitempty"`
SourceSessionID *string `json:"source_session_id,omitempty"`
Importance *float64 `json:"importance,omitempty"`
}
RememberRequest is the request body for Remember (POST /v1/memory).
type RetryConfig ¶
type RetryConfig struct {
// MaxRetries is the number of retries after the initial attempt (so a
// total of MaxRetries+1 attempts). 0 disables retry.
MaxRetries int
// BackoffBase is the base of the exponential backoff (delay for the
// first retry is drawn from [0, BackoffBase)).
BackoffBase time.Duration
// BackoffMax caps any single backoff (and any honored Retry-After).
BackoffMax time.Duration
// Statuses is the set of response status codes that trigger a retry.
Statuses map[int]bool
// Methods is the set of (idempotent) HTTP verbs eligible for retry.
Methods map[string]bool
// RespectRetryAfter honors a server-supplied Retry-After header (delta
// seconds or HTTP-date) in preference to computed backoff.
RespectRetryAfter bool
}
RetryConfig configures automatic retry of transient failures. Enable it via WithRetry; retry is off entirely when no RetryConfig is set.
func DefaultRetryConfig ¶
func DefaultRetryConfig() RetryConfig
DefaultRetryConfig is the recommended starting point for WithRetry: 2 retries, exponential backoff with full jitter (500ms base, 30s cap), retry on 429/500/502/503/504 for idempotent verbs, Retry-After honored.
type Sandbox ¶
type Sandbox struct {
ID string `json:"id"`
Status string `json:"status"`
Label *string `json:"label"`
CreatedAt string `json:"created_at"`
DestroyedAt *string `json:"destroyed_at"`
ExpiresAt *string `json:"expires_at"`
Connect *SandboxConnectInfo `json:"connect,omitempty"`
Usage *Usage `json:"usage,omitempty"`
}
Sandbox is one sandbox session (GET/POST /v1/sandboxes response shape).
type SandboxConnectInfo ¶
SandboxConnectInfo is opaque connection metadata for operators with cluster access -- external callers operate on a session exclusively through the exec/files/* routes, never this directly.
type SandboxCrashedError ¶ added in v0.6.0
type SandboxCrashedError struct{ APIError }
func (*SandboxCrashedError) Error ¶ added in v0.6.0
func (e *SandboxCrashedError) Error() string
func (*SandboxCrashedError) Unwrap ¶ added in v0.6.0
func (e *SandboxCrashedError) Unwrap() error
type SandboxNotReadyError ¶ added in v0.6.0
type SandboxNotReadyError struct{ APIError }
func (*SandboxNotReadyError) Error ¶ added in v0.6.0
func (e *SandboxNotReadyError) Error() string
func (*SandboxNotReadyError) Unwrap ¶ added in v0.6.0
func (e *SandboxNotReadyError) Unwrap() error
type Secret ¶
type Secret struct {
ID string `json:"id"`
Name string `json:"name"`
AllowedHosts []string `json:"allowed_hosts"`
TrustTier *string `json:"trust_tier"`
CreatedAt string `json:"created_at"`
LastUsedAt *string `json:"last_used_at"`
}
Secret is a secret's metadata, as returned by CreateSecret/ListSecrets. The raw value is never included here or anywhere else after creation.
type ServiceUnavailableError ¶ added in v0.6.0
func (*ServiceUnavailableError) Error ¶ added in v0.6.0
func (e *ServiceUnavailableError) Error() string
func (*ServiceUnavailableError) Unwrap ¶ added in v0.6.0
func (e *ServiceUnavailableError) Unwrap() error
type Session ¶
type Session struct {
ID string
// contains filtered or unexported fields
}
Session is a thin, session-scoped view over Client -- every method forwards to the identically-named Client method with this Session's ID as the sessionID argument. Obtained via WithSandbox; mirrors sdk-python's SandboxSession / sdk-js's SandboxSession.
func (*Session) CreatePreviewURL ¶
func (*Session) DesktopTakeover ¶
func (*Session) Exec ¶
func (s *Session) Exec(ctx context.Context, command string, opts *ExecOptions) (*ExecResult, error)
func (*Session) FileCreate ¶
func (s *Session) FileCreate(ctx context.Context, path, content string, opts *FileOptions) (*FileCreateResult, error)
func (*Session) GetLog ¶
func (s *Session) GetLog(ctx context.Context, opts *GetLogOptions) (*GetLogResult, error)
func (*Session) GetProcessOutput ¶
func (*Session) Grep ¶
func (s *Session) Grep(ctx context.Context, pattern string, opts *GrepOptions) (*GrepResult, error)
func (*Session) HTTPRequest ¶
func (s *Session) HTTPRequest(ctx context.Context, method, targetURL string, opts *HTTPRequestOptions) (*HTTPRequestResult, error)
func (*Session) ListProcesses ¶
func (s *Session) ListProcesses(ctx context.Context) (*ProcessListResult, error)
func (*Session) RevokePreviewURL ¶
func (*Session) SendProcessInput ¶
func (*Session) StartProcess ¶
func (s *Session) StartProcess(ctx context.Context, command string, opts *StartProcessOptions) (*ProcessStartResult, error)
func (*Session) StopProcess ¶
func (*Session) StrReplace ¶
func (s *Session) StrReplace(ctx context.Context, path, oldStr, newStr string, opts *StrReplaceOptions) (*StrReplaceResult, error)
func (*Session) View ¶
func (s *Session) View(ctx context.Context, path string, opts *ViewOptions) (*FileViewResult, error)
type StartProcessOptions ¶
type StartProcessOptions struct {
Description *string
// MaxRuntimeSeconds is a hard ceiling on how long the process may run
// before being force-killed. Defaults to 3600.
MaxRuntimeSeconds int
// ExposePort, if set, makes this process's listening port reachable
// via a preview URL (see CreatePreviewURL).
ExposePort *int
}
StartProcessOptions carries the optional parameters for StartProcess.
type StrReplaceOptions ¶
StrReplaceOptions carries the optional parameters for StrReplace.
type StrReplaceResult ¶
type StrReplaceResult struct {
Path string `json:"path"`
Replaced bool `json:"replaced"`
Occurrences int `json:"occurrences"`
}
StrReplaceResult is the response shape from StrReplace.
type TokenPair ¶
type TokenPair struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
RefreshToken *string `json:"refresh_token"`
Account Account `json:"account"`
}
TokenPair is the response shape from RefreshToken -- a brand new access_token + refresh_token pair, plus the account identity.
type Usage ¶
type Usage struct {
MonthlySandboxHoursUsed float64 `json:"monthly_sandbox_hours_used"`
MonthlySandboxHoursLimit float64 `json:"monthly_sandbox_hours_limit"`
ConcurrentSandboxes int `json:"concurrent_sandboxes"`
ConcurrentSandboxesLimit int `json:"concurrent_sandboxes_limit"`
}
Usage is the current usage against fair-use limits (GET /v1/usage), also returned inline on CreateSandbox's response.
type ViewOptions ¶
type ViewOptions struct {
// ViewRange is an optional [start_line, end_line] pair, 1-indexed.
ViewRange []int
Description *string
}
ViewOptions carries the optional parameters for View.
type Volume ¶
type Volume struct {
ID string `json:"id"`
Label *string `json:"label"`
SizeGB float64 `json:"size_gb"`
Status string `json:"status"`
PVCName *string `json:"pvc_name"`
FailureReason *string `json:"failure_reason"`
CreatedAt string `json:"created_at"`
}
Volume is an independent, PVC-backed storage volume, as returned by CreateVolume/GetVolume/ListVolumes.
type Webhook ¶
type Webhook struct {
ID string `json:"id"`
URL string `json:"url"`
EventTypes []string `json:"event_types"`
Description *string `json:"description"`
IsActive bool `json:"is_active"`
CreatedAt string `json:"created_at"`
LastTriggeredAt *string `json:"last_triggered_at"`
// Secret is the raw signing secret, shown exactly once on the
// CreateWebhook response. Use it to verify the
// X-Boxxkite-Webhook-Signature header on every delivery; it cannot be
// retrieved again after this response.
Secret string `json:"secret,omitempty"`
}
Webhook is a webhook subscription, as returned by CreateWebhook/ ListWebhooks. Secret is only ever populated on CreateWebhook's response -- it is never returned by any other route.
type WebhookDelivery ¶
type WebhookDelivery struct {
ID string `json:"id"`
EventType string `json:"event_type"`
Status string `json:"status"`
AttemptCount int `json:"attempt_count"`
NextAttemptAt string `json:"next_attempt_at"`
LastAttemptAt *string `json:"last_attempt_at"`
ResponseStatusCode *int `json:"response_status_code"`
FailureReason *string `json:"failure_reason"`
CreatedAt string `json:"created_at"`
DeliveredAt *string `json:"delivered_at"`
}
WebhookDelivery is one delivery attempt for a webhook subscription, as returned by ListWebhookDeliveries.