Im attempting a Cursor_portable, such that I can spawn it in multiple tiny dockers…
Information about where these files are located in a portable Cursor installation:
-
VSCode Database (vscdb):
-
For portable installations, it’s located at .cursor/User/globalStorage/state.vscdb relative to the workspace directory
-
This is set up when launching the portable instance, as seen in the launch-cursor-dock.ps1 script where it uses --user-data-dir=“.cursor”
-
Cursor Rules and Workspace Context:
-
The cursor data directory is defined in portable.config as CURSOR_DATA_DIR=$PSScriptRoot/.cursor
-
Workspace context and settings are stored in:
-
.cursor/User/globalStorage/storage.json - Contains workspace identifier and settings
-
.cursor/User/workspaceStorage/[workspace-id]/ - Contains workspace-specific data
-
.cursor/User/globalStorage/state.vscdb - Contains the database state
The portable structure keeps everything self-contained within the .cursor directory relative to the workspace root, making it fully portable. This is different from the standard installation where these files would typically be in the user’s AppData directory.
When running in portable mode, the launcher script (launch-portable.ps1) sets up these paths using the portable configuration and launches Cursor with the appropriate --user-data-dir argument to ensure all data is stored in the portable location.
launch-cursor-dock.ps1
# Cursor Dock Launcher
param (
[string]$ProjectPath = $null,
[string]$Name = "CursorDock",
[switch]$DevMode
)
# Configuration
$config = @{
CursorPath = "C:\Users\$env:USERNAME\AppData\Local\Programs\Cursor\Cursor.exe"
DockviewPort = 3579
WorkspaceDir = if ($ProjectPath) { $ProjectPath } else { Join-Path $PSScriptRoot "workspace" }
}
# Ensure workspace directory exists
if (-not (Test-Path $config.WorkspaceDir)) {
New-Item -ItemType Directory -Path $config.WorkspaceDir -Force | Out-Null
Write-Host "Created workspace directory: $($config.WorkspaceDir)"
}
# Create project structure
$projectStructure = @(
"src",
"src/components",
"src/hooks",
"src/api",
"public",
".vscode"
)
foreach ($dir in $projectStructure) {
$path = Join-Path $config.WorkspaceDir $dir
if (-not (Test-Path $path)) {
New-Item -ItemType Directory -Path $path -Force | Out-Null
Write-Host "Created directory: $dir"
}
}
# Copy Dockview integration files
$sourceFiles = @{
"cursor_dockview_config.js" = "src/cursor_dockview_config.js"
"CursorDockApp.jsx" = "src/CursorDockApp.jsx"
"components/ProcessMonitor.jsx" = "src/components/ProcessMonitor.jsx"
"hooks/useInterval.js" = "src/hooks/useInterval.js"
"api/processes.js" = "src/api/processes.js"
"package.json" = "package.json"
}
foreach ($source in $sourceFiles.Keys) {
$sourcePath = Join-Path $PSScriptRoot $source
$targetPath = Join-Path $config.WorkspaceDir $sourceFiles[$source]
if (Test-Path $sourcePath) {
Copy-Item -Path $sourcePath -Destination $targetPath -Force
Write-Host "Copied: $($sourceFiles[$source])"
}
}
# Create VS Code settings
$vsCodeSettings = @{
"editor.formatOnSave" = $true
"editor.defaultFormatter" = "esbenp.prettier-vscode"
"files.autoSave" = "afterDelay"
"files.autoSaveDelay" = 1000
"typescript.tsdk" = "node_modules/typescript/lib"
"javascript.updateImportsOnFileMove.enabled" = "always"
"typescript.updateImportsOnFileMove.enabled" = "always"
}
$vsCodeSettingsPath = Join-Path $config.WorkspaceDir ".vscode/settings.json"
$vsCodeSettings | ConvertTo-Json | Out-File $vsCodeSettingsPath -Force
Write-Host "Created VS Code settings"
# Initialize npm project if package.json doesn't exist
$packageJsonPath = Join-Path $config.WorkspaceDir "package.json"
if (-not (Test-Path $packageJsonPath)) {
Set-Location $config.WorkspaceDir
& npm init -y
Write-Host "Initialized npm project"
}
# Install dependencies
Set-Location $config.WorkspaceDir
Write-Host "Installing dependencies..."
& npm install
# Create startup script
$startupScript = @"
const { app, BrowserWindow } = require('electron');
const path = require('path');
function createWindow() {
const win = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
});
win.loadURL('http://localhost:$($config.DockviewPort)');
if ($($DevMode.IsPresent)) {
win.webContents.openDevTools();
}
}
app.whenReady().then(createWindow);
"@
$startupScriptPath = Join-Path $config.WorkspaceDir "main.js"
$startupScript | Out-File $startupScriptPath -Force
Write-Host "Created startup script"
# Launch Cursor with the workspace
$cursorArgs = @(
"--new-window",
"--user-data-dir=""$($config.WorkspaceDir)\.cursor""",
$config.WorkspaceDir
)
Write-Host "Launching Cursor..."
Start-Process -FilePath $config.CursorPath -ArgumentList $cursorArgs
# Start development server
if ($DevMode) {
Write-Host "Starting development server..."
Set-Location $config.WorkspaceDir
Start-Process -FilePath "npm" -ArgumentList "run dev -- -p $($config.DockviewPort)" -NoNewWindow
}
portable.config
# Portable Configuration - Generated 2025-01-11 15:53:45
PORTABLE_ROOT=$PSScriptRoot
R_LIBS_USER=$PSScriptRoot/r_libs
CURSOR_DATA_DIR=$PSScriptRoot/.cursor
NODE_PATH=$PSScriptRoot/node_modules
launch-portable.ps1
# Portable Cursor Dock Launcher
param (
[switch]$DevMode,
[string]$Name = "PortableCursor"
)
# Load portable configuration
$portableConfig = Get-Content (Join-Path $PSScriptRoot "portable.config") | Where-Object { $_ -match '^[^#]' }
foreach ($line in $portableConfig) {
if ($line -match '^([^=]+)=(.*)$') {
[Environment]::SetEnvironmentVariable($matches[1].Trim(), $matches[2].Trim())
}
}
# Set working directory
Set-Location $PSScriptRoot
# Source original launcher with portable paths
. (Join-Path $PSScriptRoot "launch-cursor-dock.ps1") -ProjectPath $PSScriptRoot -Name $Name -DevMode:$DevMode
after launching several of these on my twin machine - going to determine how I can orchetrate multiple YOLOs.
Anyone else looking this direction?