How handOffTaskSpace and takeOverTaskSpace Operations Transfer Control in ego-lite

Both handOffTaskSpace and takeOverTaskSpace are high-level helper functions in citrolabs/ego-lite that transfer ownership of a browser task space between the agent and the user by looking up the target context, switching the runtime, and delegating to the underlying ego bindings.

The handOffTaskSpace and takeOverTaskSpace operations manage the lifecycle of an isolated browsing context inside the ego-lite framework. When an agent finishes a step, it can hand the task space back to the user; when automation resumes, the agent can take over the same space. These functions live in package/ego-browser/src/helpers.ts and share a common lookup-and-switch routine before calling the native ego runtime.

How handOffTaskSpace Returns Control to the User

The handOffTaskSpace function follows a strict three-step flow to surrender agent control. According to the citrolabs/ego-lite source code, the implementation spans lines 26-40 of package/ego-browser/src/helpers.ts.

Locate the Target Space and Validate Ownership

If a nameOrId argument is provided, the helper calls findTaskSpace, which internally executes listTaskSpaces followed by findMatchingTaskSpace. If the resolved space is already user-owned, the function short-circuits immediately and returns {done:false, skipped:"user-owned"}. This prevents unnecessary runtime calls when the user already holds control.

Switch the Runtime Context

For agent-owned spaces, the helper invokes selectTaskSpace, which calls ego.useTaskSpace to switch the runtime to the chosen context. This ensures that the subsequent hand-off operation targets the correct isolated browsing session.

Invoke the Runtime Hand-Off

After the switch, the function delegates to ego.handOffTaskSpace() and wraps the call with assertNoEgoError. On success, it returns {done:true}, indicating that the agent overlay has been hidden and the user now owns the space.

How takeOverTaskSpace Restores Agent Control

The takeOverTaskSpace function mirrors the lookup logic but omits the user-owned short-circuit. Its flow is implemented in lines 47-54 of package/ego-browser/src/helpers.ts.

Select the Active or Specified Space

When a nameOrId is supplied, selectTaskSpaceIfProvided performs the same lookup and runtime switch as the hand-off routine. If no identifier is given, the function operates directly on the currently active task space without switching contexts.

Call the Runtime Takeover

Once the correct space is active, the helper calls ego.takeOverTaskSpace() inside an assertNoEgoError wrapper. The function resolves with void; the overlay is simply restored, signaling that the agent has resumed work in the browsing context.

Shared Utilities That Power Both Operations

Both control-transfer functions rely on a set of internal helpers defined in package/ego-browser/src/helpers.ts.

Task Space Lookup and Selection

The helpers share three core utilities:

  • findTaskSpace (lines 40-45) fetches the full list of spaces and selects the matching entry.
  • selectTaskSpace (lines 45-51) switches the runtime using ego.useTaskSpace.
  • selectTaskSpaceIfProvided (lines 53-61) is a thin conditional wrapper that runs the lookup only when a nameOrId argument is present.

Error Handling with assertNoEgoError

Every runtime invocation is guarded by assertNoEgoError, imported from package/ego-browser/src/ego-errors.ts. This helper translates low-level ego failures into explicit JavaScript errors, ensuring that hand-off and takeover failures surface immediately rather than silent rejects.

Practical Code Examples

The following snippets demonstrate typical usage patterns for both operations:

// Hand off the current task space (no argument → operates on the active space)
await handOffTaskSpace();   // → { done: true }

// Hand off a specific space, e.g. id 42
const result = await handOffTaskSpace(42);
if (!result.done) {
  console.log('Skipped – space already user-owned');
}

// Take over the current space (agent regains overlay)
await takeOverTaskSpace();

// Take over a named space
await takeOverTaskSpace('order-checkout');

End-to-end validation for these flows is available in package/ego-browser/src/taskspace-e2e.test.mjs, which exercises real hand-off and takeover sequences against the ego runtime.

Summary

  • handOffTaskSpace surrenders an agent-owned task space to the user, returning {done:true} or short-circuiting with {done:false, skipped:"user-owned"} when the user already owns the space.
  • takeOverTaskSpace reclaims a task space for the agent and resolves with void after restoring the overlay.
  • Both functions delegate to ego.handOffTaskSpace() and ego.takeOverTaskSpace() after optionally switching contexts via ego.useTaskSpace.
  • All runtime calls are wrapped with assertNoEgoError to catch and translate ego-side failures immediately.
  • The implementations are centralized in package/ego-browser/src/helpers.ts, with integration tests in taskspace-e2e.test.mjs.

Frequently Asked Questions

What happens if I call handOffTaskSpace on a user-owned task space?

The function detects user ownership during the findTaskSpace lookup and returns {done:false, skipped:"user-owned"} without invoking the ego runtime. This prevents errors when the agent never held control.

Does takeOverTaskSpace require a task space name or id?

No. When called without arguments, takeOverTaskSpace operates on the currently active task space. If you pass a nameOrId, the helper first switches to that space using selectTaskSpaceIfProvided before reclaiming control.

Where is the error handling logic centralized?

The assertNoEgoError helper lives in package/ego-browser/src/ego-errors.ts and is used by both handOffTaskSpace and takeOverTaskSpace to validate every ego runtime response. It ensures that low-level failures are surfaced as explicit exceptions in the JavaScript layer.

How can I verify these operations in a real browser context?

The citrolabs/ego-lite repository includes package/ego-browser/src/taskspace-e2e.test.mjs, an end-to-end test suite that validates full hand-off and takeover lifecycles against a live ego runtime. You can run these tests to verify correct behavior in an integrated environment.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →