System
The daemon itself: its identity, its event stream, its terminals, its browsers, its helpers
On this page(25 sections)
- What this sandbox is
- Stop offering one release
- Decide how updates are taken
- Settings files the sandbox could not read
- Take a stray setting out of a file
- Trade a sign-in for a session
- The live event stream
- Say what you are looking at
- What has been spent
- What the sandbox is using right now
- What is filling the disk
- Measure what is filling the disk
- Stop measuring the disk
- Free the space one category holds
- Open terminals
- Close a terminal
- A terminal's history as plain text
- Browsers the agent has open
- Shut a browser down
- The sandbox's own desktop
- Subagents the agents have started
- The machines you have connected
- Drive a sandbox on one of your own devices
- Run one of your device's own CLI actions
- Update, restart, or clean up the links of the agent on one of your own devices
The group with the widest job. The identity read is what the daemon says it is, including the routes it implements, which is the one call that tells a newer client what this sandbox can do. The event stream is the sandbox-wide live feed. The rest is the machinery an agent leaves running: terminals and their history, browsers, and the records of helpers it delegated to.
25 calls. Pick one to open it, or use the list on the right.
GET/infoWhat this sandbox is
The sandbox's own identity and state: which workspace it holds, which image it runs, what it is called, and the list of calls it actually implements. Start here, because a browser is routinely newer than the sandbox it is talking to and this is how it finds out what is there.
What you send
Nothing. Call it as it is.
What comes back
| Field | Type |
|---|---|
nameWhat this sandbox is called | string |
imageThe image it is running | string |
versionThe version of that image | string |
latestThe newest published version on its… | string |
updateAvailableWhether those two differ | boolean |
runtimesWhich agent runtimes can serve a… | object |
channelWhich release channel this sandbox follows | string |
previousImageThe image the last update replaced,… | string |
updateNotesWhat is in the update, in… | string[] |
moreUpdateNotesHow many further notes there are… | number |
breakingNotesWhat the update takes away, uncapped,… | string[] |
stagedAn update already downloaded and built… | object |
versionWhat the downloaded build says it… | string |
channelWhich channel it was taken from | string |
atWhen the download finished, in milliseconds,… | number |
planWhat the downloaded build's first boot… | object |
planThe format of this line | 1 |
versionThe release of the image that… | string |
engineThe conversion count builds before the… | number |
digestWhat identifies the planning build's conversion… | string |
okFalse when a conversion would fail… | boolean |
downgradeA newer release than the planning… | boolean |
failuresEach conversion or step that would… | object[] |
documentThe stored file whose conversion would… | string |
detailWhy, in the conversion's own words | string |
stepsWhat the first boot changes on… | object[] |
documentThe stored file, workspace-relative, or `<volume>:<path>`… | string |
changeWhat is done to it, in… | string |
detailWhat was particular about this one:… | string |
convertsWhat the build's conversions change as… | object[] |
documentThe stored file, workspace-relative, or `<volume>:<path>`… | string |
changeWhat is done to it, in… | string |
detailWhat was particular about this one:… | string |
filesEvery file the first boot writes,… | string[] |
preparingA download of the next update… | object |
channelWhich channel it is being taken… | string |
startedAtWhen the download began, in milliseconds | number |
atWhen the machine last said it… | number |
phaseWhat it is doing: download (pulling… | string |
percentHow far through the download it… | number |
lastUpdateWhat the machine running this sandbox… | object |
resultWhat happened | "updated" | "kept" | "restored" | "rolled-back" |
verbWhat was asked for: update, rollback,… | string |
atWhen it happened, in milliseconds | number |
fromThe version (or, when it would… | string |
toThe version (or image) that was… | string |
reasonWhy the host gave up on… | string |
logWhere the host kept the full… | string |
keepUntilUntil when the previous version stays… | number |
withdrawnSet when the version this sandbox… | object |
versionThe withdrawn version, which is the… | string |
reasonWhy it was withdrawn, as the… | string |
skippedVersionA release the owner chose to… | string |
autoUpdateWhether and when this sandbox takes… | object |
enabledWhether this sandbox takes downloaded updates… | boolean |
phaseWhere it stands: idle (nothing downloaded… | string |
versionThe downloaded version it will take | string |
holdsEverything keeping it waiting right now,… | object[] |
kindWhat it waits on: agents (an… | string |
namesWho or what, by name: the… | string[] |
untilWhen this lifts by itself, in… | number |
startsAtDuring a countdown, when the restart… | number |
pausedUntilThe owner's pause: no automatic update… | number |
failureWhy the last automatic try did… | string |
lastAppliedThe last update this sandbox took… | object |
at | number |
to | string |
curl "$SANDBOX/info" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.info();POST/system/update/skipStop offering one release
Stops offering the named release as an update, typically one this sandbox already tried and went back from. A newer release is offered as usual. Null offers the newest release again.
What you send
| Field | Type | Where |
|---|---|---|
versionrequiredThe release to stop offering, or… | string | null | body |
What comes back
| Field | Type |
|---|---|
okAlways true | true |
curl -X POST "$SANDBOX/system/update/skip" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"version":"1.4.0"}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.skipUpdate({
"version": "1.4.0"
});POST/system/update/autoDecide how updates are taken
Turns taking a downloaded update by itself on or off, pauses it until a moment, or takes the downloaded update right now. A sandbox taking updates by itself waits for a quiet moment: no agent mid-turn, nobody at the editor, terminals quiet. Answers with where it stands afterwards.
What you send
| Field | Type | Where |
|---|---|---|
enabledTurn taking downloaded updates by itself… | boolean | body |
pausedUntilHold automatic updates until this moment,… | number | body |
applyNowTake the downloaded update now, without… | true | body |
What comes back
| Field | Type |
|---|---|
enabledWhether this sandbox takes downloaded updates… | boolean |
phaseWhere it stands: idle (nothing downloaded… | string |
versionThe downloaded version it will take | string |
holdsEverything keeping it waiting right now,… | object[] |
kindWhat it waits on: agents (an… | string |
namesWho or what, by name: the… | string[] |
untilWhen this lifts by itself, in… | number |
startsAtDuring a countdown, when the restart… | number |
pausedUntilThe owner's pause: no automatic update… | number |
failureWhy the last automatic try did… | string |
lastAppliedThe last update this sandbox took… | object |
at | number |
to | string |
curl -X POST "$SANDBOX/system/update/auto" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"enabled":true,"pausedUntil":1,"applyNow":true}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.autoUpdate({
"enabled": true,
"pausedUntil": 1,
"applyNow": true
});GET/system/manifest-problemsSettings files the sandbox could not read
Anything the daemon tripped over in its own configuration on disk: a file it had to fall back from, a key it did not recognise, an entry it skipped. Separate from the identity call because it goes stale for a different reason, namely a file changing.
What you send
Nothing. Call it as it is.
What comes back
| Field | Type |
|---|---|
pathThe file, as a workspace path,… | string |
problemsEverything currently wrong with it | object[] |
kindWhat to do about it | "unreadable" | "unknownKey" | "invalidEntry" |
reasonWhy it could not be read:… | "io" | "not-json" | "conversion-failed" | "rejected" |
detailWhat exactly was wrong, as one… | string |
suggestionThe name it was probably meant… | string |
fixWhat to do about it, when… | string |
curl "$SANDBOX/system/manifest-problems" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.manifestProblems();POST/system/manifest-problems/repairTake a stray setting out of a file
Removes a key the sandbox does not recognise from one of its settings files, or renames it to the one it was probably meant to be, keeping the value. Only the files a person hand-edits can be named, and only a key — never a value — so this can only ever remove something already being ignored. Renaming onto a key the file already has is refused instead of overwriting it.
What you send
| Field | Type | Where |
|---|---|---|
pathrequiredThe file to repair, as the… | string | body |
keyrequiredThe stray top-level key, exactly as… | string | body |
toRename the key to this instead… | string | body |
What comes back
| Field | Type |
|---|---|
okAlways true | true |
curl -X POST "$SANDBOX/system/manifest-problems/repair" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"path":"src/app.ts","key":"OPENAI_API_KEY","to":"src/server.ts"}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.repairManifest({
"path": "src/app.ts",
"key": "OPENAI_API_KEY",
"to": "src/server.ts"
});POST/system/sessionTrade a sign-in for a session
Exchanges a verified sign-in, or a session that has not expired yet, for a fresh session the daemon minted. That session is the credential every other call carries, and calling this again with a live one renews it.
What you send
Nothing. Call it as it is.
What comes back
| Field | Type |
|---|---|
tokenThe credential every other call carries | string |
expiresAtWhen it stops working, in milliseconds,… | number |
emailWho the sandbox verified you as | string |
curl -X POST "$SANDBOX/system/session" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.session();GET/eventsThe live event streamstream
A stream held open for as long as you want it, carrying heartbeats so a caller notices the sandbox dying at once, batches of file changes so a tree or an editor can refresh itself, and the roster of who else is looking. Give it an id for this connection to appear in that roster; leave it out and you watch without being seen.
What you send
| Field | Type | Where |
|---|---|---|
clientId | string | query |
What comes back
| Field | Type |
|---|---|
when event is "message" | shape |
data | object |
when kind is "hello" | shape |
workspaceId | string |
routes | string[] |
shapes | object |
build | string |
boot | object |
projectDir | string |
surface | "sandbox" | "folder" |
when kind is "heartbeat" | shape |
rev | number |
when kind is "boot" | shape |
ready | boolean |
startedAt | number |
steps | object[] |
when kind is "workspaceChanged" | shape |
paths | string[] |
when kind is "treeChanged" | shape |
fromThe generation this applies on top… | integer |
generationThe generation it leaves the tree… | integer |
dirsEach folder that changed, parents before… | object[] |
barrenThe barren folders now, present only… | string[] |
when kind is "derivedChanged" | shape |
paths | string[] |
when kind is "reposChanged" | shape |
repos | string[] |
when kind is "refsChanged" | shape |
repos | string[] |
when kind is "runtimeChanged" | shape |
domains | string[] |
when kind is "presence" | shape |
users | object[] |
when kind is "agents" | shape |
agents | object[] |
rev | number |
when kind is "accountUsage" | shape |
provider | string |
account | string |
usage | object |
when kind is "providerRefusal" | shape |
provider | string |
refusal | object |
id | string |
retry | number |
when event is "done" | shape |
data | unknown |
id | string |
retry | number |
when event is "error" | shape |
data | unknown |
id | string |
retry | number |
curl -N "$SANDBOX/events" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.events();POST/system/presenceSay what you are looking at
Reports which view, conversation or file this connection is on, or that it has gone idle. The daemon fans it back out on the event stream so everyone else's roster updates.
What you send
| Field | Type | Where |
|---|---|---|
clientIdrequiredThis connection's own id, the same… | string | body |
idlerequiredWhether the person has stopped doing… | boolean | body |
awayWhether the window is on screen… | boolean | body |
viewWhich view they are on | string | body |
sessionIdWhich conversation they have open | string | body |
pathWhich file they are looking at | string | body |
What comes back
| Field | Type |
|---|---|
okAlways true | true |
curl -X POST "$SANDBOX/system/presence" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"clientId":"a1b2c3d4","idle":true,"away":true,"view":"…","sessionId":"a1b2c3d4","path":"src/app.ts"}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.presence({
"clientId": "a1b2c3d4",
"idle": true,
"away": true,
"view": "…",
"sessionId": "a1b2c3d4",
"path": "src/app.ts"
});GET/system/usageWhat has been spent
Token and cost totals per account, added up from the record of every finished turn.
What you send
Nothing. Call it as it is.
What comes back
| Field | Type |
|---|---|
accounts | object[] |
provider | string |
account | string |
turns | number |
inputTokens | number |
outputTokens | number |
cacheReadTokens | number |
cacheCreationTokens | number |
costUsd | number |
curl "$SANDBOX/system/usage" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.usage();GET/system/metricsWhat the sandbox is using right now
CPU and memory for the sandbox as a whole, for the daemon that runs it, for each kind of process, and for each conversation's own processes. Measured when you ask and never in between, so CPU is the use since the previous reading: the first reading after a quiet spell has memory and no CPU, and the next one a few seconds later has both.
What you send
Nothing. Call it as it is.
What comes back
| Field | Type |
|---|---|
atWhen this reading was taken, in… | number |
windowMsHow long the CPU figures were… | number |
sandboxThe sandbox as a whole | object |
cpuPercentCPU the whole sandbox used over… | number |
coresHow many cores the sandbox may… | number |
memoryBytesMemory counted against the limit, as… | number |
memoryLimitBytesThe memory limit work is admitted… | number |
swapBytesWhat was pushed out to swap,… | number |
swapLimitBytesWhat swap can hold | number |
swapFullSwap is nearly at `swapLimitBytes`: nothing… | boolean |
memoryRoomWhat admission reads off the same… | object |
freeBytesThe limit less what is used… | number |
reservedBytesWhat work admitted in the last… | number |
personNeedBytesWhat a person's turn needs free… | number |
stallPercentPercent of the last ten seconds… | number |
stallLimitPercentThe stall at or past which… | number |
stallSustainedPercentPercent of the last minute in… | number |
stallSustainedLimitPercentThe minute's stall at or past… | number |
diskBytesSpace used on the volume the… | number |
diskTotalBytesThat volume's size | number |
loadAverageThe load average over 1, 5… | unknown[] |
machineCoresCores the machine's load average reads… | number |
processesHow many processes are running in… | number |
pressureHow much work waited on CPU,… | object |
cpuPercent of the last ten seconds… | number |
memoryPercent of the last ten seconds… | number |
ioPercent of the last ten seconds… | number |
daemonThe daemon that runs it, which… | object |
rssBytesThe daemon's own resident memory | number |
heapUsedBytesOf that, JavaScript objects in use | number |
cpuPercentCPU the daemon itself used over… | number |
eventLoopPercentHow much of the window the… | number |
sessionsWhat each conversation's processes use, by… | object |
rolesEvery process in the sandbox but… | object |
curl "$SANDBOX/system/metrics" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.metrics();GET/system/storageWhat is filling the disk
The last measurement of the sandbox's disk, by what the space is for: conversations, checkouts, restore points, caches, logs, the trash and the rest, each with its biggest parts and whether it can be cleaned from here. Reading it measures nothing; ask for a scan to measure again.
What you send
Nothing. Call it as it is.
What comes back
| Field | Type |
|---|---|
scanThe last scan that finished | object |
startedAtWhen the scan began, in milliseconds | number |
finishedAtWhen it ended, in milliseconds: the… | number |
outcome`partial` when the scan hit its… | "complete" | "partial" |
diskThe volume as a whole | object |
usedBytesSpace used on the volume the… | number |
totalBytesThat volume's size | number |
categoriesEvery category that holds anything, largest… | object[] |
id | "workspace" | "conversations" | "checkouts" | "restorePoints" … (22) |
cleanabilityWhether this category can be cleaned… | "none" | "safe" | "confirm" |
bytesIts size in bytes | number |
filesHow many files it holds | number |
cleanableBytesWhat cleaning it would free right… | number |
itemsIts biggest parts, largest first, at… | object[] |
pathWhere it is, as an absolute… | string |
bytesIts size in bytes | number |
unreadableFiles and folders the scan could… | number |
scanningWhether a scan is running now | boolean |
curl "$SANDBOX/system/storage" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.storage();POST/system/storage/scanMeasure what is filling the disk
Walks the sandbox's volumes and answers with the new measurement once it is done. A scan already running is joined rather than doubled. It stops at a time limit and says so, since a size it could not finish is still worth reading. A cancelled scan answers with the previous measurement.
What you send
Nothing. Call it as it is.
What comes back
| Field | Type |
|---|---|
scanThe last scan that finished | object |
startedAtWhen the scan began, in milliseconds | number |
finishedAtWhen it ended, in milliseconds: the… | number |
outcome`partial` when the scan hit its… | "complete" | "partial" |
diskThe volume as a whole | object |
usedBytesSpace used on the volume the… | number |
totalBytesThat volume's size | number |
categoriesEvery category that holds anything, largest… | object[] |
id | "workspace" | "conversations" | "checkouts" | "restorePoints" … (22) |
cleanabilityWhether this category can be cleaned… | "none" | "safe" | "confirm" |
bytesIts size in bytes | number |
filesHow many files it holds | number |
cleanableBytesWhat cleaning it would free right… | number |
itemsIts biggest parts, largest first, at… | object[] |
pathWhere it is, as an absolute… | string |
bytesIts size in bytes | number |
unreadableFiles and folders the scan could… | number |
scanningWhether a scan is running now | boolean |
curl -X POST "$SANDBOX/system/storage/scan" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.scanStorage();DELETE/system/storage/scanStop measuring the disk
Stops a running scan. Whoever was waiting on it gets the previous measurement back; nothing is lost but the time.
What you send
Nothing. Call it as it is.
What comes back
| Field | Type |
|---|---|
okAlways true | true |
curl -X DELETE "$SANDBOX/system/storage/scan" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.cancelStorageScan();POST/system/storage/cleanFree the space one category holds
Removes what one cleanable category holds, and says how much space that gave back. Only what is old enough and not in use goes: today's logs, a browser that is open, the weights a running model reads and a pack still being written all stay. Nothing outside the sandbox's own volumes, and nothing a category may not hold, is ever removed. Categories that cannot be cleaned are refused.
What you send
| Field | Type | Where |
|---|---|---|
categoryrequiredThe category to clean; one whose… | "workspace" | "conversations" | "checkouts" | "restorePoints" … (22) | body |
What comes back
| Field | Type |
|---|---|
category | "workspace" | "conversations" | "checkouts" | "restorePoints" … (22) |
freedBytesSpace the removals gave back, in… | number |
removedHow many items were removed | number |
keptHow many were left in place:… | number |
failedHow many removals the filesystem refused | number |
curl -X POST "$SANDBOX/system/storage/clean" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"category":"workspace"}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.cleanStorage({
"category": "workspace"
});GET/system/terminalsOpen terminals
The terminal sessions this sandbox is holding, which is what a terminal panel rebuilds its tabs from after a reload. The live typing and output run over a separate socket; this is the list.
What you send
Nothing. Call it as it is.
What comes back
| Field | Type |
|---|---|
sessionsEvery live surface the sandbox is… | object[] |
nameIts id, and what the close… | string |
labelWhat to call it on screen | string |
kindWhat sort of thing it is:… | "shell" | "panel" | "agent" | "job" … (5) |
runningWhether it is alive | boolean |
activityAtWhen it last produced output, in… | number |
exitCodeHow the last thing in it… | number |
commandWhat is running in it right… | string |
extensionIdWhich extension declared this process, when… | string |
processNameWhich of that extension's processes it… | string |
helpThe agent has stopped at something… | object |
requestIdWhat to send back when you… | string |
messageWhat the agent needs, in its… | string |
requestedAtWhen it asked, in milliseconds | number |
curl "$SANDBOX/system/terminals" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.terminals();DELETE/system/terminals/{name}Close a terminal
Destroys one terminal session and whatever was running inside it.
What you send
| Field | Type | Where |
|---|---|---|
namerequiredWhich terminal | string | address |
What comes back
| Field | Type |
|---|---|
okAlways true | true |
curl -X DELETE "$SANDBOX/system/terminals/nightly%20changelog" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.killTerminal({
"name": "nightly changelog"
});GET/system/terminals/{name}/scrollbackA terminal's history as plain text
What has scrolled past in one terminal, as text you can select and copy. The live view is a picture of a screen on the far side of a socket, with nothing in the page to select, so scrolling back and copying is this call rather than a gesture.
What you send
| Field | Type | Where |
|---|---|---|
namerequiredWhich terminal | string | address |
linesHow far back to ask for | number | query |
What comes back
| Field | Type |
|---|---|
nameWhich terminal this is from | string |
textThe history, oldest line first, with… | string |
linesHow many lines you got | number |
truncatedIt stopped because you asked for… | boolean |
curl "$SANDBOX/system/terminals/nightly%20changelog/scrollback" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.terminalScrollback({
"name": "nightly changelog"
});GET/system/browsersBrowsers the agent has open
Every browser a conversation currently has running and the pages inside each one. The picture of what they are showing comes over a separate socket; this is the roster.
What you send
Nothing. Call it as it is.
What comes back
| Field | Type |
|---|---|
sessionsEvery browser the agents have running,… | object[] |
nameIts id, and what the close… | string |
labelWhat to call it on screen:… | string |
serverWhich browser drives it: the credential-free… | string |
runningWhether it is still open | boolean |
activityAtWhen it last did anything, in… | number |
finishedAtWhen it closed, in milliseconds | number |
helpThe agent has hit something only… | object |
requestIdWhat to send back when you… | string |
messageWhat the agent needs, in its… | string |
requestedAtWhen it asked, in milliseconds | number |
dialogA dialog a page has open… | object |
pageIdWhich page opened it | string |
kindWhat it asks: an alert wants… | "alert" | "confirm" | "prompt" | "beforeunload" |
messageWhat the page says | string |
defaultValueA prompt's prefilled answer | string |
pagesEvery page it has open | object[] |
idStable for the life of the… | string |
titleThe page's title | string |
urlWhere it is | string |
activeThe one the agent last touched,… | boolean |
curl "$SANDBOX/system/browsers" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.browsers();DELETE/system/browsers/{name}Shut a browser down
Closes one of the agent's browsers. Its next attempt to use that browser then fails as though it had crashed, which is the honest account of somebody pulling the plug.
What you send
| Field | Type | Where |
|---|---|---|
namerequiredWhich browser | string | address |
What comes back
| Field | Type |
|---|---|
okAlways true | true |
curl -X DELETE "$SANDBOX/system/browsers/nightly%20changelog" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.closeBrowser({
"name": "nightly changelog"
});GET/system/desktopThe sandbox's own desktop
Whether the sandbox's desktop is up, which display it is, and how many windows are open on it. The live picture of it comes over a separate socket; this says whether there is anything to see.
What you send
Nothing. Call it as it is.
What comes back
| Field | Type |
|---|---|
runningWhether the desktop is up | boolean |
displayThe X display it is, present… | string |
windowsHow many windows are open on… | integer |
curl "$SANDBOX/system/desktop" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.desktop();GET/system/subagentsSubagents the agents have started
Every subagent that conversations the caller can see have delegated work to, whichever tool started it, with what each one is doing: all that are still working, and the most recent that have settled.
What you send
Nothing. Call it as it is.
What comes back
| Field | Type |
|---|---|
sessionsThe subagents conversations the caller can… | object[] |
idThe id of the tool call… | string |
kindHow it was started: in-process by… | "subagent" | "spawned" |
conversationIdThe conversation whose turn started it,… | string |
agentTypeWhat kind of subagent it is | string |
descriptionWhat it was asked to do,… | string |
modelWhich model it runs on: the… | string |
effortHow hard it was told to… | string |
providerWhich provider serves it, for a… | string |
spawnDepthHow deep in the chain it… | number |
backgroundThe parent carried on working instead… | boolean |
statusHow it is going | "pending" | "running" | "blocked" | "completed" … (7) |
startedAtWhen it started, in milliseconds | number |
endedAtWhen it finished, in milliseconds | number |
activityAtWhen it last did anything, in… | number |
tokensWhat it has spent | number |
toolUsesHow many tools it has used | number |
lastToolThe last one it reached for | string |
summaryIts report: what it concluded, without… | string |
errorWhy it failed, when it did | string |
verificationWhether anything proved the work its… | object |
stateWhether anything proved its work: a… | "verified" | "unproven" | "failing" | "no-code" |
pathsThe code files it changed, most… | string[] |
checkThe command that spoke: the one… | string |
curl "$SANDBOX/system/subagents" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.subagents();GET/system/devicesThe machines you have connected
Every computer this sandbox can see, whether it reached it through desktop sync or through a connected device, in one row per machine: what it says about itself, which sandboxes it holds, and what stopped it answering when nothing came back.
What you send
Nothing. Call it as it is.
What comes back
| Field | Type |
|---|---|
devices | object[] |
key | string |
label | string |
sync | object |
machine | string |
mode | "sync" | "mirror" |
seenAt | number |
machineId | string |
environment | string |
hostId | string |
card | string |
machineId | string |
online | boolean |
platform | string |
facts | object |
machineId | string |
os | string |
arch | string |
shell | string |
home | string |
roots | string[] |
engine | object |
memoryBytes | number |
cpus | number |
hostname | string |
wsl | object |
distro | string |
wslDistros | string[] |
links | object |
total | number |
unreachable | number |
unreachableSince | number |
features | string[] |
icOutOfDate | string |
upkeep | object |
at | number |
found | object |
fixed | object |
skipped | object[] |
agentVersion | string |
lastSeen | number |
report | object |
machineId | string |
hostname | string |
os | string |
wsl | object |
distro | string |
pairings | object[] |
sandboxId | string |
mode | "sync" | "mirror" |
localDir | string |
remoteDir | string |
projectsHost | boolean |
deliver | "auto" | "off" |
mirroring | "on" | "off" |
mutagenStatus | string |
conflicts | integer |
conflictedPaths | object[] |
paused | boolean |
backupStatus | string |
ports | object[] |
port | integer |
host | "127.0.0.1" | "::1" |
sandboxId | string |
state | "mirrored" | "held-by-sandbox" | "busy" | "ignored" |
heldBy | string |
command | string |
agent | object |
running | boolean |
pid | integer |
installed | string |
build | string |
lastTickAt | number |
capturedAt | number |
sandboxes | object[] |
slug | string |
container | string |
name | string |
running | boolean |
image | string |
tunnelRunning | boolean |
resources | object |
memoryBytes | number |
cpus | number |
privileged | boolean |
gpu | boolean |
hostRuntime | string[] |
overlayRuntime | string[] |
shape | object |
desired | object |
saved | object |
staged | object |
image | string |
version | string |
channel | string |
version | string |
parked | boolean |
probationUntil | number |
lastUpdate | object |
resultWhat happened | "updated" | "kept" | "restored" | "rolled-back" |
verbWhat was asked for: update, rollback,… | string |
atWhen it happened, in milliseconds | number |
fromThe version (or, when it would… | string |
toThe version (or image) that was… | string |
reasonWhy the host gave up on… | string |
logWhere the host kept the full… | string |
keepUntilUntil when the previous version stays… | number |
rollbackTargets | object[] |
imageThe local image a rollback would… | string |
versionWhat that image says it is | string |
downloadThe local pin is gone (pruned… | boolean |
keptElsewhere | string |
keptElsewhereName | string |
adoptedFrom | string |
keeperSilentSince | number |
gap | "offline" | "scope-off" | "unreported" |
curl "$SANDBOX/system/devices" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.devices();POST/system/devices/{id}/sandboxes/{slug}Drive a sandbox on one of your own devicesstream
Start, stop, restart, update, rebuild, roll back, reshape (its memory and CPU caps, privileged, GPU) or remove a sandbox running on a machine you own, relayed over the connection that machine holds open. The answer is a stream because the slowest of these takes minutes, and it is the same stream whichever you ask for. The daemon adds no opinion: the machine enforces its own permissions and a refusal arrives as the last line, in the machine's words, naming the switch to flip.
What you send
| Field | Type | Where |
|---|---|---|
idrequired | string | address |
slugrequired | string | address |
oprequired | "start" | "stop" | "restart" | "prepare" … (17) | body |
hash | string | body |
to | string | body |
shape | object | body |
memoryGibrequired | integer | null | body |
cpusrequired | integer | null | body |
privilegedrequired | boolean | body |
gpurequired | boolean | body |
when | "now" | "nextRestart" | body |
resources | object | body |
memoryGib | integer | null | body |
cpus | integer | null | body |
privileged | boolean | body |
gpu | boolean | body |
later | boolean | body |
parentUrl | string | body |
pair | string | body |
setupCode | string | body |
platformUrl | string | body |
definition | string | body |
overlay | string | body |
overlayHash | string | body |
resumeTurns | boolean | body |
What comes back
| Field | Type |
|---|---|
when event is "message" | shape |
data | object |
when kind is "line" | shape |
text | string |
when kind is "result" | shape |
message | string |
when kind is "error" | shape |
message | string |
id | string |
retry | number |
when event is "done" | shape |
data | unknown |
id | string |
retry | number |
when event is "error" | shape |
data | unknown |
id | string |
retry | number |
curl -N -X POST "$SANDBOX/system/devices/a1b2c3d4/sandboxes/nightly-changelog" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"op":"start","hash":"…","to":"src/server.ts","shape":{"memoryGib":1,"cpus":1,"privileged":true,"gpu":true},"when":"now","resources":{"memoryGib":1,"cpus":1,"privileged":true,"gpu":true},"later":true,"parentUrl":"https://sandbox-a1b2c3d4e5f6.intentic.dev","pair":"…","setupCode":"…","platformUrl":"https://sandbox-a1b2c3d4e5f6.intentic.dev","definition":"…","overlay":"…","overlayHash":"…","resumeTurns":true}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.manageDeviceSandbox({
"id": "a1b2c3d4",
"slug": "nightly-changelog",
"op": "start",
"hash": "…",
"to": "src/server.ts",
"shape": {
"memoryGib": 1,
"cpus": 1,
"privileged": true,
"gpu": true
},
"when": "now",
"resources": {
"memoryGib": 1,
"cpus": 1,
"privileged": true,
"gpu": true
},
"later": true,
"parentUrl": "https://sandbox-a1b2c3d4e5f6.intentic.dev",
"pair": "…",
"setupCode": "…",
"platformUrl": "https://sandbox-a1b2c3d4e5f6.intentic.dev",
"definition": "…",
"overlay": "…",
"overlayHash": "…",
"resumeTurns": true
});POST/system/devices/{id}/commands/{command}Run one of your device's own CLI actions
Performs a named action on a machine you own by running its own intentic-machine command there — turning that device's port mirroring off, say — over the connection it holds open. The set of actions is fixed and the command line is built here from the name, never sent by the caller. The machine enforces its own permissions and a refusal comes back as its own sentence, naming the switch to flip.
What you send
| Field | Type | Where |
|---|---|---|
idrequired | string | address |
commandrequired | "mirror-off" | "mirror-on" | "mirror-ignore" | "mirror-unignore" … (12) | address |
sandboxId | string | body |
mode | "sync" | "mirror" | body |
localDir | string | body |
port | integer | body |
What comes back
| Field | Type |
|---|---|
ok | boolean |
message | string |
output | string |
refused | boolean |
curl -X POST "$SANDBOX/system/devices/a1b2c3d4/commands/mirror-off" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"sandboxId":"a1b2c3d4e5f6","mode":"sync","localDir":"…","port":5173}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.runDeviceCommand({
"id": "a1b2c3d4",
"command": "mirror-off",
"sandboxId": "a1b2c3d4e5f6",
"mode": "sync",
"localDir": "…",
"port": 5173
});POST/system/devices/{id}/agent/{op}Update, restart, or clean up the links of the agent on one of your own devicesstream
Updates a machine you own to the current intentic-machine agent, restarts the loop it is running, or drops the links it holds to sandboxes that have stopped answering — over the connection that machine holds open. The answer is a stream of the run's own output — and it normally stops mid-run, because the agent's loop is what carries this connection: the work is detached from it first, so it finishes regardless, and the device's reported version is what confirms it. Takes the machine's "Run commands" permission, the same one a command typed there would.
What you send
| Field | Type | Where |
|---|---|---|
idrequired | string | address |
oprequired | "upgrade" | "restart" | "forget-unreachable" | address |
What comes back
| Field | Type |
|---|---|
when event is "message" | shape |
data | object |
when kind is "line" | shape |
text | string |
when kind is "result" | shape |
message | string |
when kind is "error" | shape |
message | string |
id | string |
retry | number |
when event is "done" | shape |
data | unknown |
id | string |
retry | number |
when event is "error" | shape |
data | unknown |
id | string |
retry | number |
curl -N -X POST "$SANDBOX/system/devices/a1b2c3d4/agent/upgrade" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.system.runDeviceAgentFlow({
"id": "a1b2c3d4",
"op": "upgrade"
});