How to Complete a Task Space with keep:true vs keep:false in ego-browser
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 and exposed through the SDK's public helper list in 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
- Validate inputs — ensure name/id exists and
options.keepis boolean (lines 274-285 insrc/helpers.ts) - Locate the task space via
listTaskSpaces()→findMatchingTaskSpace - Check ownership:
- If
ownership === "user"→ return{ done: false, skipped: "user-owned" }immediately (no operation needed) - If agent-owned →
selectTaskSpacethen callego.completeTaskSpace()(runtime marks complete and hides overlay)
- If
- 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.
// 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
- Validate inputs and locate the space (same as keep:true)
- Claim if necessary:
- If
ownership === "user"→ first callclaimResolvedTaskSpaceto take control - If already agent-owned → just
selectTaskSpace
- If
- Close the space — call
ego.closeTaskSpace()to destroy it - 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.
// 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), 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:
// 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 (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
completeTaskSpacein ego-browser ends agent work on a task space via two distinct flows controlled by thekeepoptionkeep:truecompletes agent-owned spaces (hide overlay, keep open) and skips user-owned spaceskeep:falseclaims user-owned spaces if necessary, then closes and destroys the space- Implementation lives in
src/helpers.ts(lines 263-317), with SDK exposure viasrc/index.ts - Return values differ:
keep:trueon 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 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 provides essential safety checks: input validation, space lookup, ownership handling, and proper sequencing of claim/select operations. Direct runtime calls bypass these protections.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →