# How `completeTaskSpace` Works in ego‑lite: Understanding the `keep` Option

> Explore how ego-lite's completeTaskSpace functions, focusing on the keep option. Learn how to manage task spaces effectively for user inspection or complete closure. Master ownership transitions and status reporting.

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

---

**The `completeTaskSpace` helper in ego‑lite finishes work on a task space: with `keep: true` the page stays open for user inspection, while `keep: false` closes the space completely.** This function handles ownership transitions between the agent and the user, returning status objects that indicate whether the operation succeeded or was skipped.

The ego‑lite browser package provides `completeTaskSpace` as a high‑level runtime helper for managing **task spaces**—isolated browsing contexts that agents can own or hand over to users. According to the citrolabs/ego‑lite source code, the function's behavior depends heavily on the `keep` boolean option and the current ownership state of the target space.

## Core Behavior of `completeTaskSpace`

`completeTaskSpace` accepts two arguments:

1. A task space identifier (`name` or `id`)
2. An options object `{ keep: boolean }`

The function validates inputs, ensures the ego runtime exists, and looks up the task space via `listTaskSpaces()` before acting. If anything is malformed or missing, it throws descriptive errors.

### How `keep: true` Behaves

When `keep` is set to `true`:

- **Agent‑owned spaces**: The runtime calls `ego.completeTaskSpace()`, hides the agent overlay, and leaves the page open so the user can inspect results. Returns `{ done: true }`.
- **User‑owned spaces**: The function returns `{ done: false, skipped: "user‑owned" }` as a no‑op—the user already controls the page.

```js
// Keep an agent-owned space open for user inspection
await completeTaskSpace(42, { keep: true });
// → { done: true }

```

### How `keep: false` Behaves

When `keep` is set to `false`:

- **Agent‑owned spaces**: The space is selected and closed via `ego.closeTaskSpace()`.
- **User‑owned spaces**: The agent first **claims** the space, then closes it.

In both cases, the function returns `{ done: true }` to indicate the space is closed.

```js
// Close a task space completely
await completeTaskSpace('checkout-flow', { key: false });
// → { done: true }

```

## Implementation Details

The source implementation in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) follows distinct code paths based on ownership and the `keep` flag.

### User‑Owned Space Handling

As implemented in [lines 64‑71 of [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts#L64-L71), user‑owned spaces receive special treatment:

- `keep: true` → immediate return with `skipped: "user-owned"` status
- `keep: false` → ownership claim followed by closure

### Agent‑Owned Space Handling

The agent‑owned path splits into two branches at [lines 96‑115](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts#L96-L115):

- **Lines 96‑105**: `keep: true` triggers `ego.completeTaskSpace()` for graceful handover
- **Lines 106‑115**: `keep: false` triggers `ego.closeTaskSpace()` after ensuring control

## Practical Code Examples

### Complete and hand over to user

```js
// After finishing automation, let the user see the results
const result = await completeTaskSpace('form-submission', { keep: true });
console.log(result.done);  // true when successful

```

### Force close regardless of ownership

```js
// Ensure cleanup even if user interacted with the page
await completeTaskSpace('payment-modal', { keep: false });
// Always returns { done: true }

```

### Branch on ownership status

```js
const { done, skipped } = await completeTaskSpace(currentSpace, { keep: true });

if (!done && skipped === 'user-owned') {
  // User opened this tab independently—no agent cleanup needed
  await notifyUser('Please close the tab when finished');
}

```

### Handle multiple spaces

```js
const spaces = await listTaskSpaces();
for (const space of spaces) {
  if (space.agentOwned) {
    await completeTaskSpace(space.id, { keep: false });  // Clean shutdown
  }
}

```

## Source File Reference

| File | Purpose | Key Location |
|------|---------|--------------|
| [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) | Core implementation of `completeTaskSpace` and ownership utilities | [Lines 64‑115](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts#L64-L115) |
| [`package/ego-browser/src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/index.ts) | Public API export | Re‑exports `completeTaskSpace` |
| `package/ego-browser/src/taskspace-e2e.test.mjs` | End‑to‑end verification of `keep` behavior and ownership edge cases | Full test suite |

The test suite in `taskspace-e2e.test.mjs` validates these behaviors against real browser sessions, ensuring the ownership detection and state transitions work correctly across different automation scenarios.

## Summary

- **`completeTaskSpace`** finalizes work on an ego‑lite task space with configurable cleanup behavior
- **`keep: true`** preserves the page for user inspection, hiding the agent overlay; returns early with `skipped: "user-owned"` if the user already owns the space
- **`keep: false`** forcibly closes the space, claiming ownership first if necessary
- Return values always include a `done` boolean; conditional `skipped` string indicates no‑op scenarios
- Implementation lives in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) with comprehensive E2E test coverage

## Frequently Asked Questions

### What happens if I call `completeTaskSpace` with `keep: true` on a user‑owned space?

The function returns `{ done: false, skipped: "user-owned" }` without modifying the page. Since the user already controls the tab, no handover is needed. This prevents accidental interference with user‑initiated browsing sessions.

### Can `completeTaskSpace` fail, and how do I handle errors?

Yes. The function throws descriptive errors if:
- The ego runtime is not initialized
- The task space identifier is missing or malformed
- The specified space does not exist in `listTaskSpaces()`

Wrap calls in try/catch blocks and validate identifiers before invoking.

### When should I use `keep: false` instead of `keep: true`?

Use `keep: false` for automated cleanup in headless scenarios, multi‑step workflows where the space is temporary, or when you need to guarantee resource release. Use `keep: true` when the automation produces a result that benefits from human review—form submissions, search results, or generated content.

### Does `completeTaskSpace` work across browser tabs or windows?

Task spaces operate as isolated browsing contexts within the ego‑lite runtime. The `completeTaskSpace` helper affects the specific space identified by name or ID, regardless of which tab or window hosts it. The underlying runtime handles the mapping between space identifiers and actual browser contexts.