Skip to content

Commit 2e896f0

Browse files
committed
🤖 Remove stableWorkspacePath (duplicate of namedWorkspacePath)
After architecture inversion, workspace directories use names (not stable IDs), so stableWorkspacePath and namedWorkspacePath are identical. Remove the duplicate field to simplify the type system. Changes: - Remove stableWorkspacePath from FrontendWorkspaceMetadata - Update Config.getWorkspacePaths() to only return namedWorkspacePath - Remove stableWorkspacePath from all test fixtures - Fix config.test.ts to test legacy ID format correctly
1 parent e340256 commit 2e896f0

File tree

8 files changed

+26
-57
lines changed

8 files changed

+26
-57
lines changed

src/config.test.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -71,28 +71,29 @@ describe("Config", () => {
7171
expect(workspace.name).toBe("feature-branch");
7272
});
7373

74-
it("should use existing metadata file if present", () => {
74+
it("should use existing metadata file if present (legacy format)", () => {
7575
const projectPath = "/fake/project";
76-
const workspaceId = "abc123def4";
77-
const workspacePath = path.join(config.srcDir, "project", workspaceId);
76+
const workspaceName = "my-feature";
77+
const workspacePath = path.join(config.srcDir, "project", workspaceName);
7878

7979
// Create workspace directory
8080
fs.mkdirSync(workspacePath, { recursive: true });
8181

82-
// Create metadata file manually
83-
const sessionDir = config.getSessionDir(workspaceId);
82+
// Create metadata file using legacy ID format (project-workspace)
83+
const legacyId = config.generateWorkspaceId(projectPath, workspacePath);
84+
const sessionDir = config.getSessionDir(legacyId);
8485
fs.mkdirSync(sessionDir, { recursive: true });
8586
const metadataPath = path.join(sessionDir, "metadata.json");
8687
const existingMetadata = {
87-
id: workspaceId,
88-
name: "my-feature",
88+
id: legacyId,
89+
name: workspaceName,
8990
projectName: "project",
90-
workspacePath: workspacePath,
91+
projectPath: projectPath,
9192
createdAt: "2025-01-01T00:00:00.000Z",
9293
};
9394
fs.writeFileSync(metadataPath, JSON.stringify(existingMetadata));
9495

95-
// Add workspace to config
96+
// Add workspace to config (without id/name, simulating legacy format)
9697
config.editConfig((cfg) => {
9798
cfg.projects.set(projectPath, {
9899
workspaces: [{ path: workspacePath }],
@@ -105,8 +106,8 @@ describe("Config", () => {
105106

106107
expect(allMetadata).toHaveLength(1);
107108
const metadata = allMetadata[0];
108-
expect(metadata.id).toBe(workspaceId);
109-
expect(metadata.name).toBe("my-feature");
109+
expect(metadata.id).toBe(legacyId);
110+
expect(metadata.name).toBe(workspaceName);
110111
expect(metadata.createdAt).toBe("2025-01-01T00:00:00.000Z");
111112

112113
// Verify metadata was migrated to config
@@ -115,8 +116,8 @@ describe("Config", () => {
115116
expect(projectConfig).toBeDefined();
116117
expect(projectConfig!.workspaces).toHaveLength(1);
117118
const workspace = projectConfig!.workspaces[0];
118-
expect(workspace.id).toBe(workspaceId);
119-
expect(workspace.name).toBe("my-feature");
119+
expect(workspace.id).toBe(legacyId);
120+
expect(workspace.name).toBe(workspaceName);
120121
expect(workspace.createdAt).toBe("2025-01-01T00:00:00.000Z");
121122
});
122123
});

src/config.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -134,18 +134,15 @@ export class Config {
134134
}
135135

136136
/**
137-
* Compute both workspace paths from metadata.
138-
* Now both paths are the same (directory uses workspace name).
137+
* Compute workspace path from metadata.
138+
* Directory uses workspace name (e.g., ~/.cmux/src/project/workspace-name).
139139
*/
140140
getWorkspacePaths(metadata: WorkspaceMetadata): {
141-
/** Actual worktree path with name (for terminal/operations) */
142-
stableWorkspacePath: string;
143-
/** Same as stableWorkspacePath (no longer a symlink) */
141+
/** Worktree path (uses workspace name as directory) */
144142
namedWorkspacePath: string;
145143
} {
146144
const path = this.getWorkspacePath(metadata.projectPath, metadata.name);
147145
return {
148-
stableWorkspacePath: path,
149146
namedWorkspacePath: path,
150147
};
151148
}
@@ -159,10 +156,8 @@ export class Config {
159156
workspacePath: string,
160157
_projectPath: string
161158
): FrontendWorkspaceMetadata {
162-
// Both paths are the same now (directory uses workspace name)
163159
return {
164160
...metadata,
165-
stableWorkspacePath: workspacePath,
166161
namedWorkspacePath: workspacePath,
167162
};
168163
}

src/stores/GitStatusStore.test.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ describe("GitStatusStore", () => {
7373
name: "main",
7474
projectName: "test-project",
7575
projectPath: "/home/user/test-project",
76-
stableWorkspacePath: "/home/user/.cmux/src/test-project/main",
7776
namedWorkspacePath: "/home/user/.cmux/src/test-project/main",
7877
},
7978
],
@@ -95,7 +94,6 @@ describe("GitStatusStore", () => {
9594
name: "main",
9695
projectName: "test-project",
9796
projectPath: "/home/user/test-project",
98-
stableWorkspacePath: "/home/user/.cmux/src/test-project/main",
9997
namedWorkspacePath: "/home/user/.cmux/src/test-project/main",
10098
},
10199
],
@@ -106,7 +104,6 @@ describe("GitStatusStore", () => {
106104
name: "feature",
107105
projectName: "test-project",
108106
projectPath: "/home/user/test-project",
109-
stableWorkspacePath: "/home/user/.cmux/src/test-project/feature",
110107
namedWorkspacePath: "/home/user/.cmux/src/test-project/feature",
111108
},
112109
],
@@ -129,7 +126,6 @@ describe("GitStatusStore", () => {
129126
name: "main",
130127
projectName: "test-project",
131128
projectPath: "/home/user/test-project",
132-
stableWorkspacePath: "/home/user/.cmux/src/test-project/main",
133129
namedWorkspacePath: "/home/user/.cmux/src/test-project/main",
134130
},
135131
],
@@ -154,7 +150,6 @@ describe("GitStatusStore", () => {
154150
name: "main",
155151
projectName: "test-project",
156152
projectPath: "/home/user/test-project",
157-
stableWorkspacePath: "/home/user/.cmux/src/test-project/main",
158153
namedWorkspacePath: "/home/user/.cmux/src/test-project/main",
159154
},
160155
],
@@ -180,7 +175,6 @@ describe("GitStatusStore", () => {
180175
name: "main",
181176
projectName: "test-project",
182177
projectPath: "/home/user/test-project",
183-
stableWorkspacePath: "/home/user/.cmux/src/test-project/main",
184178
namedWorkspacePath: "/home/user/.cmux/src/test-project/main",
185179
},
186180
],
@@ -210,7 +204,6 @@ describe("GitStatusStore", () => {
210204
name: "main",
211205
projectName: "test-project",
212206
projectPath: "/home/user/test-project",
213-
stableWorkspacePath: "/home/user/.cmux/src/test-project/main",
214207
namedWorkspacePath: "/home/user/.cmux/src/test-project/main",
215208
},
216209
],
@@ -238,7 +231,6 @@ describe("GitStatusStore", () => {
238231
name: "main",
239232
projectName: "test-project",
240233
projectPath: "/home/user/test-project",
241-
stableWorkspacePath: "/home/user/.cmux/src/test-project/main",
242234
namedWorkspacePath: "/home/user/.cmux/src/test-project/main",
243235
},
244236
],
@@ -267,7 +259,6 @@ describe("GitStatusStore", () => {
267259
name: "main",
268260
projectName: "test-project",
269261
projectPath: "/home/user/test-project",
270-
stableWorkspacePath: "/home/user/.cmux/src/test-project/main",
271262
namedWorkspacePath: "/home/user/.cmux/src/test-project/main",
272263
},
273264
],

src/stores/WorkspaceStore.test.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ describe("WorkspaceStore", () => {
6767
name: "test-workspace",
6868
projectName: "test-project",
6969
projectPath: "/test/project",
70-
stableWorkspacePath: "/test/project/test-workspace",
7170
namedWorkspacePath: "/test/project/test-workspace",
7271
};
7372

@@ -95,7 +94,6 @@ describe("WorkspaceStore", () => {
9594
name: "test-workspace",
9695
projectName: "test-project",
9796
projectPath: "/test/project",
98-
stableWorkspacePath: "/test/project/test-workspace",
9997
namedWorkspacePath: "/test/project/test-workspace",
10098
};
10199

@@ -118,7 +116,6 @@ describe("WorkspaceStore", () => {
118116
name: "workspace-1",
119117
projectName: "project-1",
120118
projectPath: "/project-1",
121-
stableWorkspacePath: "/path/1",
122119
namedWorkspacePath: "/path/1",
123120
};
124121

@@ -137,7 +134,6 @@ describe("WorkspaceStore", () => {
137134
name: "workspace-1",
138135
projectName: "project-1",
139136
projectPath: "/project-1",
140-
stableWorkspacePath: "/path/1",
141137
namedWorkspacePath: "/path/1",
142138
};
143139

@@ -200,7 +196,6 @@ describe("WorkspaceStore", () => {
200196
name: "test-workspace",
201197
projectName: "test-project",
202198
projectPath: "/test/project",
203-
stableWorkspacePath: "/test/project/test-workspace",
204199
namedWorkspacePath: "/test/project/test-workspace",
205200
};
206201

@@ -245,7 +240,6 @@ describe("WorkspaceStore", () => {
245240
name: "test-workspace",
246241
projectName: "test-project",
247242
projectPath: "/test/project",
248-
stableWorkspacePath: "/test/project/test-workspace",
249243
namedWorkspacePath: "/test/project/test-workspace",
250244
};
251245
store.addWorkspace(metadata);
@@ -297,7 +291,6 @@ describe("WorkspaceStore", () => {
297291
name: "test-workspace",
298292
projectName: "test-project",
299293
projectPath: "/test/project",
300-
stableWorkspacePath: "/test/project/test-workspace",
301294
namedWorkspacePath: "/test/project/test-workspace",
302295
};
303296
store.addWorkspace(metadata);
@@ -336,7 +329,6 @@ describe("WorkspaceStore", () => {
336329
name: "test-workspace",
337330
projectName: "test-project",
338331
projectPath: "/test/project",
339-
stableWorkspacePath: "/test/project/test-workspace",
340332
namedWorkspacePath: "/test/project/test-workspace",
341333
};
342334
store.addWorkspace(metadata);
@@ -374,7 +366,6 @@ describe("WorkspaceStore", () => {
374366
name: "test-workspace",
375367
projectName: "test-project",
376368
projectPath: "/test/project",
377-
stableWorkspacePath: "/test/project/test-workspace",
378369
namedWorkspacePath: "/test/project/test-workspace",
379370
};
380371
store.addWorkspace(metadata);
@@ -398,7 +389,6 @@ describe("WorkspaceStore", () => {
398389
name: "test-workspace",
399390
projectName: "test-project",
400391
projectPath: "/test/project",
401-
stableWorkspacePath: "/test/project/test-workspace",
402392
namedWorkspacePath: "/test/project/test-workspace",
403393
};
404394
store.addWorkspace(metadata);
@@ -427,7 +417,6 @@ describe("WorkspaceStore", () => {
427417
name: "test-workspace",
428418
projectName: "test-project",
429419
projectPath: "/test/project",
430-
stableWorkspacePath: "/test/project/test-workspace",
431420
namedWorkspacePath: "/test/project/test-workspace",
432421
};
433422
store.addWorkspace(metadata);
@@ -474,15 +463,13 @@ describe("WorkspaceStore", () => {
474463
name: "workspace-1",
475464
projectName: "project-1",
476465
projectPath: "/project-1",
477-
stableWorkspacePath: "/path/1",
478466
namedWorkspacePath: "/path/1",
479467
};
480468
const metadata2: FrontendWorkspaceMetadata = {
481469
id: "workspace-2",
482470
name: "workspace-2",
483471
projectName: "project-2",
484472
projectPath: "/project-2",
485-
stableWorkspacePath: "/path/2",
486473
namedWorkspacePath: "/path/2",
487474
};
488475

@@ -502,7 +489,6 @@ describe("WorkspaceStore", () => {
502489
name: "test-workspace",
503490
projectName: "test-project",
504491
projectPath: "/test/project",
505-
stableWorkspacePath: "/test/project/test-workspace",
506492
namedWorkspacePath: "/test/project/test-workspace",
507493
};
508494
store.addWorkspace(metadata);

src/types/workspace.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,7 @@ export interface GitStatus {
6767
* Follows naming convention: Backend types vs Frontend types.
6868
*/
6969
export interface FrontendWorkspaceMetadata extends WorkspaceMetadata {
70-
/** Actual worktree path with stable ID (for terminal/operations) */
71-
stableWorkspacePath: string;
72-
/** User-friendly symlink path with name (for display) */
70+
/** Worktree path (uses workspace name as directory) */
7371
namedWorkspacePath: string;
7472
}
7573

src/utils/commands/sources.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,13 @@ const mk = (over: Partial<Parameters<typeof buildCoreSources>[0]> = {}) => {
1313
name: "feat-x",
1414
projectName: "a",
1515
projectPath: "/repo/a",
16-
stableWorkspacePath: "/repo/a/feat-x",
1716
namedWorkspacePath: "/repo/a/feat-x",
1817
});
1918
workspaceMetadata.set("w2", {
2019
id: "w2",
2120
name: "feat-y",
2221
projectName: "a",
2322
projectPath: "/repo/a",
24-
stableWorkspacePath: "/repo/a/feat-y",
2523
namedWorkspacePath: "/repo/a/feat-y",
2624
});
2725
const params: Parameters<typeof buildCoreSources>[0] = {

tests/ipcMain/removeWorkspace.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ describeIntegration("IpcMain remove workspace integration tests", () => {
3131
}
3232

3333
const { metadata } = createResult;
34-
const workspacePath = metadata.stableWorkspacePath;
34+
const workspacePath = metadata.namedWorkspacePath;
3535

3636
// Verify the worktree exists
3737
const worktreeExistsBefore = await fs
@@ -120,7 +120,7 @@ describeIntegration("IpcMain remove workspace integration tests", () => {
120120
}
121121

122122
const { metadata } = createResult;
123-
const workspacePath = metadata.stableWorkspacePath;
123+
const workspacePath = metadata.namedWorkspacePath;
124124

125125
// Manually delete the worktree directory (simulating external deletion)
126126
await fs.rm(workspacePath, { recursive: true, force: true });
@@ -174,7 +174,7 @@ describeIntegration("IpcMain remove workspace integration tests", () => {
174174
}
175175

176176
const { metadata } = createResult;
177-
const workspacePath = metadata.stableWorkspacePath;
177+
const workspacePath = metadata.namedWorkspacePath;
178178

179179
// Initialize submodule in the worktree
180180
const { exec } = await import("child_process");
@@ -228,7 +228,7 @@ describeIntegration("IpcMain remove workspace integration tests", () => {
228228
}
229229

230230
const { metadata } = createResult;
231-
const workspacePath = metadata.stableWorkspacePath;
231+
const workspacePath = metadata.namedWorkspacePath;
232232

233233
// Initialize submodule in the worktree
234234
const { exec } = await import("child_process");

tests/ipcMain/setup.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ export async function setupWorkspace(
183183
throw new Error("Workspace ID not returned from creation");
184184
}
185185

186-
if (!createResult.metadata.stableWorkspacePath) {
186+
if (!createResult.metadata.namedWorkspacePath) {
187187
await cleanupTempGitRepo(tempGitRepo);
188188
throw new Error("Workspace path not returned from creation");
189189
}
@@ -199,7 +199,7 @@ export async function setupWorkspace(
199199
return {
200200
env,
201201
workspaceId: createResult.metadata.id,
202-
workspacePath: createResult.metadata.stableWorkspacePath,
202+
workspacePath: createResult.metadata.namedWorkspacePath,
203203
branchName,
204204
tempGitRepo,
205205
cleanup,
@@ -237,7 +237,7 @@ export async function setupWorkspaceWithoutProvider(branchPrefix?: string): Prom
237237
throw new Error("Workspace ID not returned from creation");
238238
}
239239

240-
if (!createResult.metadata.stableWorkspacePath) {
240+
if (!createResult.metadata.namedWorkspacePath) {
241241
await cleanupTempGitRepo(tempGitRepo);
242242
throw new Error("Workspace path not returned from creation");
243243
}
@@ -252,7 +252,7 @@ export async function setupWorkspaceWithoutProvider(branchPrefix?: string): Prom
252252
return {
253253
env,
254254
workspaceId: createResult.metadata.id,
255-
workspacePath: createResult.metadata.stableWorkspacePath,
255+
workspacePath: createResult.metadata.namedWorkspacePath,
256256
branchName,
257257
tempGitRepo,
258258
cleanup,

0 commit comments

Comments
 (0)