Skip to content

fix: reopen persisted managed worktrees - #107

Open
Ahmed-Hindy wants to merge 2 commits into
Waishnav:mainfrom
Ahmed-Hindy:agent/reopen-persisted-managed-worktrees
Open

fix: reopen persisted managed worktrees#107
Ahmed-Hindy wants to merge 2 commits into
Waishnav:mainfrom
Ahmed-Hindy:agent/reopen-persisted-managed-worktrees

Conversation

@Ahmed-Hindy

@Ahmed-Hindy Ahmed-Hindy commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Fixes #106

Summary

  • Let checkout-mode open_workspace rehydrate an exact persisted managed worktree by path.
  • Reuse the original workspace ID instead of creating a new checkout session.
  • Add a regression test with a managed-worktree root outside allowedRoots, plus an assertion that an unregistered sibling remains denied.

Root cause

Persisted managed worktrees already restore safely by workspace ID: their source root is checked against allowedRoots and their worktree root against the dedicated managed-worktree root. When the client loses that ID, open_workspace only followed the new-checkout path and rejected the same worktree because the worktree parent is intentionally outside allowedRoots.

Security

Rehydration applies only to exact persisted sessions marked as both mode: "worktree" and managed: true; restored-worktree validation remains unchanged. Arbitrary paths below the managed-worktree parent are still rejected.

Validation

  • tsx src/workspaces.test.ts
  • npm run typecheck
  • npm run build
  • npm test reaches an existing Node 24 failure in src/process-sessions.test.ts:122 before the workspace test runs (true !== false).

Summary by CodeRabbit

  • New Features

    • Reopen and automatically restore persisted worktree workspaces when they match a managed root.
    • When multiple sessions share the same root, the most recently used session is selected.
    • Restored workspaces keep their identity, mode, source root, and worktree details, including restored agent profiles.
  • Bug Fixes

    • Prevent opening worktree paths that are not registered or that fall outside approved roots.
    • Improved persistence/reopening behavior for worktree sessions.

@Ahmed-Hindy
Ahmed-Hindy marked this pull request as ready for review July 25, 2026 21:35
@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: efea6d19-65b5-4782-b86e-57af973ba1d4

📥 Commits

Reviewing files that changed from the base of the PR and between e7602f5 and 2ac43f8.

📒 Files selected for processing (2)
  • src/workspaces.test.ts
  • src/workspaces.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/workspaces.ts

📝 Walkthrough

Walkthrough

Adds root-based workspace session lookup and uses it to reopen persisted managed worktrees by path. Tests cover restoration across store reopening, managed worktree metadata, agent restoration, rejection of unregistered paths, and cleanup.

Changes

Managed worktree restoration

Layer / File(s) Summary
Session root lookup
src/workspace-store.ts
Adds getSessionByRoot, returning the most recently used session matching a workspace root.
Path-based restoration and regression coverage
src/workspaces.ts, src/workspaces.test.ts
Restores persisted managed worktrees by resolved path, loads agent files, verifies persisted metadata and agents, and rejects unregistered paths under a separate worktree root.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant WorkspaceRegistry
  participant SqliteWorkspaceStore
  participant Workspace
  Client->>WorkspaceRegistry: openCheckoutWorkspace(path)
  WorkspaceRegistry->>SqliteWorkspaceStore: getSessionByRoot(resolved path)
  SqliteWorkspaceStore-->>WorkspaceRegistry: matching session
  WorkspaceRegistry->>Workspace: getWorkspace(session id)
  Workspace-->>WorkspaceRegistry: workspace and agent data
  WorkspaceRegistry-->>Client: restored WorkspaceContext
Loading

Possibly related PRs

Poem

I hop through roots where worktrees hide,
A saved session waits inside.
The path is found, the agents wake,
Old workspace threads resume their track.
Unregistered paths? “Not today!”
— a careful bunny guards the way.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes reopening persisted managed worktrees.
Linked Issues check ✅ Passed The implementation restores persisted managed worktrees by exact path, respects mode/managed checks, and adds the required regression coverage.
Out of Scope Changes check ✅ Passed The changes stay focused on managed-worktree recovery and related tests, with no clear unrelated additions.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/workspaces.test.ts`:
- Around line 183-196: Update the reopened workspace assertions around
reopenedRegistry.openWorkspace and the subsequent assert.rejects call to run
inside a try/finally block, with reopenedStore.close() in finally. Preserve all
existing assertions and ensure cleanup executes even when an assertion fails.

In `@src/workspaces.ts`:
- Around line 182-187: Update the path-based restoration branch around
getWorkspace and loadInitialAgentsFiles to load local agent profiles with
loadLocalAgentProfiles for the restored workspace, preserving them in the
returned workspace data. Ensure the persistence test covering restored managed
worktrees verifies that agent profiles are retained after restart.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 100315d5-7e75-4bc4-9716-3c8f1a21243d

📥 Commits

Reviewing files that changed from the base of the PR and between 0d9b60c and e7602f5.

📒 Files selected for processing (3)
  • src/workspace-store.ts
  • src/workspaces.test.ts
  • src/workspaces.ts

Comment thread src/workspaces.test.ts
Comment thread src/workspaces.ts
@Ahmed-Hindy

Copy link
Copy Markdown
Contributor Author

@Waishnav requesting review

Comment thread src/workspaces.ts
private async openCheckoutWorkspace(path: string): Promise<WorkspaceContext> {
const restoredWorktree = this.store?.getSessionByRoot(resolve(expandHomePath(path)));
if (restoredWorktree?.mode === "worktree" && restoredWorktree.managed) {
const workspace = this.getWorkspace(restoredWorktree.id);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Stale worktree roots are restored

When a persisted managed worktree has been deleted or moved, this branch reconstructs and returns it without checking that its root still exists, causing subsequent file operations or process startup to fail against a nonexistent workspace.

@greptile-apps

greptile-apps Bot commented Jul 29, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds exact-path restoration for persisted managed worktrees.

  • Adds a store query that selects the most recently used session for a root.
  • Reuses a persisted managed-worktree ID and reloads its local agent context.
  • Adds regression coverage for reopening a managed worktree outside allowed checkout roots while rejecting an unregistered sibling.

Confidence Score: 3/5

The PR should not merge until path-based restoration rejects or handles persisted managed worktrees whose directories no longer exist.

The new lookup can select a retained session after its worktree has been removed, and the restoration branch returns that reconstructed workspace without the filesystem validation performed on ordinary checkout roots.

Files Needing Attention: src/workspaces.ts

Important Files Changed

Filename Overview
src/workspaces.ts Adds path-based managed-worktree restoration, but can return a stale persisted workspace after its directory disappears.
src/workspace-store.ts Adds an exact-root lookup ordered by most recent use; retained rows enable the stale-root restoration issue.
src/workspaces.test.ts Covers successful restoration and denial of an unregistered sibling, but not restoration after the persisted worktree is removed.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Open checkout-mode path] --> B[Look up persisted session by exact root]
    B --> C{Managed worktree session?}
    C -- Yes --> D[Restore original workspace ID]
    D --> E[Reload agents and context]
    C -- No --> F[Validate against allowed checkout roots]
    F --> G[Open or create checkout workspace]
Loading

Reviews (1): Last reviewed commit: "fix: restore managed worktree profiles" | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow open_workspace to reopen persisted managed worktrees by path

1 participant