# How to Create or Reuse a Task Space in Ego-Lite: A Complete API Guide

> Learn how to create or reuse a task space in ego-lite with this API guide. Discover useOrCreate new claim and switch methods for efficient agent workflow management in citrolabs/ego-lite.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: api-reference
- Published: 2026-08-22

---

**TLDR: Agents in ego-lite create or reuse task spaces by calling the `taskSpaces` facade injected into every script's helper context — use `useOrCreate(nameOrId)` to reuse an existing space or create one on the fly, `new(name)` for a fresh isolated space, `claim()` to take over a user-opened tab, and `switch()` to move between active contexts.**

In the `citrolabs/ego-lite` browser automation runtime, every browsing session is isolated inside a **task space** — a lightweight context that owns a browser tab, its navigation history, and all associated state. Whether you're building a research agent, a scraping pipeline, or a multi-agent collaboration system, managing these spaces is the core of clean, reproducible browser automation. The runtime exposes a purpose-built facade — the `taskSpaces` helper — that translates high-level JavaScript calls into low-level CDP messages, letting agents create, reuse, and clean up isolated contexts with a few lines of code.

## What Is a Task Space in Ego-Lite?

A task space is the fundamental unit of isolation in ego-lite. Each space corresponds to a browser tab and encapsulates all the state an agent works with: the current page, the navigation history, and the helper context bound to that tab.

When an agent script starts, it gets a fresh helper context that includes the `taskSpaces` facade. The facade is constructed in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) and injected into every script, so you can call `taskSpaces.useOrCreate(...)` as if it were a built-in function. Behind the scenes, the facade translates your method calls into CDP messages like `ego.useTaskSpace` and `ego.createTaskSpace`, then stores the numeric ID of the active space for all subsequent operations.

## The Complete taskSpaces API

The facade exposes a small but complete API for managing task spaces. Here's the full method breakdown, as implemented in [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts) and documented in [`format.ts`](https://github.com/citrolabs/ego-lite/blob/main/format.ts):

| Method | Signature | Behavior | Typical Use Case |
|--------|-----------|----------|------------------|
| `useOrCreate` | `useOrCreate(nameOrId)` | Returns an existing task space matching the name or numeric ID, or creates a new one if none exists | Reusing a previously created workspace (e.g., a "research" task) without worrying about its current state |
| `new` | `new(name)` | Unconditionally creates a fresh task space with the given name | Starting a completely clean browsing session when isolation is required |
| `claim` | `claim(nameOrId)` | Takes ownership of a *user-owned* task space so the agent can operate on it | When a user has opened a tab that the agent should continue working on |
| `switch` | `switch(nameOrId)` | Switches the agent's active context to the specified task space | Performing actions on a different space after it has been created or claimed |
| `complete` | `complete(nameOrId, opts)` | Closes the task space (optionally keeping the underlying tab) | Cleaning up after a job is done |
| `handoff` | — | Hands the space to another agent | Collaborative agent workflows |
| `takeOver` | — | Takes control of a space owned by another agent | Escalation or error recovery |
| `waitForControl` | — | Waits until the user or another agent releases the space | Coordinated human-in-the-loop flows |

Each call returns a metadata object containing the task space's numeric ID and name, e.g., `{ id: 12, name: 'research-task' }`.

## Creating a New Task Space with `new()`

When you need a guaranteed-fresh, isolated browser context, use `new()`. A fresh space—since it unconditionally creates a new tab, any existing space with the same name remains untouched. This makes it ideal for scraping jobs or security-sensitive operations where historical state could corrupt the results.

```javascript
// Start a brand-new, isolated task space
const fresh = await taskSpaces.new('quick-scrape');

// fresh.id is a new numeric identifier
// any other task spaces ('research-task', etc.) remain untouched
console.log(fresh);
// → { id: 14, name: 'quick-scrape' }

```

## Reusing an Existing Task Space with `useOrCreate()`

The `useOrCreate(nameOrId)` method is the cornerstone of task-space reuse. It is doing a lookup: if a task space with the given name or ID already exists, it returns it; otherwise, it creates a new one. This eliminates manual existence checks and makes agent resumption concise.

```javascript
const task = await taskSpaces.useOrCreate('research-task');

// If this task was created earlier, `task` carries an existing state.
// If not, ego-lite creates it now.
console.log(task.id);

```

Because `useOrCreate` accepts either a string name or a numeric ID, you can store a task ID in a file, database, or environment variable, and pick up exactly where you left off on the next run.

## Switching Between Task Spaces with `switch()`

Once you have a reference to a task space, `switch()` sets it as the agent's active context. All subsequent helper calls — `navigate`, `click`, `extract` — operate on that tab.

```js
await taskSpaces.switch(task.id);

// Now all subsequent helper calls operate on the tab owned by taskspace.id
await navigate('https://example.com');
const html = await extract('html');

```

You can switch back and forth between spaces freely; each space retains its own page and history, so you can interleave work on multiple tabs without loading state.

## Claiming a User-Owned Task Space with `claim()`

In human-browser setup, a user might navigate to a page manually and then ask the agent to continue. The `claim()` method transfer ownership of that existing task space to the agent, so you can operate on a tab the user has already prepared.

```javascript
// Take over the space the user has opened (e.g., "user-session")
const task = await taskSpaces.claim('user-session');
await taskSpaces.switch(task.id);

// now the agent controls the tab the user started

```

This is critical for **human-in-the-loop** automation, where the agent takes over mid-browsing rather than starting from a blank tab.

## Cleaning Up with `complete()`

When a task is finished, deadline to close the space. The `complete(nameOrId, { keep })` method lets you close the space and, if `keep` is `true`, close the tab as well; if `keep` is `false` (default), the tab is closed too.

```javascript
await taskSpaces.complete('research-task', { keep: false });

// space is destroyed; the browser tab is closed

```

Leaving unused task spaces open consumes browser memory and clutters the session, so always clear up at the end of a job — or during a `finally` block.

## How the Task-Space Facade Is Wired

The facade is created in the `createTaskSpacesFacade()` factory, located at the bottom of [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts). You can see the exact construction in the repository's source:

- **[`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)** — constructs the `taskSpaces` facade and wires it into the helper context.
- **[`src/format.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/format.ts)** — contains the public API signatures and usage examples that drive the auto-generated help output.
- **`src/taskspace-e2e.test.mjs`** — end-to-end tests exercising the full task-space lifecycle (creation, reuse, switching, completion).
- **[`src/ego-errors.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/ego-errors.ts)** — maps runtime errors (e.g., trying to claim a non-existent space) to helpful error messages.

The facade pattern means you never interact with raw CDP messages directly; the high-level methods abstract away the protocol details, and the facade internally stores the numeric ID of the current task space for subsequent operations.

## Error Handling

When a task-space operation fails (e.g., claiming a space that doesn't exist, or switching to a closed space), ego-lite throws descriptive errors defined in [`ego-errors.ts`](https://github.com/citrolabs/ego-lite/blob/main/ego-errors.ts). Always wrap task-space operations in try/catch, especially when reusing or claiming spaces that might have been closed by another agent or the user.

## Summary

- **`taskSpaces`** is the facade in [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts) that gives agents a clean JS API to manage per-agent browsing contexts.
- The method string is **`useOrCreate(nameOrId)`** — it either finds an existing task space by name or ID or creates a new one, which is the recommended way to resume prior work.
- **`new(name)`** unconditionally creates a **fresh, isolated** space, ideal when clean state is required.
- **`claim()`** and **`switch()`** allow agent-to-user and agent-to-agent ownership handoffs.
- **`complete(id, { keep })`** properly cleans up resources so the browser doesn't accumulate unused tabs.

These primitives make ego-lite's task spaces both **reproducible** and **composable**, enabling everything from simple one-shot scrapers to complex orchestrated multi-tab agent workflows.

## Frequently Asked Questions

### Can I reuse a task space that was created in a previous script run?

Yes. Task spaces are identified by name or numeric ID. As long as you haven't called `complete()` on a space, the `useOrCreate()` method returns the existing space by matching the same name, so you can resume across runs.

### Does `new()` create an identical space to `useOrCreate()` when no space exists?

Effectively, yes — both create a new task space when no matching one exists. The difference is that `new()` always creates a brand-new one, even if a space with that name already exists, while `useOrCreate()` reuses the existing one.

### What happens to the current tab when I call `switch()`?

`switch()` turns the *active context* of the agent to the specified task space without closing or losing the previous tab. The previous task space stays in the browser and can be re-switched to later, so you can iterate between multiple tabs seamlessly.

### When should I prefer `claim()` over `useOrCreate()`?

`claim()` is intended for **user-opened tabs** — it transfers ownership of an existing user-owned space to the agent. Use it when the user has already navigated to a page and hands off to the filler agent. For agent-created or previously-resolved spaces, you should use `useOrCreate()` instead — it never modifies a task, `useOrCreate()` also creates when missing but doesn't transfer ownership.