---
title: "Workspace · intentic sandbox API"
description: "The file tree the agents work on: read it, search it, change it, and run what is in it. Every route in the workspace group of the intentic sandbox API, with its input, its answer and a playground."
url: "https://intentic.dev/api/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)**

- [The workspace file tree](#workspace-tree)
- [One folder's contents](#workspace-children)
- [Read part of a text file](#workspace-file)
- [Get a pass for streaming a media file](#workspace-mediaTicket)
- [Turn a written path into a real file](#workspace-resolve)
- [Search the code](#workspace-search)
- [A repo's shape in numbers](#workspace-health)
- [Sort a messy drop into buckets](#workspace-classify)
- [Create a folder](#workspace-mkdir)
- [Delete a file or folder](#workspace-delete)
- [Move or rename something](#workspace-move)
- [Copy a file or folder](#workspace-copy)
- [Which projects have their dependencies installed](#workspace-setup)
- [Install a project's dependencies](#workspace-install)
- [Repos in the workspace](#workspace-repos)
- [Clone a repo in](#workspace-addRepo)
- [Pull every repo up to date](#workspace-sync)
- [App templates you can add](#workspace-templates)
- [Scaffold new apps into a repo](#workspace-addApps)
- [Apps inside a repo](#workspace-appsList)
- [How a repo's packages depend on each other](#workspace-packageGraph)
- [Every package across every repo](#workspace-modules)
- [Start an app's dev server](#workspace-startApp)
- [Stop an app's dev server](#workspace-stopApp)
- [Run a project's tests](#workspace-runTests)

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/tree` The 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

| Field | Type | Where |
| --- | --- | --- |
| `agent` Read a conversation's own private copy… | string | query |

### What comes back

| Field | Type |
| --- | --- |
| `root` The path everything below is relative… | string |
| `tree` The workspace, one entry per file… | object[] |
| `name` Just this entry's own name | string |
| `path` Its full path from the workspace… | string |
| `type` What it is | "file" | "dir" |
| `size` Size in bytes, for a file | number |
| `ignored` Tooling ignores it: installed packages, git… | boolean |
| `link` Present when this entry is a… | object |
| `to` What the link says, verbatim, rather… | string |
| `state` Absent for an ordinary link | "broken" | "outside" |
| `children` What is inside a folder | object[] |
| `name` Just this entry's own name | string |
| `path` Its full path from the workspace… | string |
| `type` What it is | "file" | "dir" |
| `size` Size in bytes, for a file | number |
| `ignored` Tooling ignores it: installed packages, git… | boolean |
| `link` Present when this entry is a… | object |
| `to` What the link says, verbatim, rather… | string |
| `state` Absent for an ordinary link | "broken" | "outside" |
| `children` What is inside a folder | object[] |
| `name` Just this entry's own name | string |
| `path` Its full path from the workspace… | string |
| `type` What it is | "file" | "dir" |
| `size` Size in bytes, for a file | number |
| `ignored` Tooling ignores it: installed packages, git… | boolean |
| `link` Present when this entry is a… | object |
| `children` What is inside a folder | object[] |
| `hidden` How many entries at the top… | number |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/workspace/tree" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.tree();
```

**GET`/workspace/children` One 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

| Field | Type | Where |
| --- | --- | --- |
| `agent` Read a conversation's own private copy… | string | query |
| `path` required The folder to open, as a… | string | query |

### What comes back

| Field | Type |
| --- | --- |
| `entries` What is directly inside it | object[] |
| `name` Just this entry's own name | string |
| `path` Its full path from the workspace… | string |
| `type` What it is | "file" | "dir" |
| `size` Size in bytes, for a file | number |
| `ignored` Tooling ignores it: installed packages, git… | boolean |
| `link` Present when this entry is a… | object |
| `to` What the link says, verbatim, rather… | string |
| `state` Absent for an ordinary link | "broken" | "outside" |
| `children` What is inside a folder | object[] |
| `name` Just this entry's own name | string |
| `path` Its full path from the workspace… | string |
| `type` What it is | "file" | "dir" |
| `size` Size in bytes, for a file | number |
| `ignored` Tooling ignores it: installed packages, git… | boolean |
| `link` Present when this entry is a… | object |
| `to` What the link says, verbatim, rather… | string |
| `state` Absent for an ordinary link | "broken" | "outside" |
| `children` What is inside a folder | object[] |
| `name` Just this entry's own name | string |
| `path` Its full path from the workspace… | string |
| `type` What it is | "file" | "dir" |
| `size` Size in bytes, for a file | number |
| `ignored` Tooling ignores it: installed packages, git… | boolean |
| `link` Present when this entry is a… | object |
| `children` What is inside a folder | object[] |
| `hidden` How many entries were cut for… | number |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/workspace/children?path=src%2Fapp.ts" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.children({
 "path": "src/app.ts"
});
```

**GET`/workspace/file` Read 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

| Field | Type | Where |
| --- | --- | --- |
| `agent` Read a conversation's own private copy… | string | query |
| `path` required The file to read, as a… | string | query |
| `offset` Which byte to start at | integer | query |
| `limit` How many bytes to read | integer | query |

### What comes back

| Field | Type |
| --- | --- |
| `when present is true` | shape |
| `path` The path, as asked for | string |
| `content` The bytes of the window you… | string |
| `size` How large the whole file is | number |
| `offset` Which byte the window starts at | number |
| `bytes` How many bytes the window holds | number |
| `shared` Which tree answered | boolean |
| `when present is false` | shape |
| `path` The path, as asked for | string |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/workspace/file?path=src%2Fapp.ts" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.file({
 "path": "src/app.ts"
});
```

**POST`/workspace/media-ticket` Get 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

| Field | Type | Where |
| --- | --- | --- |
| `agent` Read a conversation's own private copy… | string | body |
| `path` required The media file the ticket should… | string | body |

### What comes back

| Field | Type |
| --- | --- |
| `ticket` Hand this to the streaming route… | string |
| `expiresAt` When it stops working, in milliseconds,… | number |

Try it answered in this tab

curl

```bash
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

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.mediaTicket({
 "agent": "…",
 "path": "src/app.ts"
});
```

**GET`/workspace/resolve` Turn 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

| Field | Type | Where |
| --- | --- | --- |
| `agent` Read a conversation's own private copy… | string | query |
| `path` required The reference as somebody wrote it | string | query |

### What comes back

| Field | Type |
| --- | --- |
| `path` The real path it means | string |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/workspace/resolve?path=src%2Fapp.ts" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.resolve({
 "path": "src/app.ts"
});
```

**GET`/workspace/search` Search the code**

Ranked results across the whole workspace, grouped, each carrying why it matched and how fresh it is. Left alone it blends plain text, structure, meaning and history in one pass; narrow it to a single kind of search when you already know which you want. Long result sets resume from the cursor it hands back.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `query` required What to look for | string | query |
| `mode` Narrow the search to one kind:… | "q" | "find" | "files" | "def" … (7) | query |
| `includeIgnored` Search inside installed packages and other… | string | query |
| `literal` Treat the query as fixed text… | string | query |
| `word` Match whole words only | string | query |
| `caseSensitive` Whether capitals matter | string | query |
| `include` Which files to ask, in the… | string | query |
| `limit` How many results to return | integer | query |
| `after` Resume from the cursor a previous… | string | query |

### What comes back

| Field | Type |
| --- | --- |
| `mode` Which kind of search actually ran,… | string |
| `total` Matching lines across the whole workspace,… | number |
| `files` Files the query matched in total | number |
| `shown` How many of those lines are… | number |
| `groups` The results, grouped by file, best… | object[] |
| `path` The file | string |
| `score` How well it matched | number |
| `hits` The matching lines in it | object[] |
| `line` Which line, counting from one | number |
| `text` The line itself | string |
| `spans` Where in the line the matches… | object[] |
| `start` First character of the match within… | number |
| `end` One past the last | number |
| `tags` Why it matched | object[] |
| `kind` Why this line matched: the literal… | "def" | "text" | "sem" | "bm25" … (12) |
| `score` How strongly that reason applied | number |
| `context` What it sits inside: the function,… | string |
| `capped` This file had more matches than… | boolean |
| `freshness` Whether the index behind the answer… | object |
| `state` Whether the index matches what is… | "fresh" | "building" | "stale" |
| `ageMs` How long since it last matched… | number |
| `progress` How far through building it is,… | number |
| `behind` How many files it has not… | number |
| `truncated` This page is not all of… | boolean |
| `partial` At least one file had more… | boolean |
| `cursor` Pass this back as `after` to… | string |
| `hint` A suggestion for getting a better… | string |
| `note` What the engine did that you… | string |
| `related` Places next door to the best… | string[] |
| `candidates` Ranked places that scored but did… | string[] |
| `features` Which stages of the search were… | string[] |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/workspace/search?query=%E2%80%A6" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.search({
 "query": "…"
});
```

**GET`/workspace/health` A 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

| Field | Type | Where |
| --- | --- | --- |
| `repo` required Which repository, using the same ids… | string | query |
| `since` How far back to count changes,… | string | query |
| `limit` How many files and modules to… | integer | query |

### What comes back

| Field | Type |
| --- | --- |
| `repo` Which repository this describes | string |
| `totals` Counts anybody could recount in the… | object |
| `files` Files counted | number |
| `symbols` Named things they export | number |
| `complexity` Branch points across all of them… | number |
| `hotspots` How many files qualify as hotspots… | number |
| `hotspots` Files that change often and are… | object[] |
| `path` | string |
| `commits` | number |
| `adds` | number |
| `dels` | number |
| `complexity` | number |
| `score` | number |
| `latestMs` | number |
| `modules` The parts of the codebase the… | object[] |
| `path` | string |
| `exports` | number |
| `freshness` Whether the index these numbers were… | object |
| `state` Whether the index matches what is… | "fresh" | "building" | "stale" |
| `ageMs` How long since it last matched… | number |
| `progress` How far through building it is,… | number |
| `behind` How many files it has not… | number |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/workspace/health?repo=root" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.health({
 "repo": "root"
});
```

**GET`/workspace/classify` Sort 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

| Field | Type |
| --- | --- |
| `classifications` One entry per repository folder and… | object[] |
| `path` What was looked at | string |
| `bucket` Which bucket it was sorted into | "repositories" | "documents" | "media" | "archives" … (5) |
| `reason` The signal that decided it, so… | string |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/workspace/classify" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.classify();
```

**POST`/workspace/dir` Create a folder**

Makes a folder, and any missing folders above it.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `path` required The folder to create | string | body |

### What comes back

| Field | Type |
| --- | --- |
| `ok` Always true | true |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/workspace/dir" \
 -H "x-intentic-control: $INTENTIC_TOKEN" \
 -H "content-type: application/json" \
 -d '{"path":"src/app.ts"}'
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.mkdir({
 "path": "src/app.ts"
});
```

**DELETE`/workspace/entry` Delete 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

| Field | Type | Where |
| --- | --- | --- |
| `path` required The file or folder, as a… | string | body |

### What comes back

| Field | Type |
| --- | --- |
| `ok` Always true | true |

Try it answered in this tab

curl

```bash
curl -X DELETE "$SANDBOX/workspace/entry" \
 -H "x-intentic-control: $INTENTIC_TOKEN" \
 -H "content-type: application/json" \
 -d '{"path":"src/app.ts"}'
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.delete({
 "path": "src/app.ts"
});
```

**POST`/workspace/move` Move or rename something**

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

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `from` required What to move or copy, as… | string | body |
| `to` required Where it should end up | string | body |

### What comes back

| Field | Type |
| --- | --- |
| `ok` Always true | true |

Try it answered in this tab

curl

```bash
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

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.move({
 "from": "src/app.ts",
 "to": "src/server.ts"
});
```

**POST`/workspace/copy` Copy a file or folder**

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

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `from` required What to move or copy, as… | string | body |
| `to` required Where it should end up | string | body |

### What comes back

| Field | Type |
| --- | --- |
| `ok` Always true | true |

Try it answered in this tab

curl

```bash
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

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.copy({
 "from": "src/app.ts",
 "to": "src/server.ts"
});
```

**GET`/workspace/setup` Which 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

| Field | Type |
| --- | --- |
| `projects` Every project the sandbox found, and… | object[] |
| `dir` Where the project is, relative to… | string |
| `ecosystem` Which language's tooling it uses | "node" | "python" |
| `manager` The tool that would do the… | string |
| `command` The exact command that would run | string |
| `evidence` The file that decided all of… | string |
| `state` Ready means its dependencies are really… | "ready" | "installing" | "needs-setup" | "unsupported" … (5) |
| `missing` How many declared dependencies cannot be… | number |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/workspace/setup" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.setup();
```

**POST`/workspace/setup/install` Install 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

| Field | Type | Where |
| --- | --- | --- |
| `dirs` required Which projects to install, by folder | string[] | body |

### What comes back

| Field | Type |
| --- | --- |
| `queued` Which of them actually started, which… | string[] |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/workspace/setup/install" \
 -H "x-intentic-control: $INTENTIC_TOKEN" \
 -H "content-type: application/json" \
 -d '{"dirs":["src","docs"]}'
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.install({
 "dirs": [
 "src",
 "docs"
 ]
});
```

**GET`/workspace/repos` Repos 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

| Field | Type |
| --- | --- |
| `repos` Every repository's id, sorted | string[] |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/workspace/repos" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.repos();
```

**POST`/workspace/repos` Clone a repo in**

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

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `name` required What to call it in the… | string | body |
| `cloneUrl` required Where to clone it from | string | body |
| `branch` Which branch to check out | string | body |

### What comes back

| Field | Type |
| --- | --- |
| `name` What it ended up called | string |
| `path` Where it landed | string |

Try it answered in this tab

curl

```bash
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

```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/sync` Pull 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

| Field | Type |
| --- | --- |
| `repos` One entry per repository, saying what… | object[] |
| `repo` Which repository | string |
| `status` What happened to it | "updated" | "current" | "dirty" | "diverged" … (7) |
| `behind` How many commits it was behind | number |
| `ahead` How many commits it was ahead | number |
| `head` The commit it ended up on | string |
| `message` What went wrong, when something did | string |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/workspace/sync" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.sync();
```

**GET`/workspace/templates` App 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

| Field | Type |
| --- | --- |
| `templates` The kinds of app the configured… | object[] |
| `key` The id to name when scaffolding… | string |
| `label` What to call it on screen | string |
| `description` What you get | string |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/workspace/templates" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.templates();
```

**POST`/workspace/repos/{repo}/apps` Scaffold 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

| Field | Type | Where |
| --- | --- | --- |
| `repo` required Which repository to scaffold into | string | address |
| `apps` required The apps to add | object[] | body |
| `template` required Which kind of app to scaffold,… | string | body |
| `name` required What to call this one | string | body |

### What comes back

| Field | Type |
| --- | --- |
| `ok` Always true | true |

Try it answered in this tab

curl

```bash
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

```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}/apps` Apps 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

| Field | Type | Where |
| --- | --- | --- |
| `repo` required Which repository | string | address |

### What comes back

| Field | Type |
| --- | --- |
| `apps` The apps in this repository | object[] |
| `app` The app's name, which is also… | string |
| `kind` What sort of app it is:… | string |
| `previewUrl` Where to open it | string |
| `running` Whether its dev server is up | boolean |
| `healthy` Whether it is actually answering | boolean |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/workspace/repos/root/apps" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.appsList({
 "repo": "root"
});
```

**GET`/workspace/repos/{repo}/graph` How 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

| Field | Type | Where |
| --- | --- | --- |
| `repo` required Which repository | string | address |

### What comes back

| Field | Type |
| --- | --- |
| `packages` Every package in the repository | object[] |
| `name` The name the package declares | string |
| `dir` Where it lives, relative to the… | string |
| `group` The top-level folder it sits under,… | string |
| `edges` Which of them use which | object[] |
| `from` The package that depends | string |
| `to` The package it depends on | string |
| `type` Which kind of dependency declared it | "prod" | "dev" | "peer" |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/workspace/repos/root/graph" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.packageGraph({
 "repo": "root"
});
```

**GET`/workspace/modules` Every 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

| Field | Type |
| --- | --- |
| `repos` Every repository with the packages inside… | object[] |
| `repo` Which repository | string |
| `modules` Its packages | object[] |
| `dir` Where the package lives, relative to… | string |
| `name` The name the package declares for… | string |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/workspace/modules" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.modules();
```

**POST`/workspace/repos/{repo}/apps/{app}/start` Start an app's dev server**

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

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `repo` required Which repository | string | address |
| `app` required Which app inside it | string | address |

### What comes back

| Field | Type |
| --- | --- |
| `ok` Always true | true |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/workspace/repos/root/apps/%E2%80%A6/start" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.startApp({
 "repo": "root",
 "app": "…"
});
```

**POST`/workspace/repos/{repo}/apps/{app}/stop` Stop an app's dev server**

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

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `repo` required Which repository | string | address |
| `app` required Which app inside it | string | address |

### What comes back

| Field | Type |
| --- | --- |
| `ok` Always true | true |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/workspace/repos/root/apps/%E2%80%A6/stop" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.workspace.stopApp({
 "repo": "root",
 "app": "…"
});
```

**POST`/workspace/repos/{repo}/tests` Run 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

| Field | Type | Where |
| --- | --- | --- |
| `repo` required Which repository | string | address |
| `session` required What to call the terminal this… | string | body |
| `dirs` required Which projects to test, as folders… | string[] | body |

### What comes back

| Field | Type |
| --- | --- |
| `ok` Always true | true |

Try it answered in this tab

curl

```bash
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

```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

[Next Git →](https://intentic.dev/api/git/)
