intentic
Create your workspace
The workspace

Workspace

The file tree the agents work on: read it, search it, change it, and run what is in it

On this page(25 sections)

Everything under the workspace root. The tree and one folder's contents, a window of a file's text, search that blends text, structure, meaning and history, and the ordinary changes: make a folder, delete, move, copy. It also holds what a workspace knows about itself — which repos it contains, how its packages depend on each other, which apps are in it, and starting or stopping one.

25 calls. Pick one to open it, or use the list on the right.

GET/workspace/treeThe workspace file tree

Every folder and file under the workspace root, as one walk. Name a conversation to read its own private copy of the tree instead of the shared one. Folders the daemon skips, such as installed packages, come back without their contents; ask for those separately.

What you send

FieldTypeWhere
agentRead a conversation's own private copy…stringquery

What comes back

FieldType
rootThe path everything below is relative…string
treeThe workspace, one entry per file…object[]
nameJust this entry's own namestring
pathIts full path from the workspace…string
typeWhat it is"file" | "dir"
sizeSize in bytes, for a filenumber
ignoredTooling ignores it: installed packages, git…boolean
linkPresent when this entry is a…object
toWhat the link says, verbatim, rather…string
stateAbsent for an ordinary link"broken" | "outside"
childrenWhat is inside a folderobject[]
nameJust this entry's own namestring
pathIts full path from the workspace…string
typeWhat it is"file" | "dir"
sizeSize in bytes, for a filenumber
ignoredTooling ignores it: installed packages, git…boolean
linkPresent when this entry is a…object
toWhat the link says, verbatim, rather…string
stateAbsent for an ordinary link"broken" | "outside"
childrenWhat is inside a folderobject[]
nameJust this entry's own namestring
pathIts full path from the workspace…string
typeWhat it is"file" | "dir"
sizeSize in bytes, for a filenumber
ignoredTooling ignores it: installed packages, git…boolean
linkPresent when this entry is a…object
childrenWhat is inside a folderobject[]
hiddenHow many entries at the top…number
Try itanswered in this tab
curl
curl "$SANDBOX/workspace/tree" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.tree();
GET/workspace/childrenOne folder's contents

The entries directly inside a single folder. This is how you open a folder the full tree walk deliberately left closed, such as an installed-packages directory with a hundred thousand files in it.

What you send

FieldTypeWhere
agentRead a conversation's own private copy…stringquery
pathrequiredThe folder to open, as a…stringquery

What comes back

FieldType
entriesWhat is directly inside itobject[]
nameJust this entry's own namestring
pathIts full path from the workspace…string
typeWhat it is"file" | "dir"
sizeSize in bytes, for a filenumber
ignoredTooling ignores it: installed packages, git…boolean
linkPresent when this entry is a…object
toWhat the link says, verbatim, rather…string
stateAbsent for an ordinary link"broken" | "outside"
childrenWhat is inside a folderobject[]
nameJust this entry's own namestring
pathIts full path from the workspace…string
typeWhat it is"file" | "dir"
sizeSize in bytes, for a filenumber
ignoredTooling ignores it: installed packages, git…boolean
linkPresent when this entry is a…object
toWhat the link says, verbatim, rather…string
stateAbsent for an ordinary link"broken" | "outside"
childrenWhat is inside a folderobject[]
nameJust this entry's own namestring
pathIts full path from the workspace…string
typeWhat it is"file" | "dir"
sizeSize in bytes, for a filenumber
ignoredTooling ignores it: installed packages, git…boolean
linkPresent when this entry is a…object
childrenWhat is inside a folderobject[]
hiddenHow many entries were cut for…number
Try itanswered in this tab
curl
curl "$SANDBOX/workspace/children?path=src%2Fapp.ts" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.children({
  "path": "src/app.ts"
});
GET/workspace/fileRead part of a text file

A window of one file's text, plus how large the whole file is. Never the entire file: an unbounded read is how a single enormous log stalls the daemon for everyone, so ask for the slice you mean to show and page through if you need more.

What you send

FieldTypeWhere
agentRead a conversation's own private copy…stringquery
pathrequiredThe file to read, as a…stringquery
offsetWhich byte to start atintegerquery
limitHow many bytes to readintegerquery

What comes back

FieldType
when present is trueshape
pathThe path, as asked forstring
contentThe bytes of the window you…string
sizeHow large the whole file isnumber
offsetWhich byte the window starts atnumber
bytesHow many bytes the window holdsnumber
sharedWhich tree answeredboolean
when present is falseshape
pathThe path, as asked forstring
Try itanswered in this tab
curl
curl "$SANDBOX/workspace/file?path=src%2Fapp.ts" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.file({
  "path": "src/app.ts"
});
POST/workspace/media-ticketGet a pass for streaming a media file

Mints the short-lived ticket a video or audio element hands to the streaming route, which serves byte ranges and so cannot carry an ordinary header. Minting it here means a caller can tell whether this sandbox streams media at all, rather than discovering it mid-playback.

What you send

FieldTypeWhere
agentRead a conversation's own private copy…stringbody
pathrequiredThe media file the ticket should…stringbody

What comes back

FieldType
ticketHand this to the streaming route…string
expiresAtWhen it stops working, in milliseconds,…number
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/workspace/media-ticket" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"agent":"…","path":"src/app.ts"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.mediaTicket({
  "agent": "",
  "path": "src/app.ts"
});
GET/workspace/resolveTurn a written path into a real file

Matches a path somebody wrote in prose against the real tree and says which file it means. A path mentioned in a message is often only the tail of the real one, so this is the lookup behind every clickable file reference rather than a plain existence check.

What you send

FieldTypeWhere
agentRead a conversation's own private copy…stringquery
pathrequiredThe reference as somebody wrote itstringquery

What comes back

FieldType
pathThe real path it meansstring
Try itanswered in this tab
curl
curl "$SANDBOX/workspace/resolve?path=src%2Fapp.ts" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.resolve({
  "path": "src/app.ts"
});
GET/workspace/healthA repo's shape in numbers

Where one repo's risk sits: the files that change often and are complicated at once, what the index holds, and which modules the rest of the code leans on most. Scoped to a repo, because a codebase is a repo rather than the whole drop.

What you send

FieldTypeWhere
reporequiredWhich repository, using the same ids…stringquery
sinceHow far back to count changes,…stringquery
limitHow many files and modules to…integerquery

What comes back

FieldType
repoWhich repository this describesstring
totalsCounts anybody could recount in the…object
filesFiles countednumber
symbolsNamed things they exportnumber
complexityBranch points across all of them…number
hotspotsHow many files qualify as hotspots…number
hotspotsFiles that change often and are…object[]
pathstring
commitsnumber
addsnumber
delsnumber
complexitynumber
scorenumber
latestMsnumber
modulesThe parts of the codebase the…object[]
pathstring
exportsnumber
freshnessWhether the index these numbers were…object
stateWhether the index matches what is…"fresh" | "building" | "stale"
ageMsHow long since it last matched…number
progressHow far through building it is,…number
behindHow many files it has not…number
Try itanswered in this tab
curl
curl "$SANDBOX/workspace/health?repo=root" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.health({
  "repo": "root"
});
GET/workspace/classifySort a messy drop into buckets

Proposes which of the loose things in the workspace are code, documents, media or archives. A read-only suggestion by fixed rules, with no model involved: nothing moves until a caller applies the moves it likes through the move call.

What you send

Nothing. Call it as it is.

What comes back

FieldType
classificationsOne entry per repository folder and…object[]
pathWhat was looked atstring
bucketWhich bucket it was sorted into"repositories" | "documents" | "media" | "archives" … (5)
reasonThe signal that decided it, so…string
Try itanswered in this tab
curl
curl "$SANDBOX/workspace/classify" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.classify();
POST/workspace/dirCreate a folder

Makes a folder, and any missing folders above it.

What you send

FieldTypeWhere
pathrequiredThe folder to createstringbody

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/workspace/dir" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"path":"src/app.ts"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.mkdir({
  "path": "src/app.ts"
});
DELETE/workspace/entryDelete a file or folder

Removes one entry and everything under it. The path travels in the body rather than the address, the same as every other write in this group.

What you send

FieldTypeWhere
pathrequiredThe file or folder, as a…stringbody

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X DELETE "$SANDBOX/workspace/entry" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"path":"src/app.ts"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.delete({
  "path": "src/app.ts"
});
POST/workspace/moveMove or rename something

Moves one entry to a new path, which is also how you rename it.

What you send

FieldTypeWhere
fromrequiredWhat to move or copy, as…stringbody
torequiredWhere it should end upstringbody

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/workspace/move" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"from":"src/app.ts","to":"src/server.ts"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.move({
  "from": "src/app.ts",
  "to": "src/server.ts"
});
POST/workspace/copyCopy a file or folder

Duplicates one entry at a new path, recursively for a folder.

What you send

FieldTypeWhere
fromrequiredWhat to move or copy, as…stringbody
torequiredWhere it should end upstringbody

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/workspace/copy" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"from":"src/app.ts","to":"src/server.ts"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.copy({
  "from": "src/app.ts",
  "to": "src/server.ts"
});
GET/workspace/setupWhich projects have their dependencies installed

Per project, whether its dependencies are actually present. A project that arrives by import comes without them, so files landing is not the same as the project working: until this says a project is ready, its type checks and tests can only mislead you.

What you send

Nothing. Call it as it is.

What comes back

FieldType
projectsEvery project the sandbox found, and…object[]
dirWhere the project is, relative to…string
ecosystemWhich language's tooling it uses"node" | "python"
managerThe tool that would do the…string
commandThe exact command that would runstring
evidenceThe file that decided all of…string
stateReady means its dependencies are really…"ready" | "installing" | "needs-setup" | "unsupported" … (5)
missingHow many declared dependencies cannot be…number
Try itanswered in this tab
curl
curl "$SANDBOX/workspace/setup" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.setup();
POST/workspace/setup/installInstall a project's dependencies

Starts the install for one or more projects in a terminal you can attach to, and answers immediately. The run survives a page reload and its output stays in the terminal history.

What you send

FieldTypeWhere
dirsrequiredWhich projects to install, by folderstring[]body

What comes back

FieldType
queuedWhich of them actually started, which…string[]
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/workspace/setup/install" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"dirs":["src","docs"]}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.install({
  "dirs": [
    "src",
    "docs"
  ]
});
GET/workspace/reposRepos in the workspace

Every git repo the daemon found in the workspace, with where each one sits and what it is called.

What you send

Nothing. Call it as it is.

What comes back

FieldType
reposEvery repository's id, sortedstring[]
Try itanswered in this tab
curl
curl "$SANDBOX/workspace/repos" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.repos();
POST/workspace/reposClone a repo in

Clones a repository into the workspace beside the others, using whatever forge credentials the sandbox already holds.

What you send

FieldTypeWhere
namerequiredWhat to call it in the…stringbody
cloneUrlrequiredWhere to clone it fromstringbody
branchWhich branch to check outstringbody

What comes back

FieldType
nameWhat it ended up calledstring
pathWhere it landedstring
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/workspace/repos" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"name":"nightly changelog","cloneUrl":"https://sandbox-a1b2c3d4e5f6.intentic.dev","branch":"main"}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.addRepo({
  "name": "nightly changelog",
  "cloneUrl": "https://sandbox-a1b2c3d4e5f6.intentic.dev",
  "branch": "main"
});
POST/workspace/syncPull every repo up to date

Fetches every repo that has a remote and fast-forwards the ones that can move safely, reporting what happened to each. This runs by itself at the start of a turn; call it directly to refresh on demand, or to re-sync a repo that had drifted.

What you send

Nothing. Call it as it is.

What comes back

FieldType
reposOne entry per repository, saying what…object[]
repoWhich repositorystring
statusWhat happened to it"updated" | "current" | "dirty" | "diverged" … (7)
behindHow many commits it was behindnumber
aheadHow many commits it was aheadnumber
headThe commit it ended up onstring
messageWhat went wrong, when something didstring
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/workspace/sync" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.sync();
GET/workspace/templatesApp templates you can add

The kinds of app the configured source repo knows how to scaffold, which is what an add-app picker lists.

What you send

Nothing. Call it as it is.

What comes back

FieldType
templatesThe kinds of app the configured…object[]
keyThe id to name when scaffolding…string
labelWhat to call it on screenstring
descriptionWhat you getstring
Try itanswered in this tab
curl
curl "$SANDBOX/workspace/templates" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.templates();
POST/workspace/repos/{repo}/appsScaffold new apps into a repo

Starts scaffolding one or more apps inside an existing multi-package repo and answers straight away. Watch the terminal it opens for progress and for anything that goes wrong.

What you send

FieldTypeWhere
reporequiredWhich repository to scaffold intostringaddress
appsrequiredThe apps to addobject[]body
templaterequiredWhich kind of app to scaffold,…stringbody
namerequiredWhat to call this onestringbody

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/workspace/repos/root/apps" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"apps":[{"template":"…","name":"nightly changelog"},{"template":"…","name":"release notes"}]}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.addApps({
  "repo": "root",
  "apps": [
    {
      "template": "",
      "name": "nightly changelog"
    },
    {
      "template": "",
      "name": "release notes"
    }
  ]
});
GET/workspace/repos/{repo}/appsApps inside a repo

The apps in one multi-package repo, each with its preview address and whether its dev server is up.

What you send

FieldTypeWhere
reporequiredWhich repositorystringaddress

What comes back

FieldType
appsThe apps in this repositoryobject[]
appThe app's name, which is also…string
kindWhat sort of app it is:…string
previewUrlWhere to open itstring
runningWhether its dev server is upboolean
healthyWhether it is actually answeringboolean
Try itanswered in this tab
curl
curl "$SANDBOX/workspace/repos/root/apps" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.appsList({
  "repo": "root"
});
GET/workspace/repos/{repo}/graphHow a repo's packages depend on each other

Every package in one multi-package repo and which of its siblings each one uses, which is what a dependency view draws.

What you send

FieldTypeWhere
reporequiredWhich repositorystringaddress

What comes back

FieldType
packagesEvery package in the repositoryobject[]
nameThe name the package declaresstring
dirWhere it lives, relative to the…string
groupThe top-level folder it sits under,…string
edgesWhich of them use whichobject[]
fromThe package that dependsstring
toThe package it depends onstring
typeWhich kind of dependency declared it"prod" | "dev" | "peer"
Try itanswered in this tab
curl
curl "$SANDBOX/workspace/repos/root/graph" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.packageGraph({
  "repo": "root"
});
GET/workspace/modulesEvery package across every repo

The named packages in the whole workspace, which is what a review list groups changed files under when a reader wants packages rather than paths. Whole-workspace in one answer, because a review spans repos and asking per repo would be a fan-out on every open.

What you send

Nothing. Call it as it is.

What comes back

FieldType
reposEvery repository with the packages inside…object[]
repoWhich repositorystring
modulesIts packagesobject[]
dirWhere the package lives, relative to…string
nameThe name the package declares for…string
Try itanswered in this tab
curl
curl "$SANDBOX/workspace/modules" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.modules();
POST/workspace/repos/{repo}/apps/{app}/startStart an app's dev server

Brings up one app's preview server in an attachable terminal, so its address starts answering.

What you send

FieldTypeWhere
reporequiredWhich repositorystringaddress
apprequiredWhich app inside itstringaddress

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/workspace/repos/root/apps/%E2%80%A6/start" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.startApp({
  "repo": "root",
  "app": ""
});
POST/workspace/repos/{repo}/apps/{app}/stopStop an app's dev server

Shuts one app's preview server down and frees its port.

What you send

FieldTypeWhere
reporequiredWhich repositorystringaddress
apprequiredWhich app inside itstringaddress

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/workspace/repos/root/apps/%E2%80%A6/stop" \
  -H "x-intentic-control: $INTENTIC_TOKEN"
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.stopApp({
  "repo": "root",
  "app": ""
});
POST/workspace/repos/{repo}/testsRun a project's tests

Starts the test run for the projects you name in an attachable terminal and answers straight away. The terminal is where the results appear.

What you send

FieldTypeWhere
reporequiredWhich repositorystringaddress
sessionrequiredWhat to call the terminal this…stringbody
dirsrequiredWhich projects to test, as folders…string[]body

What comes back

FieldType
okAlways truetrue
Try itanswered in this tab
curl
curl -X POST "$SANDBOX/workspace/repos/root/tests" \
  -H "x-intentic-control: $INTENTIC_TOKEN" \
  -H "content-type: application/json" \
  -d '{"session":"panel-root--dev","dirs":["src","docs"]}'
TypeScript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.runTests({
  "repo": "root",
  "session": "panel-root--dev",
  "dirs": [
    "src",
    "docs"
  ]
});
More in The workspace

Type to search every page, in the docs and the API reference.