docs: devlog 011 + known-issues (workspace URI 세션 격리)

This commit is contained in:
2026-03-10 19:33:39 +09:00
parent ae91134ff2
commit 08c5cb461b
4 changed files with 44 additions and 14 deletions

View File

@@ -73,6 +73,7 @@ let sdk;
let statusBar;
let bridgePath;
let projectName;
let workspaceUri = ''; // filesystem path of the workspace folder (for session filtering)
let isActive = false;
let deterministicPort = 0; // derived from projectName, consistent across restarts
let watcher = null;
@@ -1472,24 +1473,43 @@ function setupMonitor() {
return;
}
// ── Filter to sessions owned by THIS window ──
// Each window claims sessions it sees first via writeRegistration().
// Only process sessions registered to THIS projectName (or unclaimed ones).
// PRIMARY: Use trajectoryMetadata.workspaces URI to match sessions to this workspace.
// FALLBACK: Use bridge/register/ files for sessions without metadata.
// This prevents cross-window session grabbing when multiple AG instances run.
let bestSession = null;
let bestSessionId = '';
let bestModTime = '';
const regDir = path.join(bridgePath, 'register');
const normalizedWorkspace = workspaceUri.replace(/\\/g, '/').toLowerCase();
for (const [sid, data] of Object.entries(allTraj.trajectorySummaries)) {
// Check if this session is claimed by another project
const regFile = path.join(regDir, `${sid}.json`);
if (fs.existsSync(regFile)) {
try {
const reg = JSON.parse(fs.readFileSync(regFile, 'utf-8'));
if (reg.project_name && reg.project_name !== projectName) {
// Session belongs to another window — skip
continue;
}
// PRIMARY FILTER: Check workspace URI from trajectoryMetadata
const trajMeta = data.trajectoryMetadata;
if (trajMeta?.workspaces?.length > 0 && normalizedWorkspace) {
const sessionWorkspaceRaw = trajMeta.workspaces[0]?.workspaceFolderAbsoluteUri || '';
// Convert file:///c:/Users/... URI to c:/Users/... path for comparison
const sessionWorkspace = sessionWorkspaceRaw
.replace(/^file:\/\/\//, '')
.replace(/%3A/gi, ':')
.replace(/\\/g, '/')
.toLowerCase();
if (sessionWorkspace && !sessionWorkspace.includes(normalizedWorkspace) && !normalizedWorkspace.includes(sessionWorkspace)) {
// Session belongs to a different workspace — skip
continue;
}
}
else {
// FALLBACK: Check registration file (for sessions without metadata)
const regFile = path.join(regDir, `${sid}.json`);
if (fs.existsSync(regFile)) {
try {
const reg = JSON.parse(fs.readFileSync(regFile, 'utf-8'));
if (reg.project_name && reg.project_name !== projectName) {
// Session belongs to another window — skip
continue;
}
}
catch { }
}
catch { }
}
const modTime = data.lastModifiedTime || '';
if (!bestSession || modTime > bestModTime) {
@@ -2737,7 +2757,10 @@ async function activate(context) {
console.log('Gravity Bridge: activating...');
// Project detection
projectName = detectProjectName();
console.log(`Gravity Bridge: project "${projectName}"`);
// Store workspace folder path for session filtering (prevents cross-window session grabbing)
const folders = vscode.workspace.workspaceFolders;
workspaceUri = folders && folders.length > 0 ? folders[0].uri.fsPath : '';
console.log(`Gravity Bridge: project "${projectName}" workspace="${workspaceUri}"`);
// Bridge path
const config = vscode.workspace.getConfiguration('gravityBridge');
const configPath = config.get('bridgePath');