Skip to content

feat(stagewise): support isolated dev instances - #1524

Merged
glenntws merged 5 commits into
mainfrom
isolated-dev-instances
Aug 6, 2026
Merged

glenntws merged 5 commits into
mainfrom
isolated-dev-instances

Conversation

@jakobFNF

@jakobFNF jakobFNF commented Aug 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

This makes it possible to run the stagewise Electron app from multiple Git worktrees at the same time, so multiple features can be developed and tested in parallel.

  • add pnpm -F stagewise start:isolated
  • derive a stable dev instance ID from the current worktree
  • isolate Electron user data, temp data, ports, and single-instance locks
  • seed shared development data such as login, credentials, preferences, and
    recent workspaces
  • keep the regular pnpm -F stagewise start behavior unchanged

Note

Medium Risk
Dev-only and opt-in, but it copies auth/credentials between profiles and changes Electron paths and ports; mistakes could affect local dev data or encryption on Windows.

Overview
Adds parallel dev Electron runs from multiple worktrees via pnpm -F stagewise start:isolated, which sets STAGEWISE_DEV_INSTANCE=auto and derives a stable 8-character ID from the worktree path.

That ID drives per-instance isolation: __APP_BASE_NAME__ becomes stagewise-dev-<id> (userData, temp roots, Windows App User Model ID, single-instance lock), and the pages Vite dev server uses a stable port in the 30000–39999 range derived from the suffix. Regular start is unchanged.

First launch of an isolated profile one-time seeds missing files (auth, credentials, preferences, identity, etc.) from the default stagewise-dev profile, with a marker so it does not repeat; app data reset keeps that marker. On Windows, dev app.setName stays on the default dev label so copied session/Local State can work with safeStorage, while display names still show the instance ID.

Cleanup adds --isolated-only on clean-data and root clean:browser-data-isolated to remove only stagewise-dev-* userData and temp directories.

Reviewed by Cursor Bugbot for commit 2c6f98a. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Run multiple isolated Stagewise dev Electron instances from different Git worktrees in parallel with unique data, locks, and ports. Also improves cleanup by surfacing errors during isolated profile removal.

  • New Features

    • Add pnpm -F stagewise start:isolated (STAGEWISE_DEV_INSTANCE=auto) that derives an 8-char ID from the worktree.
    • Isolate userData, temp folder, session/ports, and single-instance locks; app base name becomes stagewise-dev-<id>. Vite pages dev server and HMR use a stable port derived from the ID.
    • One-time seeding of selected files (auth, credentials, preferences, identity, recent workspaces) from the default stagewise-dev profile, guarded by a marker. On Windows, also copy session/Local State; keep a stable dev app.setName so encrypted/safeStorage data works.
    • Add pnpm clean:browser-data-isolated (alias of pnpm -F stagewise clean-data --isolated-only) to remove only isolated dev userData and temp directories.
  • Bug Fixes

    • Surface errors when cleaning isolated dev profiles so failures are visible during clean-data runs.

Written for commit 2c6f98a. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Added an isolated development start option with a unique app identity, temporary data location, and development port for each workspace.
    • Development instances can reuse selected settings from the shared development profile.
    • Existing profile files are preserved, and setup is skipped when already completed.
    • Added an option to clean up isolated development data independently.
  • Bug Fixes

    • Resetting app data now preserves isolated development profile information.
  • Tests

    • Added coverage for profile setup, repeated launches, file preservation, and default development behavior.

@vercel

vercel Bot commented Aug 6, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
website Ready Ready Preview Aug 6, 2026 3:23pm

Request Review

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026 •

Copy link
Copy Markdown
Contributor

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

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 04c51ab8-c871-445e-a24b-8b22660c429d

📥 Commits

Reviewing files that changed from the base of the PR and between d2ae72c and 2c6f98a.

📒 Files selected for processing (1)
  • apps/browser/scripts/clean-data.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/browser/scripts/clean-data.ts

📝 Walkthrough

Walkthrough

Development builds derive unique identities and ports from the worktree path. Isolated instances use separate application data paths, seed missing profile files at startup, preserve the seed marker during resets, and support isolated data cleanup.

Changes

Isolated development profile

Layer / File(s) Summary
Development identity and paths
apps/browser/build-constants.ts, apps/browser/package.json, apps/browser/src/backend/utils/paths.ts, apps/browser/vite.pages.config.ts
Automatic development instances append an 8-character worktree hash to their base and display names. The isolated start script enables this mode. Development temp paths and Vite server ports use the application base name.
Profile seeding and reset preservation
apps/browser/src/backend/utils/seed-isolated-dev-profile.ts, apps/browser/src/backend/utils/seed-isolated-dev-profile.test.ts, apps/browser/src/backend/utils/app-data-reset.ts, apps/browser/src/backend/utils/app-data-reset.test.ts
seedIsolatedDevProfile copies missing allowed files, writes a marker, skips repeated seeding, and excludes the default development profile. App-data reset preserves the seed marker. Tests cover these behaviors.
Startup profile initialization
apps/browser/src/backend/index.ts
Backend startup uses build-time application constants and seeds isolated profile data. Successful copies are logged, and seeding errors are logged without stopping startup.
Isolated data cleanup
apps/browser/scripts/clean-data.ts, package.json
The cleanup script discovers isolated directories and removes their user-data and temporary directories. A dedicated package script runs cleanup in isolated-only mode.

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

Possibly related PRs

  • stagewise-io/stagewise#1179: Both changes modify application identity and channel handling in browser build and backend startup code.
  • stagewise-io/stagewise#1469: Both changes modify app-data reset behavior and tests, including preservation of isolated-development state.

Sequence Diagram(s)

sequenceDiagram
  participant Developer
  participant StartIsolated
  participant BackendStartup
  participant SeedProfile
  participant UserData
  Developer->>StartIsolated: Run isolated development script
  StartIsolated->>BackendStartup: Set STAGEWISE_DEV_INSTANCE=auto
  BackendStartup->>SeedProfile: Seed isolated profile
  SeedProfile->>UserData: Copy missing files and write marker
  SeedProfile-->>BackendStartup: Return copied-file count
  BackendStartup-->>Developer: Continue application startup
Loading
🚥 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 clearly and concisely summarizes the main change: support for isolated Stagewise development instances.
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.
✨ 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 isolated-dev-instances

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 6, 2026 •

Copy link
Copy Markdown

Greptile Summary

Adds worktree-specific Electron development instances while preserving the existing default development flow.

  • Derives stable instance-specific application identities, data paths, temporary paths, and pages-server ports.
  • Seeds selected state from the shared development profile on first launch.
  • Adds isolated-profile cleanup and reset-marker handling.

Confidence Score: 5/5

The PR appears safe to merge because no blocking failure remains within the eligible follow-up-review scope.

No blocking failure remains.

Important Files Changed

Filename Overview
apps/browser/build-constants.ts Derives stable worktree-based development instance names while retaining the existing names for ordinary development and release channels.
apps/browser/src/backend/index.ts Applies instance-specific Electron identity and user-data paths and seeds isolated profiles during startup.
apps/browser/src/backend/utils/seed-isolated-dev-profile.ts Implements allowlisted, non-overwriting, one-time profile seeding, including Windows Local State.
apps/browser/src/backend/utils/app-data-reset.ts Preserves the isolated-profile seed marker when processing an application-data reset.
apps/browser/scripts/clean-data.ts Extends developer cleanup to discover isolated user-data and temporary directories and adds isolated-only scope.
apps/browser/vite.pages.config.ts Assigns isolated worktrees stable pages-server and HMR ports while retaining port 5174 for ordinary development.

Reviews (5): Last reviewed commit: "fix(stagewise): surface isolated profile..." | Re-trigger Greptile

Comment thread apps/browser/vite.pages.config.ts
}

fs.writeFileSync(markerPath, '');
return copiedFileCount;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Empty seed still marks complete

Low Severity

seedIsolatedDevProfile writes .isolated-dev-profile-seeded even when it copied nothing. If the default stagewise-dev data root exists but seed files are not there yet, a later login or preferences setup in the default profile never gets copied into the isolated instance.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2b5e27e. Configure here.

@cubic-dev-ai cubic-dev-ai 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.

2 issues found across 9 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/browser/src/backend/utils/seed-isolated-dev-profile.ts">

<violation number="1" location="apps/browser/src/backend/utils/seed-isolated-dev-profile.ts:40">
P2: The one-shot seed copies mutable JSON files from the default dev profile with no atomicity or sync while that profile may be running concurrently, so an isolated instance can permanently inherit a partially-written/corrupt preferences or auth file (the marker then prevents any re-seed). Consider copying via temp-file+rename and re-attempting/clearing partial targets, or accepting this only as a best-effort dev convenience.</violation>

<violation number="2" location="apps/browser/src/backend/utils/seed-isolated-dev-profile.ts:44">
P2: The seed marker `.isolated-dev-profile-seeded` is written unconditionally after the copy loop, even when `copiedFileCount` is 0 because the source files simply didn't exist yet. Since subsequent calls short-circuit on `fs.existsSync(markerPath)`, if the default dev profile's login/preferences/credentials are created after the isolated instance's first run, they will never get copied over. Consider only writing the marker when at least one file was found in the source (or track missing files separately) so seeding can retry until real data becomes available.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

const sourcePath = path.join(sourceDataRoot, fileName);
const targetPath = path.join(targetDataRoot, fileName);
if (!fs.existsSync(sourcePath) || fs.existsSync(targetPath)) continue;
fs.copyFileSync(sourcePath, targetPath);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: The one-shot seed copies mutable JSON files from the default dev profile with no atomicity or sync while that profile may be running concurrently, so an isolated instance can permanently inherit a partially-written/corrupt preferences or auth file (the marker then prevents any re-seed). Consider copying via temp-file+rename and re-attempting/clearing partial targets, or accepting this only as a best-effort dev convenience.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/browser/src/backend/utils/seed-isolated-dev-profile.ts, line 40:

<comment>The one-shot seed copies mutable JSON files from the default dev profile with no atomicity or sync while that profile may be running concurrently, so an isolated instance can permanently inherit a partially-written/corrupt preferences or auth file (the marker then prevents any re-seed). Consider copying via temp-file+rename and re-attempting/clearing partial targets, or accepting this only as a best-effort dev convenience.</comment>

<file context>
@@ -0,0 +1,46 @@
+    const sourcePath = path.join(sourceDataRoot, fileName);
+    const targetPath = path.join(targetDataRoot, fileName);
+    if (!fs.existsSync(sourcePath) || fs.existsSync(targetPath)) continue;
+    fs.copyFileSync(sourcePath, targetPath);
+    copiedFileCount++;
+  }
</file context>

copiedFileCount++;
}

fs.writeFileSync(markerPath, '');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: The seed marker .isolated-dev-profile-seeded is written unconditionally after the copy loop, even when copiedFileCount is 0 because the source files simply didn't exist yet. Since subsequent calls short-circuit on fs.existsSync(markerPath), if the default dev profile's login/preferences/credentials are created after the isolated instance's first run, they will never get copied over. Consider only writing the marker when at least one file was found in the source (or track missing files separately) so seeding can retry until real data becomes available.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/browser/src/backend/utils/seed-isolated-dev-profile.ts, line 44:

<comment>The seed marker `.isolated-dev-profile-seeded` is written unconditionally after the copy loop, even when `copiedFileCount` is 0 because the source files simply didn't exist yet. Since subsequent calls short-circuit on `fs.existsSync(markerPath)`, if the default dev profile's login/preferences/credentials are created after the isolated instance's first run, they will never get copied over. Consider only writing the marker when at least one file was found in the source (or track missing files separately) so seeding can retry until real data becomes available.</comment>

<file context>
@@ -0,0 +1,46 @@
+    copiedFileCount++;
+  }
+
+  fs.writeFileSync(markerPath, '');
+  return copiedFileCount;
+}
</file context>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@apps/browser/vite.pages.config.ts`:
- Around line 22-26: Update the port derivation around pagesPort and its related
Vite server/HMR configuration to use collision-aware per-instance allocation
instead of only applying a modulo 10,000 hash mapping. Ensure the selected
server and HMR ports remain identical, and add coverage for distinct
stagewise-dev identifiers that collide under the current mapping.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 936e370e-9602-4272-90cc-0595c1ceeffa

📥 Commits

Reviewing files that changed from the base of the PR and between 2b5e27e and 9b04d50.

📒 Files selected for processing (1)
  • apps/browser/vite.pages.config.ts

Comment on lines +22 to +26
const pagesPort = buildConstants.__APP_BASE_NAME__.startsWith('stagewise-dev-')
? 30000 +
(Number.parseInt(buildConstants.__APP_BASE_NAME__.slice(-8), 16) % 10000)
: 5174;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n -C 8 '__APP_BASE_NAME__|stagewise-dev-' \
  apps/browser/build-constants.ts \
  apps/browser/vite.pages.config.ts

python - <<'PY'
def pages_port(app_base_name):
    return 30000 + (int(app_base_name[-8:], 16) % 10000)

first = 'stagewise-dev-00002710'
second = 'stagewise-dev-00004e20'

assert pages_port(first) == pages_port(second) == 30000
print(f'collision: {first}, {second} -> {pages_port(first)}')
PY

Repository: stagewise-io/stagewise

Length of output: 3226


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo '## vite.pages.config.ts relevant sections'
sed -n '1,130p' apps/browser/vite.pages.config.ts

echo
echo '## build-constants.ts relevant section'
sed -n '1,70p' apps/browser/build-constants.ts

echo
echo '## devInstance usages'
rg -n -C 4 '\bdevInstance\b|__DEV_INSTANCE__|STAGEWISE_DEV|stagewise-dev' apps/browser apps -g '!node_modules' -g '!dist' -g '!build' | head -n 200

echo
echo '## deterministic port mapping samples'
python3 - <<'PY'
from pathlib import Path
path = Path('apps/browser/vite.pages.config.ts')
text = path.read_text()
print('uses slice(-8):', "slice(-8)" in text)
print('uses strictPort:', "strictPort" in text)

samples = [
    'stagewise-dev-00002710',
    'stagewise-dev-00004e20',
    'stagewise-dev-00003938',
    'stagewise-dev-00005d48',
    'stagewise-dev-0004ea64',
    'stagewise-dev-0006e8b4',
]
for name in samples:
    port = 30000 + (int(name[-8:], 16) % 10000)
    print(name, '->', port)
PY

Repository: stagewise-io/stagewise

Length of output: 21425


Make isolated port allocation collision-aware.

STAGEWISE_DEV_INSTANCE=auto derives stagewise-dev-* instances from the worktree hash truncated to eight hex chars, but vite.pages.config.ts maps that suffix modulo 10,000. Different worktrees can share the same server/HMR port, and strictPort: true blocks the second instance from starting. Use collision-aware allocation or per-instance port reservation, keep the selected server and HMR ports aligned, and add a test for colliding identifiers.

🤖 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 `@apps/browser/vite.pages.config.ts` around lines 22 - 26, Update the port
derivation around pagesPort and its related Vite server/HMR configuration to use
collision-aware per-instance allocation instead of only applying a modulo 10,000
hash mapping. Ensure the selected server and HMR ports remain identical, and add
coverage for distinct stagewise-dev identifiers that collide under the current
mapping.

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 9b04d50. Configure here.

Comment thread apps/browser/src/backend/utils/seed-isolated-dev-profile.ts

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/browser/vite.pages.config.ts">

<violation number="1" location="apps/browser/vite.pages.config.ts:22">
P2: The derived port for isolated dev instances is computed as `30000 + (parseInt(hash.slice(-8),16) % 10000)`, which only has 10,000 possible values. Two different worktrees can hash to the same port, and since `strictPort: true` is set, the second instance will fail to start instead of falling back to another port. Consider a collision-aware allocation strategy (e.g., checking port availability and incrementing) or a larger port space to reduce collision likelihood.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

// Release channel: 'dev' | 'prerelease' | 'release'
const _releaseChannel = process.env.RELEASE_CHANNEL || 'dev';

const pagesPort = buildConstants.__APP_BASE_NAME__.startsWith('stagewise-dev-')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: The derived port for isolated dev instances is computed as 30000 + (parseInt(hash.slice(-8),16) % 10000), which only has 10,000 possible values. Two different worktrees can hash to the same port, and since strictPort: true is set, the second instance will fail to start instead of falling back to another port. Consider a collision-aware allocation strategy (e.g., checking port availability and incrementing) or a larger port space to reduce collision likelihood.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/browser/vite.pages.config.ts, line 22:

<comment>The derived port for isolated dev instances is computed as `30000 + (parseInt(hash.slice(-8),16) % 10000)`, which only has 10,000 possible values. Two different worktrees can hash to the same port, and since `strictPort: true` is set, the second instance will fail to start instead of falling back to another port. Consider a collision-aware allocation strategy (e.g., checking port availability and incrementing) or a larger port space to reduce collision likelihood.</comment>

<file context>
@@ -19,6 +19,11 @@ const _appVersion = packageJson.version;
 // Release channel: 'dev' | 'prerelease' | 'release'
 const _releaseChannel = process.env.RELEASE_CHANNEL || 'dev';
 
+const pagesPort = buildConstants.__APP_BASE_NAME__.startsWith('stagewise-dev-')
+  ? 30000 +
+    (Number.parseInt(buildConstants.__APP_BASE_NAME__.slice(-8), 16) % 10000)
</file context>

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/browser/src/backend/utils/seed-isolated-dev-profile.ts">

<violation number="1" location="apps/browser/src/backend/utils/seed-isolated-dev-profile.ts:41">
P2: Existing Windows isolated profiles created before this change still cannot receive the default profile's `Local State`, because the persisted seed marker causes an early return before this copy runs. A versioned one-time migration or a separate missing-`Local State` check would apply the fix to already-seeded profiles without reseeding their data.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

copiedFileCount++;
}

if (process.platform === 'win32') {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Existing Windows isolated profiles created before this change still cannot receive the default profile's Local State, because the persisted seed marker causes an early return before this copy runs. A versioned one-time migration or a separate missing-Local State check would apply the fix to already-seeded profiles without reseeding their data.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/browser/src/backend/utils/seed-isolated-dev-profile.ts, line 41:

<comment>Existing Windows isolated profiles created before this change still cannot receive the default profile's `Local State`, because the persisted seed marker causes an early return before this copy runs. A versioned one-time migration or a separate missing-`Local State` check would apply the fix to already-seeded profiles without reseeding their data.</comment>

<file context>
@@ -41,6 +38,16 @@ export function seedIsolatedDevProfile(
     copiedFileCount++;
   }
 
+  if (process.platform === 'win32') {
+    const sourcePath = path.join(sourceUserData, 'session', 'Local State');
+    const targetPath = path.join(userDataDirectory, 'session', 'Local State');
</file context>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 `@apps/browser/scripts/clean-data.ts`:
- Line 168: Wrap the completion message template literal in the cleanup flow so
each source line stays within the repository’s 80-character limit, while
preserving the existing message content and interpolation values deletedCount
and tempDeletedCount.
- Around line 106-117: Update getIsolatedDirectories to catch the readdir error
explicitly, return an empty array only when its code is ENOENT, and rethrow
every other error so permission and I/O failures propagate to the cleanup flow.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 35154f63-e40b-45a2-ac0d-540a5b526c3a

📥 Commits

Reviewing files that changed from the base of the PR and between e07cece and d2ae72c.

📒 Files selected for processing (2)
  • apps/browser/scripts/clean-data.ts
  • package.json

Comment thread apps/browser/scripts/clean-data.ts
log(`\n${'='.repeat(50)}`, colors.cyan);
log(
`\n✓ Cleanup complete! Deleted ${deletedCount} userData directories and ${prodTempDeleted + devTempDeleted} temp workspace directories.`,
`\n✓ Cleanup complete! Deleted ${deletedCount} userData directories and ${tempDeletedCount} temp directories.`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Wrap the completion message to meet the line-width rule.

The changed template literal exceeds the 80-character limit. Split the message into shorter parts so Biome can format the code within the repository limit.

Proposed fix
   log(
-    `\n✓ Cleanup complete! Deleted ${deletedCount} userData directories and ${tempDeletedCount} temp directories.`,
+    [
+      '\n✓ Cleanup complete!',
+      `Deleted ${deletedCount} userData directories`,
+      `and ${tempDeletedCount} temp directories.`,
+    ].join(' '),
     colors.green,
   );

As per coding guidelines, JavaScript/TypeScript code must maintain an 80-character line width and use Biome for formatting.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
`\n✓ Cleanup complete! Deleted ${deletedCount} userData directories and ${tempDeletedCount} temp directories.`,
log(
[
'\n✓ Cleanup complete!',
`Deleted ${deletedCount} userData directories`,
`and ${tempDeletedCount} temp directories.`,
].join(' '),
colors.green,
);
🤖 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 `@apps/browser/scripts/clean-data.ts` at line 168, Wrap the completion message
template literal in the cleanup flow so each source line stays within the
repository’s 80-character limit, while preserving the existing message content
and interpolation values deletedCount and tempDeletedCount.

Source: Coding guidelines

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/browser/scripts/clean-data.ts">

<violation number="1" location="apps/browser/scripts/clean-data.ts:144">
P2: The standard `pnpm clean:browser-data` (no flag) now also deletes every isolated `stagewise-dev-*` profile, not just the production and regular-dev directories it cleaned before. Since the whole point of the isolated feature is to keep per-worktree data (auth, credentials, prefs) separate and persistent across concurrent worktrees, a developer running the conventional dev-cleanup command will unexpectedly wipe all of those scoped profiles. Consider gating the isolated-dir removal behind an explicit opt-in (e.g. only clean `stagewise-dev-*` when passed a flag such as `--include-isolated`), leaving the default `clean-data` behavior unchanged, and keeping `--isolated-only` as the targeted way to clean up isolated profiles.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

if (deleted) deletedCount++;
}
}
for (const dirPath of await getIsolatedDirectories(appDataPath)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: The standard pnpm clean:browser-data (no flag) now also deletes every isolated stagewise-dev-* profile, not just the production and regular-dev directories it cleaned before. Since the whole point of the isolated feature is to keep per-worktree data (auth, credentials, prefs) separate and persistent across concurrent worktrees, a developer running the conventional dev-cleanup command will unexpectedly wipe all of those scoped profiles. Consider gating the isolated-dir removal behind an explicit opt-in (e.g. only clean stagewise-dev-* when passed a flag such as --include-isolated), leaving the default clean-data behavior unchanged, and keeping --isolated-only as the targeted way to clean up isolated profiles.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/browser/scripts/clean-data.ts, line 144:

<comment>The standard `pnpm clean:browser-data` (no flag) now also deletes every isolated `stagewise-dev-*` profile, not just the production and regular-dev directories it cleaned before. Since the whole point of the isolated feature is to keep per-worktree data (auth, credentials, prefs) separate and persistent across concurrent worktrees, a developer running the conventional dev-cleanup command will unexpectedly wipe all of those scoped profiles. Consider gating the isolated-dir removal behind an explicit opt-in (e.g. only clean `stagewise-dev-*` when passed a flag such as `--include-isolated`), leaving the default `clean-data` behavior unchanged, and keeping `--isolated-only` as the targeted way to clean up isolated profiles.</comment>

<file context>
@@ -103,43 +103,69 @@ async function cleanTempWorkspaces(tempBasePath: string): Promise<number> {
+      if (deleted) deletedCount++;
+    }
+  }
+  for (const dirPath of await getIsolatedDirectories(appDataPath)) {
     const deleted = await deleteDirectory(dirPath);
     if (deleted) deletedCount++;
</file context>

Comment thread apps/browser/scripts/clean-data.ts Outdated
@glenntws
glenntws merged commit 9480a1a into main Aug 6, 2026
23 of 25 checks passed
@glenntws
glenntws deleted the isolated-dev-instances branch September 14, 2026 09:03

This branch was successfully deployed

1 active and 1 inactive deployments
Dev — 2c6f98a6 Deployed Aug 6, 2026 by jakobFNF via Build Browser (win32-x64) #6073
Preview — 2c6f98a6 Deployed Aug 6, 2026 by vercel[bot]
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.

3 participants