# How `useOrCreateTaskSpace()` Works in ego-lite: Task Space Management Explained

> Learn how useOrCreateTaskSpace in ego-lite automatically retrieves or creates agent-owned task spaces. Understand its ownership validation and runtime selection features.

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

---

**`useOrCreateTaskSpace()` is a high-level helper in ego-lite that retrieves an existing task space or creates a new agent-owned one, handling ownership validation and runtime selection automatically.**

The `useOrCreateTaskSpace()` function serves as the primary entry point for agents to acquire a working environment within the **citrolabs/ego-lite** browser automation framework. Located in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts), this utility abstracts the complexity of task space discovery, creation, and ownership management, ensuring agents operate within the correct context without inadvertently seizing control of user-owned spaces.

## Understanding Task Space Ownership in ego-lite

Task spaces in ego-lite represent isolated execution environments where agents perform browser automation tasks. Each space carries an **ownership** property that determines control rights:

- **`"agent"`** or **`"agentDelegatedToUser"`**: Spaces the agent created and controls
- **`"user"`**: Spaces created by or delegated to the human user
- **Unknown values**: Treated as errors to prevent unsafe operations

According to the source code in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) (around line 143), the helper `isAgentOwned()` returns `true` only for `"agent"` and `"agentDelegatedToUser"` ownership strings, which dictates whether the function can safely claim administrative control.

## How `useOrCreateTaskSpace()` Operates

The function implements a six-step workflow that balances idempotency with strict ownership rules:

### 1. Enumerating Existing Task Spaces

First, the function calls `listTaskSpaces()`, which forwards to the native runtime via `ego.listTaskSpaces` to retrieve all available task spaces from the browser environment.

```javascript
// Internal call chain
listTaskSpaces() -> ego.listTaskSpaces()

```

### 2. Matching by Name or ID

Next, `findMatchingTaskSpace()` searches the enumerated list for a space whose **name** (string) or **numeric ID** matches the supplied `nameOrId` parameter. This dual-type matching allows flexible space referencing across different integration patterns.

### 3. Handling Missing Spaces

When no match exists, the behavior diverges based on input type:

- **Numeric ID**: Throws an error immediately, as numeric identifiers must reference existing spaces
- **String name**: Creates a new agent-owned space via `newTaskSpace(nameOrId)`, which calls `ego.createTaskSpace`

This distinction prevents accidental space proliferation when using database-style IDs while allowing dynamic name-based provisioning.

### 4. Ownership-Based Selection Logic

If a matching space exists, the function evaluates ownership before selection:

- **Agent-owned** (`"agent"` or `"agentDelegatedToUser"`): Immediately selects the space using `selectTaskSpace()`, which invokes `ego.useTaskSpace`
- **User-owned** (`"user"`): Selects the space for the current Node invocation but **does not claim ownership**, displaying the friendly message `"EGO_TASK_SPACE_USER_IN_CONTROL"` rather than throwing an error

### 5. Error Handling for Unknown Ownership

Any ownership value outside the three recognized types triggers an error at lines 212-214 of [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts), enforcing type safety and preventing undefined behavior in the runtime.

### 6. Final Selection and Validation

The `selectTaskSpace()` helper completes the workflow by calling `ego.useTaskSpace` and validating the result through `assertNoEgoError()`, ensuring the runtime successfully switched contexts before returning control to the agent.

## Implementation Details and Source Code

The core logic resides in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) (lines 193-214), with the following supporting utilities:

| Helper Function | File Location | Responsibility |
|-----------------|---------------|----------------|
| `listTaskSpaces()` | [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts) (line 107) | Retrieves task spaces from `ego.listTaskSpaces` |
| `findMatchingTaskSpace()` | [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts) (line 194) | Matches name or numeric ID against the list |
| `newTaskSpace(name)` | [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts) | Creates fresh agent-owned spaces via `ego.createTaskSpace` |
| `isAgentOwned(ownership)` | [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts) (line 143) | Validates ownership strings |
| `selectTaskSpace()` | [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts) (lines 45-50) | Invokes `ego.useTaskSpace` with error handling |

The function is exported publicly from [`package/ego-browser/src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/index.ts) as `useOrCreate: useOrCreateTaskSpace`, providing a clean API surface for consumers.

## Practical Usage Examples

### Idempotent Space Acquisition

Create a space if it doesn't exist, or reuse the existing one:

```javascript
import { useOrCreateTaskSpace } from 'ego-browser';

(async () => {
  // Returns existing space or creates "order-flow"
  const space = await useOrCreateTaskSpace('order-flow');
  
  console.log('Using task space:', space.name, '(id:', space.id, ')');
  
  // Subsequent operations act within this context
})();

```

### Strict Numeric ID Referencing

Enforce that a space must already exist when using numeric identifiers:

```javascript
import { useOrCreateTaskSpace } from 'ego-browser';

(async () => {
  try {
    const space = await useOrCreateTaskSpace(42); // Must exist
    console.log('Switched to space', space.id);
  } catch (e) {
    console.error('Task space not found:', e.message);
  }
})();

```

### Handling User-Owned Spaces

Check ownership before attempting full control:

```javascript
import { useOrCreateTaskSpace, claimTaskSpace } from 'ego-browser';

(async () => {
  const space = await useOrCreateTaskSpace('user-demo');
  
  if (space.ownership === 'user') {
    // Explicitly claim control if needed
    const claimed = await claimTaskSpace(space.id);
    console.log('Claimed user space:', claimed.id);
  }
})();

```

## Summary

- **`useOrCreateTaskSpace()`** provides a single entry point for task space management in citrolabs/ego-lite, located in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts).
- The function **automatically creates** agent-owned spaces when given string names that don't exist, but **throws errors** for non-existent numeric IDs.
- **Ownership validation** prevents agents from automatically claiming user-controlled spaces, requiring explicit `claimTaskSpace()` calls for those scenarios.
- The implementation delegates to native ego runtime APIs (`ego.listTaskSpaces`, `ego.createTaskSpace`, `ego.useTaskSpace`) while providing TypeScript-friendly wrappers with error handling.

## Frequently Asked Questions

### What happens if I pass a numeric ID that doesn't exist?

The function throws an error immediately. Unlike string names, numeric IDs in `useOrCreateTaskSpace()` are treated as strict references to existing spaces. If the ID is not found in the list returned by `listTaskSpaces()`, the function raises an exception rather than creating a new space, preventing accidental ID collisions.

### Can an agent take control of a user-owned task space?

Not automatically. When `useOrCreateTaskSpace()` encounters a user-owned space (`ownership === "user"`), it selects the space for the current operation but does not claim ownership. To gain full control, the agent must explicitly call `claimTaskSpace(space.id)` after checking the ownership property, ensuring intentional user consent.

### Where is `useOrCreateTaskSpace()` exported from?

The function is exported from [`package/ego-browser/src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/index.ts) as part of the public API, aliased as `useOrCreate`. This allows consumers to import it directly from the `ego-browser` package: `import { useOrCreateTaskSpace } from 'ego-browser'`.

### How does the function handle unknown ownership types?

Any ownership value other than `"agent"`, `"agentDelegatedToUser"`, or `"user"` triggers an error in the implementation at lines 212-214 of [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts). This strict validation ensures the runtime cannot enter an undefined state when encountering corrupted or future ownership types not yet supported by the helper.