Skip to content

feat(workspace): reuse checkout sessions per ChatGPT conversation - #128

Merged
Waishnav merged 59 commits into
mainfrom
codex/chatgpt-conversation-workspace-reuse
Aug 4, 2026
Merged

feat(workspace): reuse checkout sessions per ChatGPT conversation#128
Waishnav merged 59 commits into
mainfrom
codex/chatgpt-conversation-workspace-reuse

Conversation

@Waishnav

@Waishnav Waishnav commented Aug 4, 2026

Copy link
Copy Markdown
Owner

Summary

DevSpace currently creates a new checkout workspace when open_workspace is called again, which loses workspaceId continuity and repeats workspace context in a ChatGPT conversation.

This PR adds optional conversation-scoped checkout recovery using a non-empty _meta["openai/session"] value as an opaque OpenAI-host correlation key. The same conversation opening the same canonical checkout reuses its persisted workspace session, including across MCP reconnects and DevSpace restarts.

Behavior

  • The same supported conversation and canonical checkout reuse one workspaceId.
  • Different conversations receive separate checkout workspaces.
  • Every worktree-mode call creates a fresh managed worktree and workspace, even for the same project and base ref.
  • Worktree opens never replace the reusable checkout binding.
  • A first successful checkout open returns complete workspace context.
  • A repeated open of that same checkout omits repeated model-visible context and instead tells the model to continue following the instructions, nested instruction files, skills, agent profiles, and diagnostics previously supplied for that workspace.
  • Every new worktree returns its own complete context.
  • Opening checkout after a worktree returns the checkout's complete context.
  • Hosts without supported conversation metadata continue using the normal explicit workspaceId workflow and receive complete context on each open.

Conversation metadata is an optional OpenAI host-adapter enhancement, not a standard MCP conversation identifier. The portable contract remains open_workspace returning a workspaceId that later tools pass explicitly.

Model and UI contract

Workspace lifecycle bookkeeping remains internal:

  • workspaceReused and includeBootstrapContext are not part of the model-facing output schema or structuredContent.
  • The model receives direct, actionable text instead of lifecycle booleans.
  • Hidden workspace-card metadata retains complete workspace details and internal reuse state.
  • The UI distinguishes Opened workspace, Reused workspace, and Opened worktree.

Repeated-context suppression is derived from actual reuse of the same checkout. There is no separate persisted project-bootstrap ledger.

Persistence and recovery

  • Persists conversation-to-checkout bindings in SQLite.
  • Canonicalizes project targets across equivalent paths and symlink aliases.
  • Validates persisted sessions before reuse: active status, checkout mode, allowed root, and existing directory.
  • Replaces expected stale bindings while propagating unexpected database and filesystem errors.
  • Keeps workspace sessions and conversation bindings available across restarts.

Review checkpoints

Stable workspace IDs require review checkpoints to survive reinitialization. This PR preserves the existing workspace-open and last-shown checkpoint meanings across restart and concurrent initialization, validates workspace/root consistency, supports safe fallback when the last-shown ref is missing after restart, and retains unborn-repository recovery.

The public show_changes tool contract is unchanged; this PR does not add a since parameter or another model-selectable review baseline.

Validation

Validated with the project-supported Node 22 runtime:

npm test
npm run typecheck
npm run build
git diff --check

The repository CI matrix covers Ubuntu, macOS, and Windows.

Waishnav added 28 commits August 4, 2026 16:06
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR adds conversation-scoped checkout reuse, isolated worktree creation, persisted bootstrap delivery, review checkpoint recovery, request metadata extraction, workspace metadata rendering, database migrations, tests, and workflow guidance.

Changes

Workspace lifecycle

Layer / File(s) Summary
Workspace persistence contracts
src/db/schema.ts, src/db/migrations.ts, src/workspace-store.ts, src/oauth-store.test.ts, src/workspace-store.test.ts
Adds conversation binding and bootstrap tables, migrations, store operations, and migration coverage.
Request metadata extraction
src/request-meta.ts, src/request-meta.test.ts, package.json
Extracts valid OpenAI conversation scope identifiers and adds test coverage to the npm test script.
Conversation-scoped workspace opening
src/workspaces.ts, src/workspace-conversation.test.ts, src/workspaces.test.ts
Reuses checkout workspaces by conversation and project, creates fresh worktrees, claims bootstrap context, canonicalizes paths, and handles persistence and failure cases.
Review checkpoint recovery
src/review-checkpoints.ts, src/review-checkpoints.test.ts
Tracks checkpoint availability, initializes state safely, falls back from missing checkpoints, validates roots, and supports committed and unborn repositories.
Workspace tool and UI contracts
src/server.ts, src/ui/card-types.ts, src/ui/workspace-app.tsx, src/ui/card-types.test.ts
Exposes reuse and bootstrap state through open_workspace, keeps show_changes on default checkpoint behavior, and renders workspace and agent metadata.
Workflow guidance
docs/chatgpt-coding-workflow.md, docs/gotchas.md
Documents checkout reuse, worktree isolation, bootstrap delivery, unsupported-host behavior, retention, and checkpoint behavior.

Estimated code review effort: 4 (Complex) | ~65 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant open_workspace
  participant request_meta
  participant WorkspaceRegistry
  participant WorkspaceStore
  participant ReviewCheckpointManager
  participant WorkspaceCard
  Client->>open_workspace: Request workspace
  open_workspace->>request_meta: Extract openai/session scope
  open_workspace->>WorkspaceRegistry: Open workspace with scope
  WorkspaceRegistry->>WorkspaceStore: Resolve binding and claim bootstrap
  WorkspaceRegistry->>ReviewCheckpointManager: Initialize checkpoints
  WorkspaceRegistry-->>open_workspace: Return workspace context
  open_workspace->>WorkspaceCard: Send workspace metadata
  WorkspaceCard-->>Client: Render workspace information
Loading

Possibly related issues

Possibly related PRs

Poem

A rabbit opened one workspace nest,
Then kept its checkout close and blessed.
Fresh worktrees sprang from every call,
Bootstrap notes stayed safe through all.
Checkpoints watched each change take flight.
The cards showed details clear and bright. 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.33% 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
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: reusing checkout workspace sessions per ChatGPT conversation.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/chatgpt-conversation-workspace-reuse

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.

@greptile-apps

greptile-apps Bot commented Aug 4, 2026

Copy link
Copy Markdown

Greptile Summary

Adds conversation-scoped reuse of checkout workspaces while keeping worktree opens isolated and preserving bootstrap and review state across restarts.

  • Persists checkout bindings and per-project bootstrap-delivery claims in SQLite.
  • Canonicalizes project targets and recovers stale workspace bindings.
  • Persists workspace-open and last-shown review checkpoints using Git refs.
  • Keeps complete workspace metadata in the hidden card while omitting repeated model-visible bootstrap context.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
src/workspaces.ts Implements canonical conversation-scoped checkout reuse, isolated worktree creation, stale-binding recovery, and bootstrap claiming.
src/workspace-store.ts Adds persistent conversation bindings and transactional per-project bootstrap claims.
src/db/migrations.ts Creates the new persistence tables and deterministically backfills bootstrap history from existing bindings.
src/review-checkpoints.ts Persists distinct workspace-open and last-shown checkpoints and safely handles restarts, missing refs, and concurrent initialization.
src/server.ts Extracts OpenAI conversation metadata, connects reuse to workspace opening, and separates visible bootstrap output from complete card metadata.
src/ui/workspace-app.tsx Renders expanded workspace, worktree, agent-provider, agent, instruction, and diagnostic details.

Sequence Diagram

sequenceDiagram
    participant Host as ChatGPT host
    participant Server as MCP server
    participant Registry as WorkspaceRegistry
    participant Store as SQLite store

    Host->>Server: open_workspace(path, openai/session)
    Server->>Registry: openWorkspace(path, conversationScopeId)
    Registry->>Store: lookup checkout binding
    alt valid checkout binding
        Store-->>Registry: existing workspace session
        Registry-->>Server: "workspaceReused=true"
    else no valid binding
        Registry->>Registry: create checkout workspace
        Registry->>Store: persist conversation binding
        Registry-->>Server: "workspaceReused=false"
    end
    Registry->>Store: claim project bootstrap
    Store-->>Registry: first delivery or already claimed
    Registry-->>Server: workspace plus bootstrap state
    Server-->>Host: visible result and complete hidden card metadata
Loading

Reviews (3): Last reviewed commit: "docs(workspace): describe resume behavio..." | Re-trigger Greptile

@Waishnav

Waishnav commented Aug 4, 2026

Copy link
Copy Markdown
Owner Author

[gpt-5.6] RESPONDING ON BEHALF OF WAISHNAV

Addressed the two test findings from the latest CodeRabbit review.

  • Fixed in 0249608: added concurrent checkout-open coverage for one conversation and project. It asserts one workspace ID, exactly one bootstrap response, exactly one workspaceReused result, and complete context metadata while retaining the isolated worktree coverage.
  • Fixed in bf752da (follow-up to 5ea08d3): the restart test now marks the initial README change reviewed, recreates the manager, creates the next file only after restart, and verifies the default review returns only that new file. The workspace-open comparison still verifies both changes.

The focused review suite, complete npm test, type checking, production build, and git diff --check pass.

@Waishnav

Waishnav commented Aug 4, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai, @greptileai full review

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

@Waishnav, I will perform a full review of #128.

✅ Action performed

Full review finished.

@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

🧹 Nitpick comments (5)
docs/gotchas.md (1)

151-154: 🚀 Performance & Scalability | 🔵 Trivial | 🏗️ Heavy lift

Define and implement retention before long-lived deployment.

The document states that workspace sessions, conversation bindings, bootstrap records, and review refs have no expiration or orphan cleanup. Repeated conversations and worktree opens can grow database and repository metadata without a bound.

Define cleanup per record type. Preserve active workspaces and review checkpoints. Remove orphaned records and refs safely.

🤖 Prompt for 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.

In `@docs/gotchas.md` around lines 151 - 154, Define and implement retention
policies for workspace sessions, conversation bindings, conversation bootstrap
records, and review refs before long-lived deployment. Add bounded expiration
and safe orphan cleanup for each record type, while preserving active workspaces
and review checkpoints and ensuring repository refs are removed only when no
longer needed.
src/review-checkpoints.test.ts (1)

94-128: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the workspace_open selector and the missing-open-checkpoint errors.

ReviewSince exposes "workspace_open", but the tests only cover the implicit fallback from "last_shown". Add tests for reviewChanges({ since: "workspace_open", ... }) including the open-ref-missing and both-refs-missing error paths.

🤖 Prompt for 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.

In `@src/review-checkpoints.test.ts` around lines 94 - 128, Add tests in the
review checkpoint suite for explicit since: "workspace_open" via reviewChanges,
covering the normal comparison and the error when the workspace-open ref is
missing. Also cover the error when both the workspace-open and last-shown refs
are missing, using the existing checkpoint setup and ref-deletion helpers.
src/workspaces.ts (1)

237-249: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider refreshing skills for a reused workspace.

reusedWorkspaceContext reloads agentProfiles, agentsFiles, and availableAgentsFiles, but it keeps the skills and skillDiagnostics captured at the first open. A reused checkout therefore reports stale skill metadata to open_workspace card output after the user adds or edits a SKILL.md in the same conversation. loadSkillsForWorkspace is synchronous and cheap, so refreshing keeps all bootstrap-derived data consistent.

♻️ Proposed refresh of skill metadata
   private async reusedWorkspaceContext(workspace: Workspace): Promise<WorkspaceContext> {
+    Object.assign(workspace, this.loadSkillsForWorkspace(workspace.root));
     workspace.agentProfiles = await loadLocalAgentProfiles(this.config, workspace.root);
     const agentsFiles = await this.loadInitialAgentsFiles(workspace.root);
     const availableAgentsFiles = await this.findAvailableAgentsFiles(workspace.root, agentsFiles);
🤖 Prompt for 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.

In `@src/workspaces.ts` around lines 237 - 249, Update reusedWorkspaceContext to
refresh the workspace’s skills and skillDiagnostics by calling
loadSkillsForWorkspace for workspace.root before constructing the returned
WorkspaceContext, and include the refreshed values in the return object so
reused workspaces report current skill metadata.
src/ui/card-types.test.ts (1)

34-66: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the new worktree and instruction expansion branches.

isExpandableCard gained two more workspace branches in src/ui/card-types.ts at lines 174-175: Boolean(card.worktree) and Boolean(card.instruction). Neither branch is exercised here.

💚 Proposed additional tests
+test("a workspace card expands when it contains worktree metadata", () => {
+  assert.equal(
+    isExpandableCard({ tool: "open_workspace", worktree: { path: "/tmp/wt" } }),
+    true,
+  );
+});
+
+test("a workspace card expands when it contains an instruction", () => {
+  assert.equal(
+    isExpandableCard({ tool: "open_workspace", instruction: "Reuse this workspaceId." }),
+    true,
+  );
+});
+
 test("an empty workspace card stays collapsed", () => {
   assert.equal(isExpandableCard({ tool: "open_workspace" }), false);
 });
🤖 Prompt for 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.

In `@src/ui/card-types.test.ts` around lines 34 - 66, Add tests in the
workspace-card section covering `isExpandableCard` returning true when
`worktree` is present and when `instruction` is present. Keep the existing
empty-card assertion to verify cards without any expandable metadata remain
collapsed.
src/workspace-conversation.test.ts (1)

487-490: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Rename the cleanup loop variable.

The loop variable openStore shadows the openStore factory declared at line 477 and holds a SqliteWorkspaceStore instance, not a factory. Rename it to make the cleanup intent clear.

♻️ Proposed rename
   t.after(async () => {
-    for (const openStore of stores) openStore.close();
+    for (const store of stores) store.close();
     await rm(root, { recursive: true, force: true });
   });
🤖 Prompt for 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.

In `@src/workspace-conversation.test.ts` around lines 487 - 490, Rename the
cleanup loop variable in the t.after teardown from openStore to a name
representing its SqliteWorkspaceStore instance, and update the corresponding
close() call; leave the openStore factory declaration and cleanup behavior
unchanged.
🤖 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/review-checkpoints.ts`:
- Around line 96-109: The availability flags openRefAvailable and
baselineRefAvailable are set once during initialization and never refreshed, so
a checkpoint ref removed after startup will still appear available. Before
trusting these flags to determine which ref to use, verify that the selected
baselineRef (derived from effectiveSince and either state.openRef or
state.baselineRef) actually resolves to a commit by attempting the git rev-parse
command. If the ref resolution fails, handle it as an unavailable checkpoint by
applying the same fallback or error-handling logic that occurs in the guard
conditions at lines 96-106, rather than letting the raw git error propagate to
the user.

In `@src/workspace-conversation.test.ts`:
- Around line 383-392: The test around WorkspaceRegistry.openWorkspace should
not require better-sqlite3’s exact error message. Assert the observable
rejection behavior or use the message only as a non-essential secondary check,
while preserving verification that the storage error is propagated rather than
treated as a stale binding.

---

Nitpick comments:
In `@docs/gotchas.md`:
- Around line 151-154: Define and implement retention policies for workspace
sessions, conversation bindings, conversation bootstrap records, and review refs
before long-lived deployment. Add bounded expiration and safe orphan cleanup for
each record type, while preserving active workspaces and review checkpoints and
ensuring repository refs are removed only when no longer needed.

In `@src/review-checkpoints.test.ts`:
- Around line 94-128: Add tests in the review checkpoint suite for explicit
since: "workspace_open" via reviewChanges, covering the normal comparison and
the error when the workspace-open ref is missing. Also cover the error when both
the workspace-open and last-shown refs are missing, using the existing
checkpoint setup and ref-deletion helpers.

In `@src/ui/card-types.test.ts`:
- Around line 34-66: Add tests in the workspace-card section covering
`isExpandableCard` returning true when `worktree` is present and when
`instruction` is present. Keep the existing empty-card assertion to verify cards
without any expandable metadata remain collapsed.

In `@src/workspace-conversation.test.ts`:
- Around line 487-490: Rename the cleanup loop variable in the t.after teardown
from openStore to a name representing its SqliteWorkspaceStore instance, and
update the corresponding close() call; leave the openStore factory declaration
and cleanup behavior unchanged.

In `@src/workspaces.ts`:
- Around line 237-249: Update reusedWorkspaceContext to refresh the workspace’s
skills and skillDiagnostics by calling loadSkillsForWorkspace for workspace.root
before constructing the returned WorkspaceContext, and include the refreshed
values in the return object so reused workspaces report current skill metadata.
🪄 Autofix

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: cc4bdd41-1c88-4447-a6b5-35526fc795fc

📥 Commits

Reviewing files that changed from the base of the PR and between 5f677b8 and e1e2019.

📒 Files selected for processing (19)
  • docs/chatgpt-coding-workflow.md
  • docs/gotchas.md
  • package.json
  • src/db/migrations.ts
  • src/db/schema.ts
  • src/oauth-store.test.ts
  • src/request-meta.test.ts
  • src/request-meta.ts
  • src/review-checkpoints.test.ts
  • src/review-checkpoints.ts
  • src/server.ts
  • src/ui/card-types.test.ts
  • src/ui/card-types.ts
  • src/ui/workspace-app.tsx
  • src/workspace-conversation.test.ts
  • src/workspace-store.test.ts
  • src/workspace-store.ts
  • src/workspaces.test.ts
  • src/workspaces.ts

Comment thread src/review-checkpoints.ts
Comment thread src/workspace-conversation.test.ts
@Waishnav
Waishnav merged commit 81a0093 into main Aug 4, 2026
4 checks passed
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.

1 participant