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

4.9 KiB

title, description, nav, order, category
title description nav order category
Workspaces with the SDK Open directories as Paseo workspaces, place agents in them, follow changes, and archive them. Workspaces 53 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

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:

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:

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

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:

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:

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

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 for command arguments, working-directory overrides, input, and capture options.

List workspaces

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

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.