# How to Complete a Task Space with keep:true vs keep:false in ego-browser

> Learn how ego-browser's keep:true and keep:false options complete task spaces. Decide whether to keep or close spaces for your workflow.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: how-to-guide
- Published: 2026-08-06

---

**Use `keep:true` to hand the page back to the user without closing it, or `keep:false` to claim and close the space entirely.**

The `completeTaskSpace` helper in **ego-browser** (from the `citrolabs/ego-lite` repository) controls how agent work ends on a task space. The `keep` boolean option determines whether the page stays open for user inspection or gets cleaned up immediately. This flow is implemented in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) and exposed through the SDK's public helper list in [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts).

## What completeTaskSpace Does

`completeTaskSpace` is the standard way to finish work on a **task space** — a browser tab or isolated page context managed by the ego runtime. The function wraps two underlying runtime operations: `ego.completeTaskSpace` (mark as done, hide overlay) and `ego.closeTaskSpace` (destroy the space).

The helper accepts a space name or ID and an options object containing the `keep` flag. Based on this flag and the space's **ownership state** (agent-owned vs user-owned), it executes one of two distinct code paths.

## The keep:true Flow (Hand Off to User)

When `keep:true` is passed, the goal is to **complete agent work while leaving the page open** for the user to review.

### What happens step by step

1. **Validate inputs** — ensure name/id exists and `options.keep` is boolean (lines 274-285 in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts))
2. **Locate the task space** via `listTaskSpaces()` → `findMatchingTaskSpace`
3. **Check ownership**:
   - If `ownership === "user"` → return `{ done: false, skipped: "user-owned" }` immediately (no operation needed)
   - If agent-owned → `selectTaskSpace` then call `ego.completeTaskSpace()` (runtime marks complete and hides overlay)
4. Return `{ done: true }`

The key distinction: `keep:true` only acts on **agent-owned spaces**. User-owned spaces are skipped because the user already controls the page.

```javascript
// Complete and hand back to user
const result = await ego.completeTaskSpace('order-checkout', { keep: true });
// → { done: true } — page stays open, agent overlay hidden

```

## The keep:false Flow (Close and Clean Up)

When `keep:false` is passed, the goal is to **destroy the task space entirely** after agent work finishes.

### What happens step by step

1. **Validate inputs** and locate the space (same as keep:true)
2. **Claim if necessary**:
   - If `ownership === "user"` → first call `claimResolvedTaskSpace` to take control
   - If already agent-owned → just `selectTaskSpace`
3. **Close the space** — call `ego.closeTaskSpace()` to destroy it
4. Return `{ done: true }`

The key distinction: `keep:false` **always removes the space**. If the user currently owns it, the agent must claim it first before closing.

```javascript
// Close the space entirely
const result = await ego.completeTaskSpace('order-checkout', { keep: false });
// → { done: true } — tab is closed, resources freed

```

## Ownership States and Return Values

| Scenario | `keep` value | Action | Return value |
|----------|-------------|--------|--------------|
| Agent-owned space | `true` | Complete (hide overlay) | `{ done: true }` |
| User-owned space | `true` | No operation | `{ done: false, skipped: "user-owned" }` |
| Any space | `false` | Claim if needed, then close | `{ done: true }` |

The ownership check prevents redundant operations. As the source comments note (lines 263-270 in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)), the `keep:true` path specifically avoids interfering when "the user already controls the page."

## Complete Implementation Reference

The full `completeTaskSpace` implementation spans lines **274-317** in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts):

```typescript
// Simplified structure based on source
export async function completeTaskSpace(
  nameOrId: string,
  options: { keep: boolean }
): Promise<CompletionResult> {
  // Validate (lines 274-285)
  assertArgument(nameOrId, 'nameOrId', 'string');
  assertArgument(options.keep, 'options.keep', 'boolean');
  
  // Find space (lines 286-290)
  const space = await findMatchingTaskSpace(nameOrId);
  
  if (options.keep) {
    // Lines 291-302: keep:true branch
    if (space.ownership === 'user') {
      return { done: false, skipped: 'user-owned' };
    }
    await selectTaskSpace(space.id);
    await ego.completeTaskSpace(space.id); // runtime call
    return { done: true };
  } else {
    // Lines 303-317: keep:false branch
    if (space.ownership === 'user') {
      await claimResolvedTaskSpace(space.id);
    }
    await selectTaskSpace(space.id);
    await ego.closeTaskSpace(space.id); // runtime call
    return { done: true };
  }
}

```

The helper is exported in [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts) (lines 125-132) and bound to `globalThis.ego` for agent script access.

## When to Use Each Option

| Use case | Recommended `keep` | Why |
|----------|-------------------|-----|
| Agent finishes task, user needs to review/submit | `true` | Page stays open, overlay disappears, user takes control |
| Agent finishes task, no further interaction needed | `false` | Immediate cleanup, frees browser resources |
| Unsure of ownership state | `true` | Safe no-op if user already owns it; `false` would forcibly claim and close |
| Automated batch processing | `false` | Minimize resource usage, close tabs aggressively |

## Summary

- **`completeTaskSpace` in ego-browser** ends agent work on a task space via two distinct flows controlled by the `keep` option
- **`keep:true`** completes agent-owned spaces (hide overlay, keep open) and skips user-owned spaces
- **`keep:false`** claims user-owned spaces if necessary, then closes and destroys the space
- **Implementation lives in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)** (lines 263-317), with SDK exposure via [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts)
- **Return values differ**: `keep:true` on user-owned returns `{ done: false, skipped: "user-owned" }`; all successful closures return `{ done: true }`

## 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 making any changes. Since the user already controls the page, no hand-off is necessary. This is an intentional no-op to prevent redundant operations.

### Does keep:false always close the tab, or can it fail?

`keep:false` always attempts to close the space. If the space is user-owned, the helper first calls `claimResolvedTaskSpace` to transfer ownership to the agent, then proceeds with `closeTaskSpace`. The operation succeeds or throws — it does not silently skip.

### Where is completeTaskSpace exposed in the SDK?

The helper is registered in [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts) lines 125-132 as part of the public helper list. It becomes available to agent scripts through `globalThis.ego.completeTaskSpace` after SDK initialization.

### Can I complete a task space without calling completeTaskSpace?

Direct runtime calls are possible (`ego.completeTaskSpace` and `ego.closeTaskSpace`), but `completeTaskSpace` in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) provides essential safety checks: input validation, space lookup, ownership handling, and proper sequencing of claim/select operations. Direct runtime calls bypass these protections.