Skip to content

Commit 1f62132

Browse files
committed
🤖 Fix lint errors from workspace rename changes
1 parent f9f1c9e commit 1f62132

File tree

10 files changed

+132
-70
lines changed

10 files changed

+132
-70
lines changed

src/App.tsx

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,17 @@ function AppInner() {
166166
[setProjects]
167167
);
168168

169-
const { workspaceMetadata, loading: metadataLoading, createWorkspace, removeWorkspace, renameWorkspace } =
170-
useWorkspaceManagement({
171-
selectedWorkspace,
172-
onProjectsUpdate: handleProjectsUpdate,
173-
onSelectedWorkspaceUpdate: setSelectedWorkspace,
174-
});
169+
const {
170+
workspaceMetadata,
171+
loading: metadataLoading,
172+
createWorkspace,
173+
removeWorkspace,
174+
renameWorkspace,
175+
} = useWorkspaceManagement({
176+
selectedWorkspace,
177+
onProjectsUpdate: handleProjectsUpdate,
178+
onSelectedWorkspaceUpdate: setSelectedWorkspace,
179+
});
175180

176181
// NEW: Sync workspace metadata with the stores
177182
const workspaceStore = useWorkspaceStoreRaw();
@@ -226,11 +231,11 @@ function AppInner() {
226231
// Restore workspace from URL on mount (if valid)
227232
// This effect runs once on mount to restore from hash, which takes priority over localStorage
228233
const [hasRestoredFromHash, setHasRestoredFromHash] = useState(false);
229-
234+
230235
useEffect(() => {
231236
// Only run once
232237
if (hasRestoredFromHash) return;
233-
238+
234239
// Wait for metadata to finish loading
235240
if (metadataLoading) return;
236241

@@ -251,18 +256,18 @@ function AppInner() {
251256
});
252257
}
253258
}
254-
259+
255260
setHasRestoredFromHash(true);
256261
}, [metadataLoading, workspaceMetadata, hasRestoredFromHash, setSelectedWorkspace]);
257262

258263
// Validate selected workspace exists and has all required fields
259264
useEffect(() => {
260265
// Don't validate until metadata is loaded
261266
if (metadataLoading) return;
262-
267+
263268
if (selectedWorkspace) {
264269
const metadata = workspaceMetadata.get(selectedWorkspace.workspaceId);
265-
270+
266271
if (!metadata) {
267272
// Workspace was deleted
268273
console.warn(
@@ -274,9 +279,7 @@ function AppInner() {
274279
}
275280
} else if (!selectedWorkspace.namedWorkspacePath && metadata.namedWorkspacePath) {
276281
// Old localStorage entry missing namedWorkspacePath - update it once
277-
console.log(
278-
`Updating workspace ${selectedWorkspace.workspaceId} with missing fields`
279-
);
282+
console.log(`Updating workspace ${selectedWorkspace.workspaceId} with missing fields`);
280283
setSelectedWorkspace({
281284
workspaceId: metadata.id,
282285
projectPath: metadata.projectPath,
@@ -287,13 +290,16 @@ function AppInner() {
287290
}
288291
}, [metadataLoading, selectedWorkspace, workspaceMetadata, setSelectedWorkspace]);
289292

290-
const openWorkspaceInTerminal = useCallback((workspaceId: string) => {
291-
// Look up workspace metadata to get the named path (user-friendly symlink)
292-
const metadata = workspaceMetadata.get(workspaceId);
293-
if (metadata) {
294-
void window.api.workspace.openTerminal(metadata.namedWorkspacePath);
295-
}
296-
}, [workspaceMetadata]);
293+
const openWorkspaceInTerminal = useCallback(
294+
(workspaceId: string) => {
295+
// Look up workspace metadata to get the named path (user-friendly symlink)
296+
const metadata = workspaceMetadata.get(workspaceId);
297+
if (metadata) {
298+
void window.api.workspace.openTerminal(metadata.namedWorkspacePath);
299+
}
300+
},
301+
[workspaceMetadata]
302+
);
297303

298304
const handleRemoveProject = useCallback(
299305
async (path: string) => {
@@ -682,7 +688,10 @@ function AppInner() {
682688
key={selectedWorkspace.workspaceId}
683689
workspaceId={selectedWorkspace.workspaceId}
684690
projectName={selectedWorkspace.projectName}
685-
branch={selectedWorkspace.namedWorkspacePath?.split("/").pop() ?? selectedWorkspace.workspaceId}
691+
branch={
692+
selectedWorkspace.namedWorkspacePath?.split("/").pop() ??
693+
selectedWorkspace.workspaceId
694+
}
686695
namedWorkspacePath={selectedWorkspace.namedWorkspacePath ?? ""}
687696
/>
688697
</ErrorBoundary>

src/config.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ describe("Config", () => {
3535
});
3636
});
3737

38-
39-
4038
describe("getAllWorkspaceMetadata with migration", () => {
4139
it("should migrate legacy workspace without metadata file", () => {
4240
const projectPath = "/fake/project";

src/config.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ export class Config {
157157
private addPathsToMetadata(
158158
metadata: WorkspaceMetadata,
159159
workspacePath: string,
160-
projectPath: string
160+
_projectPath: string
161161
): FrontendWorkspaceMetadata {
162162
// Both paths are the same now (directory uses workspace name)
163163
return {
@@ -329,7 +329,9 @@ export class Config {
329329
workspace.createdAt = metadata.createdAt;
330330
configModified = true;
331331

332-
workspaceMetadata.push(this.addPathsToMetadata(metadata, workspace.path, projectPath));
332+
workspaceMetadata.push(
333+
this.addPathsToMetadata(metadata, workspace.path, projectPath)
334+
);
333335
metadataFound = true;
334336
}
335337
}

src/hooks/useWorkspaceManagement.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,15 @@ export function useWorkspaceManagement({
4646

4747
// Subscribe to metadata updates (for create/rename/delete operations)
4848
useEffect(() => {
49-
const unsubscribe = window.api.workspace.onMetadata((event: { workspaceId: string; metadata: FrontendWorkspaceMetadata }) => {
50-
setWorkspaceMetadata((prev) => {
51-
const updated = new Map(prev);
52-
updated.set(event.workspaceId, event.metadata);
53-
return updated;
54-
});
55-
});
49+
const unsubscribe = window.api.workspace.onMetadata(
50+
(event: { workspaceId: string; metadata: FrontendWorkspaceMetadata }) => {
51+
setWorkspaceMetadata((prev) => {
52+
const updated = new Map(prev);
53+
updated.set(event.workspaceId, event.metadata);
54+
return updated;
55+
});
56+
}
57+
);
5658

5759
return () => {
5860
unsubscribe();

src/services/agentSession.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ export class AgentSession {
151151
assert(trimmedWorkspacePath.length > 0, "workspacePath must not be empty");
152152

153153
const normalizedWorkspacePath = path.resolve(trimmedWorkspacePath);
154-
const existing = await this.aiService.getWorkspaceMetadata(this.workspaceId);
154+
const existing = this.aiService.getWorkspaceMetadata(this.workspaceId);
155155

156156
if (existing.success) {
157157
// Metadata already exists, verify workspace path matches

src/services/aiService.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { applyToolOutputRedaction } from "@/utils/messages/applyToolOutputRedact
77
import type { Result } from "@/types/result";
88
import { Ok, Err } from "@/types/result";
99
import type { WorkspaceMetadata } from "@/types/workspace";
10-
import { WorkspaceMetadataSchema } from "@/types/workspace";
10+
1111
import type { CmuxMessage, CmuxTextPart } from "@/types/message";
1212
import { createCmuxMessage } from "@/types/message";
1313
import type { Config } from "@/config";
@@ -180,7 +180,7 @@ export class AIService extends EventEmitter {
180180
return this.mockModeEnabled;
181181
}
182182

183-
async getWorkspaceMetadata(workspaceId: string): Promise<Result<WorkspaceMetadata>> {
183+
getWorkspaceMetadata(workspaceId: string): Result<WorkspaceMetadata> {
184184
try {
185185
// Get all workspace metadata (which includes migration logic)
186186
// This ensures we always get complete metadata with all required fields
@@ -510,7 +510,7 @@ export class AIService extends EventEmitter {
510510
}
511511

512512
// Get workspace metadata to retrieve workspace path
513-
const metadataResult = await this.getWorkspaceMetadata(workspaceId);
513+
const metadataResult = this.getWorkspaceMetadata(workspaceId);
514514
if (!metadataResult.success) {
515515
return Err({ type: "unknown", raw: metadataResult.error });
516516
}
@@ -522,7 +522,7 @@ export class AIService extends EventEmitter {
522522
if (!workspace) {
523523
return Err({ type: "unknown", raw: `Workspace ${workspaceId} not found in config` });
524524
}
525-
525+
526526
// Get workspace path (directory name uses workspace name)
527527
const workspacePath = this.config.getWorkspacePath(metadata.projectPath, metadata.name);
528528

src/services/gitService.test.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ describe("removeWorktreeSafe", () => {
4949

5050
test("should instantly remove clean worktree via rename", async () => {
5151
// Create a worktree
52-
const result = await createWorktree(mockConfig, repoPath, "test-branch", { trunkBranch: "main" });
52+
const result = await createWorktree(mockConfig, repoPath, "test-branch", {
53+
trunkBranch: "main",
54+
});
5355
expect(result.success).toBe(true);
5456
const worktreePath = result.path!;
5557

@@ -80,7 +82,9 @@ describe("removeWorktreeSafe", () => {
8082

8183
test("should block removal of dirty worktree", async () => {
8284
// Create a worktree
83-
const result = await createWorktree(mockConfig, repoPath, "dirty-branch", { trunkBranch: "main" });
85+
const result = await createWorktree(mockConfig, repoPath, "dirty-branch", {
86+
trunkBranch: "main",
87+
});
8488
expect(result.success).toBe(true);
8589
const worktreePath = result.path!;
8690

@@ -107,7 +111,9 @@ describe("removeWorktreeSafe", () => {
107111

108112
test("should handle already-deleted worktree gracefully", async () => {
109113
// Create a worktree
110-
const result = await createWorktree(mockConfig, repoPath, "temp-branch", { trunkBranch: "main" });
114+
const result = await createWorktree(mockConfig, repoPath, "temp-branch", {
115+
trunkBranch: "main",
116+
});
111117
expect(result.success).toBe(true);
112118
const worktreePath = result.path!;
113119

@@ -122,7 +128,9 @@ describe("removeWorktreeSafe", () => {
122128

123129
test("should remove clean worktree with staged changes using git", async () => {
124130
// Create a worktree
125-
const result = await createWorktree(mockConfig, repoPath, "staged-branch", { trunkBranch: "main" });
131+
const result = await createWorktree(mockConfig, repoPath, "staged-branch", {
132+
trunkBranch: "main",
133+
});
126134
expect(result.success).toBe(true);
127135
const worktreePath = result.path!;
128136

@@ -142,7 +150,9 @@ describe("removeWorktreeSafe", () => {
142150

143151
test("should call onBackgroundDelete callback on errors", async () => {
144152
// Create a worktree
145-
const result = await createWorktree(mockConfig, repoPath, "callback-branch", { trunkBranch: "main" });
153+
const result = await createWorktree(mockConfig, repoPath, "callback-branch", {
154+
trunkBranch: "main",
155+
});
146156
expect(result.success).toBe(true);
147157
const worktreePath = result.path!;
148158

@@ -184,15 +194,19 @@ describe("isWorktreeClean", () => {
184194
});
185195

186196
test("should return true for clean worktree", async () => {
187-
const result = await createWorktree(mockConfig, repoPath, "clean-check", { trunkBranch: "main" });
197+
const result = await createWorktree(mockConfig, repoPath, "clean-check", {
198+
trunkBranch: "main",
199+
});
188200
expect(result.success).toBe(true);
189201

190202
const isClean = await isWorktreeClean(result.path!);
191203
expect(isClean).toBe(true);
192204
});
193205

194206
test("should return false for worktree with uncommitted changes", async () => {
195-
const result = await createWorktree(mockConfig, repoPath, "dirty-check", { trunkBranch: "main" });
207+
const result = await createWorktree(mockConfig, repoPath, "dirty-check", {
208+
trunkBranch: "main",
209+
});
196210
expect(result.success).toBe(true);
197211
const worktreePath = result.path!;
198212

src/services/ipcMain.ts

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import { createBashTool } from "@/services/tools/bash";
2525
import type { BashToolResult } from "@/types/tools";
2626
import { secretsToRecord } from "@/types/secrets";
2727
import { DisposableTempDir } from "@/services/tempDir";
28-
import type { WorkspaceMetadata, FrontendWorkspaceMetadata } from "@/types/workspace";
2928

3029
/**
3130
* IpcMain - Manages all IPC handlers and service coordination
@@ -122,8 +121,6 @@ export class IpcMain {
122121
this.sessions.delete(workspaceId);
123122
}
124123

125-
126-
127124
/**
128125
* Register all IPC handlers and setup event forwarding
129126
* @param ipcMain - Electron's ipcMain module
@@ -267,7 +264,7 @@ export class IpcMain {
267264

268265
ipcMain.handle(
269266
IPC_CHANNELS.WORKSPACE_RENAME,
270-
async (_event, workspaceId: string, newName: string) => {
267+
(_event, workspaceId: string, newName: string) => {
271268
try {
272269
// Validate workspace name
273270
const validation = validateWorkspaceName(newName);
@@ -276,7 +273,7 @@ export class IpcMain {
276273
}
277274

278275
// Get current metadata
279-
const metadataResult = await this.aiService.getWorkspaceMetadata(workspaceId);
276+
const metadataResult = this.aiService.getWorkspaceMetadata(workspaceId);
280277
if (!metadataResult.success) {
281278
return Err(`Failed to get workspace metadata: ${metadataResult.error}`);
282279
}
@@ -305,8 +302,6 @@ export class IpcMain {
305302
const { projectPath, workspacePath } = workspace;
306303

307304
// Compute new path (based on name)
308-
const projectName =
309-
projectPath.split("/").pop() ?? projectPath.split("\\").pop() ?? "unknown";
310305
const oldPath = workspacePath;
311306
const newPath = this.config.getWorkspacePath(projectPath, newName);
312307

@@ -374,7 +369,7 @@ export class IpcMain {
374369
}
375370
});
376371

377-
ipcMain.handle(IPC_CHANNELS.WORKSPACE_GET_INFO, async (_event, workspaceId: string) => {
372+
ipcMain.handle(IPC_CHANNELS.WORKSPACE_GET_INFO, (_event, workspaceId: string) => {
378373
// Get complete metadata from config (includes paths)
379374
const allMetadata = this.config.getAllWorkspaceMetadata();
380375
return allMetadata.find((m) => m.id === workspaceId) ?? null;
@@ -573,7 +568,7 @@ export class IpcMain {
573568
) => {
574569
try {
575570
// Get workspace metadata
576-
const metadataResult = await this.aiService.getWorkspaceMetadata(workspaceId);
571+
const metadataResult = this.aiService.getWorkspaceMetadata(workspaceId);
577572
if (!metadataResult.success) {
578573
return Err(`Failed to get workspace metadata: ${metadataResult.error}`);
579574
}
@@ -587,7 +582,7 @@ export class IpcMain {
587582
if (!workspace) {
588583
return Err(`Workspace ${workspaceId} not found in config`);
589584
}
590-
585+
591586
// Get workspace path (directory name uses workspace name)
592587
const namedPath = this.config.getWorkspacePath(metadata.projectPath, metadata.name);
593588

@@ -714,15 +709,13 @@ export class IpcMain {
714709
): Promise<{ success: boolean; error?: string }> {
715710
try {
716711
// Get workspace metadata
717-
const metadataResult = await this.aiService.getWorkspaceMetadata(workspaceId);
712+
const metadataResult = this.aiService.getWorkspaceMetadata(workspaceId);
718713
if (!metadataResult.success) {
719714
// If metadata doesn't exist, workspace is already gone - consider it success
720715
log.info(`Workspace ${workspaceId} metadata not found, considering removal successful`);
721716
return { success: true };
722717
}
723718

724-
const metadata = metadataResult.data;
725-
726719
// Get actual workspace path from config (handles both legacy and new format)
727720
const workspace = this.config.findWorkspace(workspaceId);
728721
if (!workspace) {
@@ -807,7 +800,7 @@ export class IpcMain {
807800
// because the worktree might be deleted (so getMainWorktreeFromWorktree fails)
808801
const projectsConfig = this.config.loadConfigOrDefault();
809802
let configUpdated = false;
810-
for (const [projectPath, projectConfig] of projectsConfig.projects.entries()) {
803+
for (const [_projectPath, projectConfig] of projectsConfig.projects.entries()) {
811804
const initialCount = projectConfig.workspaces.length;
812805
projectConfig.workspaces = projectConfig.workspaces.filter((w) => w.path !== workspacePath);
813806
if (projectConfig.workspaces.length < initialCount) {

src/utils/commands/sources.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ export function buildCoreSources(p: BuildSourcesParams): Array<() => CommandActi
154154
}
155155

156156
// Remove current workspace (rename action intentionally omitted until we add a proper modal)
157-
if (selected && selected.namedWorkspacePath) {
157+
if (selected?.namedWorkspacePath) {
158158
const workspaceDisplayName = `${selected.projectName}/${selected.namedWorkspacePath.split("/").pop() ?? selected.namedWorkspacePath}`;
159159
list.push({
160160
id: "ws:open-terminal-current",

0 commit comments

Comments
 (0)