# How the taskSpaces Facade Manages Agent Collaboration Environments in ego-lite

> Learn how the taskSpaces facade in ego-lite manages AI agent collaboration. Discover how it handles creating, claiming, and switching browsing contexts with ownership rules and session state.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: internals
- Published: 2026-07-31

---

**The taskSpaces facade provides high-level helpers in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) that let AI agents create, claim, switch, and finish isolated browsing contexts while enforcing ownership rules and managing session state.**

The **taskSpaces** facade in the `citrolabs/ego-lite` repository abstracts the native browser bridge into a manageable API for agent collaboration. Exposed via the SDK's `installEgoSdk` routine in [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts), this facade enables scripts to isolate browsing sessions into distinct task spaces with controlled ownership transitions. Understanding how these helpers manage environment lifecycle and access control is essential for building reliable agent workflows.

## Core Concepts of the taskSpaces Facade

The facade implements a strict ownership model and normalized operations across primary functions defined in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts).

### Task-Space Ownership Model

Every task space carries an `ownership` field determining who can mutate it. According to lines 18-24 of [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts), the `isAgentOwned` helper validates three states:

- **`"agent"`** – Fully controlled by the agent, allowing direct mutation and switching.
- **`"agentDelegatedToUser"`** – Agent-owned but temporarily under user control.
- **`"user"`** – Owned by the user; agents must claim these before modification.

Only agent-owned spaces may be switched or mutated directly. User-owned spaces require explicit claiming via `claimTaskSpace` to transfer ownership.

### Listing and Discovering Spaces

The `listTaskSpaces()` function (lines 7-15 of [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)) returns an array of all existing spaces with normalized metadata including `taskId`, `id`, `name`, and `ownership`. This discovery mechanism allows agents to inspect the environment before attempting operations that might violate ownership constraints.

### Creating and Claiming Spaces

**Creating new spaces** happens through `newTaskSpace(name)` (lines 66-84 of [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)), which invokes the native `ego.createTaskSpace` API, normalizes the result, and immediately selects the newly created agent-owned space.

**Claiming existing spaces** requires `claimTaskSpace(nameOrId)` (lines 224-242 of [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)). This function calls `ego.claimTaskSpace` to transfer ownership from user to agent, then selects the space for immediate use. This two-step process ensures agents cannot accidentally modify user-controlled environments.

### Switching and Selection Logic

The `switchTaskSpace(nameOrId)` function (lines 52-63 of [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)) selects an already agent-owned space by calling the internal `selectTaskSpace` routine (lines 245-253). This routine executes `ego.useTaskSpace` to bind the chosen space to the current Node process. If the target space is user-owned, the function throws an error, enforcing the ownership boundary.

For convenience, `useOrCreateTaskSpace(nameOrId)` (lines 88-106 of [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)) implements a use-or-create pattern: it locates existing spaces and selects them, or creates new agent-owned spaces if none exist. If it encounters a user-owned space, it only selects it without claiming, requiring explicit `claimTaskSpace` calls for mutation rights.

### Completing and Handing Off Control

The `completeTaskSpace(nameOrId, { keep })` function (lines 274-314 of [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)) finalizes spaces based on the `keep` parameter:

- **`keep: true`** – Maintains user-owned spaces without claiming or closing.
- **`keep: false`** – Claims user-owned spaces then closes them, or simply closes agent-owned spaces.

For control transitions, `handOffTaskSpace` skips user-owned spaces entirely (returning `{ done: false, skipped: "user-owned" }`), while `takeOverTaskSpace` selects spaces without ownership validation, enabling users to regain control (lines 326-353 of [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)).

## Implementation Details in src/helpers.ts

Beyond the public API, the facade manages internal state consistency and session lifecycle.

### Normalization and Selection Routines

All native API results pass through `normalizeTaskSpace(s)` to ensure consistent object shapes before returning to caller code. The `selectTaskSpace` function (lines 245-253 of [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)) handles the actual binding by invoking `ego.useTaskSpace`, ensuring the Node process targets the correct browsing context.

### Session Invalidation and State Management

Mutating operations—including `useTaskSpace`, `closeTaskSpace`, `createTaskSpace`, and `claimTaskSpace`—are wrapped by `wrapInvalidating` (lines 81-99 of [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts)). This wrapper automatically invalidates the current Chrome DevTools Protocol (CDP) session and clears cached targets whenever task spaces change. According to the implementation in [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts), this ensures subsequent operations work with updated browser states rather than stale sessions.

The global state singleton managed in [`src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/state.ts) holds the runtime context (current session, preferred targets) that these helpers reference during execution.

## Using the taskSpaces Facade in Practice

The following examples demonstrate common patterns for managing collaboration environments:

```javascript
// List all task spaces (agent and user owned)
const spaces = await listTaskSpaces();
console.log('Available spaces:', spaces);

// Create a new agent-owned space and switch to it
const mySpace = await newTaskSpace('analysis-run');
console.log('Created & selected:', mySpace.id);

// Switch to an existing agent-owned space
await switchTaskSpace('existing-space-id');

// Use-or-create (creates if missing, selects otherwise)
const space = await useOrCreateTaskSpace('shared-workspace');
console.log('Using space:', space.id);

// Claim a user-owned space before mutating it
await claimTaskSpace('user-owned-space');
await switchTaskSpace('user-owned-space'); // now safe

// Hand off control to the user (no claim)
await handOffTaskSpace('user-owned-space');

// Take over a user-owned space (no ownership check)
await takeOverTaskSpace('user-owned-space');

// Complete a space, keeping it alive
await completeTaskSpace('analysis-run', { keep: true });

// Complete and close a user-owned space
await completeTaskSpace('user-owned-space', { keep: false });

```

## Summary

- The **taskSpaces facade** in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) provides core functions (`listTaskSpaces`, `newTaskSpace`, `claimTaskSpace`, `switchTaskSpace`, `useOrCreateTaskSpace`, `completeTaskSpace`, `handOffTaskSpace`, `takeOverTaskSpace`) for managing isolated browsing contexts.
- **Ownership enforcement** via `isAgentOwned` ensures only agent-owned spaces (`"agent"` or `"agentDelegatedToUser"`) can be mutated directly; user-owned spaces require claiming.
- **Session consistency** is maintained through `wrapInvalidating` in [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts), which clears CDP sessions whenever task spaces mutate.
- The facade is **exposed globally** through `installEgoSdk` in [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts), which injects helpers listed in the `LEGACY_GLOBAL_HELPERS` array (lines 21-33).
- **State management** relies on the singleton runtime state defined in [`src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/state.ts) to track current sessions and targets across operations.

## Frequently Asked Questions

### What is the difference between switchTaskSpace and claimTaskSpace?

**`switchTaskSpace`** selects an already agent-owned space and throws an error if the target is user-owned, while **`claimTaskSpace`** invokes the native `ego.claimTaskSpace` API to transfer ownership from user to agent before selecting the space. Use `switchTaskSpace` for spaces you already control, and `claimTaskSpace` when taking over user-created environments.

### How does the taskSpaces facade handle user-owned spaces?

The facade strictly isolates user-owned spaces through the `isAgentOwned` helper in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) (lines 18-24). Functions like `switchTaskSpace` refuse to select user-owned spaces, and `handOffTaskSpace` explicitly skips them. Agents must call `claimTaskSpace` to convert a user-owned space to agent ownership before mutation.

### What happens when completeTaskSpace is called with keep: false?

When **`completeTaskSpace`** receives `keep: false` (implemented in lines 274-314 of [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)), it claims user-owned spaces before closing them, or directly closes agent-owned spaces. This ensures clean teardown of collaboration environments while preventing the agent from leaving unclaimed user spaces in an ambiguous state.

### Where are the taskSpaces helpers exposed in the SDK?

All task-space helpers are injected onto the global object during **`installEgoSdk`** in [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts). The specific function names are listed in the `LEGACY_GLOBAL_HELPERS` array (lines 21-33), which includes `listTaskSpaces`, `newTaskSpace`, `claimTaskSpace`, and other collaboration management functions.