---
title: "Extensions · intentic sandbox API"
description: "Installed extensions: their settings, their readiness, their updates and their processes. Every route in the extensions group of the intentic sandbox API."
url: "https://intentic.dev/api/extensions/"
---

Agent setup

# Extensions

Installed extensions: their settings, their readiness, their updates and their processes

**On this page (22 sections)**

- [Installed extensions](#extensions-list)
- [Write a new extension in place](#extensions-create)
- [What removing an extension would take away](#extensions-removalPlan)
- [Remove an extension](#extensions-remove)
- [An extension's settings](#extensions-settings)
- [Change an extension's settings](#extensions-setSettings)
- [Let a workspace extension run](#extensions-approve)
- [Turn an extension on or off](#extensions-setEnabled)
- [Record what extensions just used](#extensions-recordUsage)
- [Whether an extension is fit to share](#extensions-readiness)
- [Look for extension updates now](#extensions-checkUpdates)
- [What an update would change](#extensions-updatePreview)
- [Update an extension](#extensions-applyUpdate)
- [Go back to the previous version](#extensions-revert)
- [How an extension should handle its own updates](#extensions-setUpdatePolicy)
- [Whether an extension's background process is up](#extensions-processStatus)
- [Start an extension's background process](#extensions-processStart)
- [Stop an extension's background process](#extensions-processStop)
- [Installed extensions and their source checkouts](#extensions-devList)
- [Run an installed extension from its source checkout](#extensions-devSet)
- [Go back to the pinned version](#extensions-devClear)
- [Pick up a rebuilt checkout](#extensions-devReload)

The runtime half of the extension format documented under Developers. These routes enumerate what is installed, read and write each one's settings, switch it on or off, check for updates and apply or undo one, and start or stop the long-running processes an extension declares.

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

**GET`/extensions` Installed extensions**

Every extension installed here, resolved to the manifest the owner approved, which is what the app boots its extension host from. The code itself is served separately, because raw script bytes are not a JSON answer.

### What you send

Nothing. Call it as it is.

### What comes back

| Field | Type |
| --- | --- |
| `extensions` What is installed | object[] |
| `id` The extension's id | string |
| `manifest` What it declares about itself: what… | object |
| `$schema` The authoring schema, for editor completion… | string |
| `publisher` | string |
| `name` | string |
| `version` Your own semver, display and identity… | string |
| `category` Which section of the Extensions tab… | string |
| `art` This extension's own mark, as a… | string |
| `logo` A simple-icons slug, fetched from a… | string |
| `icon` A name from the host's own… | string |
| `engines` A semver range over the host's… | object |
| `intentic` | string |
| `entry` Repo-relative path of your prebuilt single-file… | string |
| `server` Repo-relative path of your prebuilt single-file… | string |
| `permissions` How far this extension may reach… | object |
| `sandbox` Daemon routes your UI half may… | string[] |
| `daemon` Daemon routes your SERVER half may… | string[] |
| `contributes` | object |
| `views` Sidebar elements this extension may register… | object[] |
| `files` Which workspace files back your views,… | object[] |
| `viewers` File formats this extension can render | object[] |
| `documents` Per-directory documents this extension can offer | object[] |
| `sideViews` Things this extension can show in… | object[] |
| `commands` Commands this extension may register handlers… | object[] |
| `settings` Typed settings the host renders into… | object[] |
| `processes` Long-lived background processes the daemon runs… | object[] |
| `agent` Declare that this checkout is also… | object |
| `environment` A Dockerfile fragment baked into the… | object |
| `capabilities` Capability cards this pack adds to… | object[] |
| `listener` A realtime event source this extension… | object |
| `automationTemplates` Starting points this pack offers in… | object[] |
| `bin` A checkout-relative directory of executables the… | string |
| `tools` Tools for the agent, as an… | object |
| `commit` Exactly which commit is installed | string |
| `source` Where the code comes from: baked… | "builtin" | "installed" | "workspace" |
| `enabled` The owner's switch | boolean |
| `essential` Its switch is fixed on, because… | boolean |
| `usage` How much of the reach it… | object |
| `backend` Present only for an extension that… | object |
| `state` How its server half is doing | "running" | "error" | "absent" | "incompatible" … (6) |
| `detail` What went wrong, so a backend… | string |
| `problems` Declarations in its manifest the sandbox… | string[] |
| `update` A newer version waiting | object |
| `ref` The commit being offered | string |
| `version` What it calls itself | string |
| `url` Where it comes from | string |
| `path` Where inside that repository it lives | string |
| `trust` Whether anybody vouched for it, or… | "verified" | "listed" |
| `securityFix` This release fixes a security problem… | boolean |
| `registry` Which registry said so | string |
| `at` When it was published | string |
| `needsReview` Why this one was not taken… | string |
| `review` An agent has already read the… | object |
| `conversationId` Where to read what it found | string |
| `at` When it looked | string |
| `advisory` A security warning about the installed… | object |
| `reason` Why the registry pulled the listing,… | string |
| `registry` Which registry said so | string |
| `at` When | string |
| `autoDisabled` Whether the sandbox has already switched… | boolean |
| `health` How it has behaved since the… | object |
| `state` How it has behaved since the… | "watching" | "healthy" | "unhealthy" |
| `detail` What is going wrong, when something… | string |
| `fromRef` Which version it was updated from,… | string |
| `at` When the watching started | string |
| `autoReverted` The update was already rolled back… | boolean |
| `previous` The version kept one step back,… | object |
| `ref` The commit that was running before | string |
| `version` What it called itself | string |
| `updatePolicy` The owner's standing answer for this… | object |
| `updates` | "notify" | "agent" | "auto" |
| `advisories` | "auto-disable" | "notify" |
| `dev` Set while an extension installed from… | object |
| `path` The source checkout it was pointed… | string |
| `conversation` The conversation whose isolated copy of… | string |
| `uncommitted` How many files in the checkout… | integer |
| `revision` A short fingerprint of the browser… | string |
| `held` Why the checkout is not what… | string |
| `invalid` Extensions written here that could not… | object[] |
| `dir` Which folder | string |
| `error` Why it could not be read | string |
| `pending` Extensions written in this workspace that… | object[] |
| `id` The extension's id | string |
| `dir` Which folder under .intentic/config/workspace-extensions/ | string |
| `manifest` What it declares about itself | object |
| `$schema` The authoring schema, for editor completion… | string |
| `publisher` | string |
| `name` | string |
| `version` Your own semver, display and identity… | string |
| `category` Which section of the Extensions tab… | string |
| `art` This extension's own mark, as a… | string |
| `logo` A simple-icons slug, fetched from a… | string |
| `icon` A name from the host's own… | string |
| `engines` A semver range over the host's… | object |
| `intentic` | string |
| `entry` Repo-relative path of your prebuilt single-file… | string |
| `server` Repo-relative path of your prebuilt single-file… | string |
| `permissions` How far this extension may reach… | object |
| `sandbox` Daemon routes your UI half may… | string[] |
| `daemon` Daemon routes your SERVER half may… | string[] |
| `contributes` | object |
| `views` Sidebar elements this extension may register… | object[] |
| `files` Which workspace files back your views,… | object[] |
| `viewers` File formats this extension can render | object[] |
| `documents` Per-directory documents this extension can offer | object[] |
| `sideViews` Things this extension can show in… | object[] |
| `commands` Commands this extension may register handlers… | object[] |
| `settings` Typed settings the host renders into… | object[] |
| `processes` Long-lived background processes the daemon runs… | object[] |
| `agent` Declare that this checkout is also… | object |
| `environment` A Dockerfile fragment baked into the… | object |
| `capabilities` Capability cards this pack adds to… | object[] |
| `listener` A realtime event source this extension… | object |
| `automationTemplates` Starting points this pack offers in… | object[] |
| `bin` A checkout-relative directory of executables the… | string |
| `tools` Tools for the agent, as an… | object |
| `powers` What saying yes allows, as plain… | object |
| `added` What the new version asks for… | string[] |
| `removed` What it no longer asks for | string[] |
| `unchanged` What stays the same | string[] |
| `approvedBefore` An earlier shape of it was… | boolean |
| `digest` The fingerprint of the powers shown,… | string |
| `updatesCheckedAt` When updates were last looked for | string |

Try it answered in this tab

curl

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

TypeScript

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

const result = await sandbox.extensions.list();
```

**POST`/extensions/workspace` Write a new extension in place**

Scaffolds a working extension into this workspace and installs it. The only call here that creates one, and it exists because that folder is otherwise reachable only through an agent's file tools, which is a fine way to change an extension and a poor way to meet the idea of one.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `publisher` required Who it is by, which together… | string | body |
| `name` required What it is called | string | body |

### What comes back

| Field | Type |
| --- | --- |
| `id` The id it was given | string |
| `dir` Where its files are, so you… | string |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/extensions/workspace" \
 -H "x-intentic-control: $INTENTIC_TOKEN" \
 -H "content-type: application/json" \
 -d '{"publisher":"…","name":"nightly changelog"}'
```

TypeScript

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

const result = await sandbox.extensions.create({
 "publisher": "…",
 "name": "nightly changelog"
});
```

**GET`/extensions/{id}/removal` What removing an extension would take away**

Everything one removal destroys, before it happens: the files deleted, the connections configured from its cards, the settings and credentials forgotten, the background processes stopped, and the owner's own automations that quietly stop firing. Also answerable for an extension that cannot be removed, in which case it says why.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required Which connection | string | address |

### What comes back

| Field | Type |
| --- | --- |
| `id` The extension's id, as the list… | string |
| `name` Its publisher.name identity, which is the… | string |
| `version` The version being removed | string |
| `source` Where its code comes from, which… | "builtin" | "installed" | "workspace" |
| `blocked` Why this one cannot be removed,… | string |
| `files` Directories deleted outright | object[] |
| `path` Workspace-relative | string |
| `detail` What is in there | string |
| `connections` Connections configured from its cards, which… | object[] |
| `id` The name the owner gave it,… | string |
| `kind` Which core kind it is underneath:… | string |
| `entry` The catalog entry it was added… | string |
| `secrets` Credential fields stored for it, by… | string[] |
| `effect` What tearing it down actually takes… | string |
| `settings` Values the owner entered for this… | object[] |
| `key` Which setting | string |
| `secret` Whether its value is a stored… | boolean |
| `processes` Background processes it declared, stopped before… | string[] |
| `automations` Automations of the owner's own that… | string[] |
| `rebuildNeeded` It bakes a layer into the… | boolean |
| `keeps` What removal deliberately leaves alone, so… | string[] |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/extensions/a1b2c3d4/removal" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

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

const result = await sandbox.extensions.removalPlan({
 "id": "a1b2c3d4"
});
```

**POST`/extensions/{id}/remove` Remove an extension**

Uninstalls it and everything that only existed because it was here: the connections added from its cards, with their stored credentials, its settings, its switch and its update record. What the owner made with it — automations, files in the workspace — is left alone. Owner only, for the same reason installing is. Built-in extensions cannot be removed; switch them off instead.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required Which connection | string | address |

### What comes back

| Field | Type |
| --- | --- |
| `ok` It is gone | true |
| `connections` Which configured connections went with it,… | string[] |
| `rebuildNeeded` Its image layer is still in… | boolean |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/extensions/a1b2c3d4/remove" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

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

const result = await sandbox.extensions.remove({
 "id": "a1b2c3d4"
});
```

**GET`/extensions/{id}/settings` An extension's settings**

The current values for the settings this extension declared it has.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required Which connection | string | address |

### What comes back

| Field | Type |
| --- | --- |
| `settings` The values, minus anything marked secret | object |
| `secretsSet` Which of its secret settings actually… | string[] |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/extensions/a1b2c3d4/settings" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

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

const result = await sandbox.extensions.settings({
 "id": "a1b2c3d4"
});
```

**POST`/extensions/{id}/settings` Change an extension's settings**

Writes new values. A key the extension never declared is refused rather than quietly stored, the same honesty rule that governs everything else an extension claims.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required Which extension | string | address |
| `settings` required The values to write | object | body |

### What comes back

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

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/extensions/a1b2c3d4/settings" \
 -H "x-intentic-control: $INTENTIC_TOKEN" \
 -H "content-type: application/json" \
 -d '{"settings":{"src/app.ts":"…","README.md":"…"}}'
```

TypeScript

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

const result = await sandbox.extensions.setSettings({
 "id": "a1b2c3d4",
 "settings": {
 "src/app.ts": "…",
 "README.md": "…"
 }
});
```

**POST`/extensions/{id}/approve` Let a workspace extension run**

Approves an extension written in this workspace with the powers it declares now: its background processes start, its backend loads, and what it contributes is wired from the next turn. Editing its code keeps the approval; declaring a power it did not have puts it back in the pending list. Owner and maintainers only.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required Which extension | string | address |
| `digest` required The fingerprint of the powers you… | string | body |

### What comes back

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

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/extensions/a1b2c3d4/approve" \
 -H "x-intentic-control: $INTENTIC_TOKEN" \
 -H "content-type: application/json" \
 -d '{"digest":"…"}'
```

TypeScript

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

const result = await sandbox.extensions.approve({
 "id": "a1b2c3d4",
 "digest": "…"
});
```

**POST`/extensions/{id}/enabled` Turn an extension on or off**

The owner's switch. Turning one off stops its background processes at once. What it contributes to an agent's tools is rebuilt at the start of the next turn, and anything it adds to the sandbox image only at the next rebuild.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required Which extension | string | address |
| `enabled` required On or off | boolean | body |

### What comes back

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

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/extensions/a1b2c3d4/enabled" \
 -H "x-intentic-control: $INTENTIC_TOKEN" \
 -H "content-type: application/json" \
 -d '{"enabled":true}'
```

TypeScript

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

const result = await sandbox.extensions.setEnabled({
 "id": "a1b2c3d4",
 "enabled": true
});
```

**POST`/extensions/usage` Record what extensions just used**

One batch written by the app rather than measured by the daemon, because the permission gate runs in the browser: from the sandbox's side extension traffic is indistinguishable from anyone else's. This is how the record of which powers each extension actually exercises gets kept without one reporting request per extension.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `reports` required Each extension that called something, and… | object | body |

### What comes back

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

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/extensions/usage" \
 -H "x-intentic-control: $INTENTIC_TOKEN" \
 -H "content-type: application/json" \
 -d '{"reports":{"src/app.ts":{"src/app.ts":1,"README.md":1},"README.md":{"src/app.ts":1,"README.md":1}}}'
```

TypeScript

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

const result = await sandbox.extensions.recordUsage({
 "reports": {
 "src/app.ts": {
 "src/app.ts": 1,
 "README.md": 1
 },
 "README.md": {
 "src/app.ts": 1,
 "README.md": 1
 }
 }
});
```

**GET`/extensions/{id}/readiness` Whether an extension is fit to share**

The checks that can be answered from an extension's own files, for an author about to publish. Read on demand rather than carried on the list, because it reads the code off disk each time.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required Which connection | string | address |

### What comes back

| Field | Type |
| --- | --- |
| `checks` Everything that can be checked from… | object[] |
| `id` Which check | string |
| `label` What it is called | string |
| `status` How it went | "pass" | "warn" | "fail" |
| `detail` What it found | string |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/extensions/a1b2c3d4/readiness" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

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

const result = await sandbox.extensions.readiness({
 "id": "a1b2c3d4"
});
```

**POST`/extensions/updates/check` Look for extension updates now**

Compares every installed extension against its source and reports what is newer, what carries an advisory and what looks unhealthy. This also happens on a schedule; call it to check on demand.

### What you send

Nothing. Call it as it is.

### What comes back

| Field | Type |
| --- | --- |
| `ok` The check ran | true |
| `checkedAt` When, so a screen can date… | string |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/extensions/updates/check" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

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

const result = await sandbox.extensions.checkUpdates();
```

**POST`/extensions/{id}/update/preview` What an update would change**

The read before the click: which versions are involved and exactly which powers the new code asks for that the running one does not. Costs one throwaway copy of the source, the same as browsing a registry entry.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required Which extension | string | address |
| `ref` Which commit, in full | string | body |

### What comes back

| Field | Type |
| --- | --- |
| `ref` The commit this would install | string |
| `version` What that version calls itself | string |
| `installedVersion` What is running now | string |
| `engines` Which sandbox versions the new one… | string |
| `compatible` Whether this sandbox is one of… | boolean |
| `powers` Exactly what the new code asks… | object |
| `added` What the new version asks for… | string[] |
| `removed` What it no longer asks for | string[] |
| `unchanged` What stays the same | string[] |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/extensions/a1b2c3d4/update/preview" \
 -H "x-intentic-control: $INTENTIC_TOKEN" \
 -H "content-type: application/json" \
 -d '{"ref":"refs/heads/main"}'
```

TypeScript

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

const result = await sandbox.extensions.updatePreview({
 "id": "a1b2c3d4",
 "ref": "refs/heads/main"
});
```

**POST`/extensions/{id}/update` Update an extension**

The whole swap as one transaction: fetch, check, quiet the running one, replace it while keeping the outgoing copy one step back, restart and watch it come up. The existing configuration is kept, so a token for a private source survives what removing and re-adding would lose. Owner only, because it changes what code runs.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required Which extension | string | address |
| `ref` Which commit, in full | string | body |

### What comes back

| Field | Type |
| --- | --- |
| `ok` It went through | true |
| `ref` Which commit is now running | string |
| `rebuildNeeded` The new version changes what the… | boolean |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/extensions/a1b2c3d4/update" \
 -H "x-intentic-control: $INTENTIC_TOKEN" \
 -H "content-type: application/json" \
 -d '{"ref":"refs/heads/main"}'
```

TypeScript

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

const result = await sandbox.extensions.applyUpdate({
 "id": "a1b2c3d4",
 "ref": "refs/heads/main"
});
```

**POST`/extensions/{id}/revert` Go back to the previous version**

Swaps the copy kept from before the last update back into place. Owner only, for the same reason updating is.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required Which connection | string | address |

### What comes back

| Field | Type |
| --- | --- |
| `ok` It went through | true |
| `ref` Which commit is now running | string |
| `rebuildNeeded` The new version changes what the… | boolean |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/extensions/a1b2c3d4/revert" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

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

const result = await sandbox.extensions.revert({
 "id": "a1b2c3d4"
});
```

**POST`/extensions/{id}/update-policy` How an extension should handle its own updates**

The owner's standing answer for one extension: tell me, have an agent look at it, or just do it. Security advisories can be opted out of separately.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required Which extension | string | address |
| `updates` What to do about a newer… | "notify" | "agent" | "auto" | body |
| `advisories` What to do about a security… | "auto-disable" | "notify" | body |

### What comes back

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

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/extensions/a1b2c3d4/update-policy" \
 -H "x-intentic-control: $INTENTIC_TOKEN" \
 -H "content-type: application/json" \
 -d '{"updates":"notify","advisories":"auto-disable"}'
```

TypeScript

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

const result = await sandbox.extensions.setUpdatePolicy({
 "id": "a1b2c3d4",
 "updates": "notify",
 "advisories": "auto-disable"
});
```

**GET`/extensions/{id}/processes/{name}` Whether an extension's background process is up**

The state of one process an extension declared, with the port it was given and its preview address if it has one.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required Which extension | string | address |
| `name` required Which of its declared processes | string | address |

### What comes back

| Field | Type |
| --- | --- |
| `name` Which process | string |
| `running` Whether it is up | boolean |
| `port` The port it was given | number |
| `restarts` How many times it died and… | number |
| `lastExitCode` How it last exited, when it… | number |
| `previewUrl` Where to open it, when it… | string |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/extensions/a1b2c3d4/processes/nightly%20changelog" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

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

const result = await sandbox.extensions.processStatus({
 "id": "a1b2c3d4",
 "name": "nightly changelog"
});
```

**POST`/extensions/{id}/processes/{name}/start` Start an extension's background process**

Brings one of an extension's declared processes up in an attachable terminal.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required Which extension | string | address |
| `name` required Which of its declared processes | string | address |

### What comes back

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

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/extensions/a1b2c3d4/processes/nightly%20changelog/start" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

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

const result = await sandbox.extensions.processStart({
 "id": "a1b2c3d4",
 "name": "nightly changelog"
});
```

**POST`/extensions/{id}/processes/{name}/stop` Stop an extension's background process**

Shuts one of an extension's declared processes down and frees its port.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required Which extension | string | address |
| `name` required Which of its declared processes | string | address |

### What comes back

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

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/extensions/a1b2c3d4/processes/nightly%20changelog/stop" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

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

const result = await sandbox.extensions.processStop({
 "id": "a1b2c3d4",
 "name": "nightly changelog"
});
```

**GET`/extensions/dev` Installed extensions and their source checkouts**

Every extension installed from a repository, with its pinned commit, whether it runs from a source checkout, and the checkout of its repository this workspace holds, if any. The calling conversation's own copy is named first.

### What you send

Nothing. Call it as it is.

### What comes back

| Field | Type |
| --- | --- |
| `extensions` Every extension installed from a repository | object[] |
| `id` Its connection id | string |
| `name` Its manifest id, publisher.name | string |
| `commit` The pinned commit, in full | string |
| `dev` Present while it is pointed at… | object |
| `path` The source checkout it was pointed… | string |
| `conversation` The conversation whose isolated copy of… | string |
| `uncommitted` How many files in the checkout… | integer |
| `revision` A short fingerprint of the browser… | string |
| `held` Why the checkout is not what… | string |
| `checkout` A checkout of its source repository… | object |
| `path` Relative to the workspace, or to… | string |
| `conversation` Set when the calling conversation's own… | string |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/extensions/dev" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

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

const result = await sandbox.extensions.devList();
```

**POST`/extensions/{id}/dev` Run an installed extension from its source checkout**

Serves the extension's browser bundle, backend, processes, skills and contributions from a checkout of its source instead of its pinned copy, so a change to it shows on reload without being landed first. The checkout must hold the same extension and declare the same powers; one asking for more, or not built yet, is held and the pinned version keeps running, with the reason. Nothing is installed or updated: the pinned copy stays where it is.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required Which installed extension: its connection id… | string | address |
| `path` The checkout to run it from | string | body |

### What comes back

| Field | Type |
| --- | --- |
| `id` Its connection id | string |
| `name` Its manifest id, publisher.name | string |
| `dev` Where it runs from now, or… | object |
| `path` The source checkout it was pointed… | string |
| `conversation` The conversation whose isolated copy of… | string |
| `uncommitted` How many files in the checkout… | integer |
| `revision` A short fingerprint of the browser… | string |
| `held` Why the checkout is not what… | string |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/extensions/a1b2c3d4/dev" \
 -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.extensions.devSet({
 "id": "a1b2c3d4",
 "path": "src/app.ts"
});
```

**POST`/extensions/{id}/dev/clear` Go back to the pinned version**

Stops serving the extension from its source checkout. The checkout itself is left exactly as it is.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required Which installed extension: its connection id… | string | address |

### What comes back

| Field | Type |
| --- | --- |
| `id` Its connection id | string |
| `name` Its manifest id, publisher.name | string |
| `cleared` Whether it was pointed at a… | boolean |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/extensions/a1b2c3d4/dev/clear" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

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

const result = await sandbox.extensions.devClear({
 "id": "a1b2c3d4"
});
```

**POST`/extensions/{id}/dev/reload` Pick up a rebuilt checkout**

Call after rebuilding an extension that runs from its source checkout: its backend restarts on the new code, and an open app is told the list changed, so it offers to reload the new browser bundle.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `id` required Which installed extension: its connection id… | string | address |

### What comes back

| Field | Type |
| --- | --- |
| `id` Its connection id | string |
| `name` Its manifest id, publisher.name | string |
| `dev` Where it runs from now, or… | object |
| `path` The source checkout it was pointed… | string |
| `conversation` The conversation whose isolated copy of… | string |
| `uncommitted` How many files in the checkout… | integer |
| `revision` A short fingerprint of the browser… | string |
| `held` Why the checkout is not what… | string |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/extensions/a1b2c3d4/dev/reload" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

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

const result = await sandbox.extensions.devReload({
 "id": "a1b2c3d4"
});
```

More in Agent setup

[Previous ← Skills](https://intentic.dev/api/skills/)[Next Settings →](https://intentic.dev/api/settings/)
