Files
paseo/public-docs/sdk/workspaces.md
T
Mohamed Boudra a880c9619d feat: background agents for hidden helpers (#8683)
* feat(server): add background agents

An agent can be created background in any workspace. It stays a durable,
addressable agent, but default discovery, workspace status and attention
leave it out. Effective background is agent.background ||
workspace.background.

- Protocol: `create_agent_request.background` now marks the agent itself
  and stays the workspace intent for a workspace the request creates.
  Snapshots carry `background`. The daemon advertises
  `features.backgroundAgents`. Clients advertise the `background_agents`
  capability.
- Daemon: the flag persists in the agent record, so restart and resume
  keep it. AgentDirectory owns visibility. Inclusive reads and
  subscriptions from sources without `background_agents` see only agents
  in background workspaces, because older apps would otherwise open a tab
  for each one.
- Inheritance: omitted on agent-scoped creation, children and new
  workspaces take the caller agent's background.
- MCP: create_agent accepts `background`.
- SDK: placing a background agent in an existing workspace, or under a
  caller, fails fast with "Update the host to use background agents." on
  older hosts.
- CLI: `ls -a` and `ls --background` add a BACKGROUND column.

* feat(app): hide background agents from tabs, track and status

* docs(plugins): point hidden helpers at background agents

* fix: keep background agents hidden across cache reload and connected hosts

* fix: keep remote creation working on older hosts and inherit foreign parents' background
2026-11-04 07:19:21 +07:00

153 lines
4.9 KiB
Markdown

---
title: Workspaces with the SDK
description: Open directories as Paseo workspaces, place agents in them, follow changes, and archive them.
nav: Workspaces
order: 53
category: TypeScript SDK
---
# Workspaces with the SDK
Use a workspace when an integration needs a durable place in the Paseo app for agents, terminals, browsers, and files related to one task.
## Open a directory
```ts
const workspace = await client.workspaces.open("/Users/me/dev/storefront");
console.log(workspace.id);
console.log(workspace.directory);
```
`open()` creates the project when needed and reuses the active workspace for that exact directory. Use it when the directory is the identity you care about.
## Create a fresh workspace
`create()` always creates a new workspace, even when another workspace already uses the directory:
```ts
const workspace = await client.workspaces.create({
source: {
kind: "directory",
path: "/Users/me/dev/storefront",
},
title: "Checkout issue 42",
});
```
Create a Paseo-owned worktree when concurrent work needs an isolated checkout:
```ts
const workspace = await client.workspaces.create({
source: {
kind: "worktree",
cwd: "/Users/me/dev/storefront",
action: "branch-off",
refName: "main",
branchName: "fix/checkout-42",
},
title: "Checkout issue 42",
});
```
Pass `agent` to create the workspace and its first agent in one call. See the
[combined background workspace example](./agents.md#run-work-in-a-background-workspace).
Set visibility on the workspace options; `agent.background` is rejected.
You can pass `projectId` in either source when you already have one. Most integrations should omit it; the daemon finds or creates the project from the directory.
Pass `background: true` to hide a workspace from default discovery. Its agents and terminals
remain durable, with ordinary history, lifecycle hooks, archive, and exact-ID access. The app's
sidebar offers **Show background** without dropping replicated state.
`background` is creation-only. Omission defaults to false; when `callerAgentId` identifies an agent
creating a new workspace, omission inherits the caller's visibility: true when the caller agent or
its workspace is background. Explicit false or true overrides inheritance. Agent creation that
creates its workspace applies `background` to both the workspace and the agent. To hide one agent
in an existing workspace, see [background agents](./agents.md#run-a-helper-as-a-background-agent).
Creation and inclusive discovery require `features.backgroundWorkspaces`; the client rejects an
unsupported host with an update-host message.
## Start an agent in a workspace
Create through the workspace handle:
```ts
const agent = await workspace.agents.create({
config: {
provider: "claude/claude-sonnet-5",
},
prompt: "Map the checkout flow before changing anything.",
});
```
The handle supplies both the workspace identity and its actual directory. This avoids mismatched placement arguments.
For a one-off agent, you can skip the workspace call:
```ts
const agent = await client.agents.create({
config: {
provider: "claude/claude-sonnet-5",
},
cwd: "/Users/me/dev/storefront",
prompt: "Map the checkout flow before changing anything.",
});
```
The daemon still creates a project and a fresh workspace. Read `agent.workspaceId` when you need the generated workspace ID.
## Start a terminal in a workspace
```ts
const terminal = await workspace.terminals.create({ name: "Development" });
terminal.write("echo ready");
terminal.sendKeys(["Enter"]);
const { lines } = await terminal.capture();
const { entries } = await workspace.terminals.list();
await terminal.kill();
```
Two workspaces may share a directory. The workspace handle supplies the ID that keeps their terminals separate. To use an ID you already have, call `client.workspaces.ref(workspaceId).terminals.create()`.
See the [terminal API reference](/docs/sdk/reference#clientterminals) for command arguments, working-directory overrides, input, and capture options.
## List workspaces
```ts
let cursor: string | undefined;
do {
const page = await client.workspaces.list({
filter: { query: "storefront" },
page: { limit: 50, cursor },
});
for (const workspace of page.entries) {
console.log(workspace.id, workspace.name, workspace.status);
}
cursor = page.pageInfo.nextCursor ?? undefined;
} while (cursor);
```
Background workspaces are left out unless `filter.includeBackground` is true. Use
`client.workspaces.list({ filter: { includeBackground: true } })` or
`client.agents.list({ filter: { includeBackground: true } })`. Workspace and agent snapshots carry
`background`. An agent is hidden when it or its workspace is background.
## Refresh and archive a handle
```ts
const workspace = client.workspaces.ref(savedWorkspaceId);
const snapshot = await workspace.refresh();
if (snapshot) {
await workspace.archive();
}
```
Workspace archive is separate from agent archive. Archive each resource according to the lifecycle your integration owns.