diff --git a/supacode/Clients/Workspace/WorkspaceClient.swift b/supacode/Clients/Workspace/WorkspaceClient.swift index 317c1e310..f5adcea9f 100644 --- a/supacode/Clients/Workspace/WorkspaceClient.swift +++ b/supacode/Clients/Workspace/WorkspaceClient.swift @@ -75,8 +75,12 @@ private func performOpenWorktreeAction( ) return } + var targetURL = worktree.workingDirectory + if case .xcode = action { + targetURL = XcodeProjectLocator.findProject(in: worktree.workingDirectory) ?? worktree.workingDirectory + } NSWorkspace.shared.open( - [worktree.workingDirectory], + [targetURL], withApplicationAt: appURL, configuration: .init() ) { _, error in @@ -94,3 +98,68 @@ private func performOpenWorktreeAction( } } } + +private enum XcodeProjectLocator { + private static let skippedDirectoryNames = Set([ + ".build", + ".dart_tool", + ".expo", + ".expo-shared", + ".git", + ".gradle", + ".pnpm-store", + ".swiftpm", + ".symlinks", + ".yarn", + "Carthage", + "DerivedData", + "Pods", + "build", + "node_modules", + ]) + + static func findProject(in directory: URL, maxDepth: Int = 5) -> URL? { + var directories = [directory.standardizedFileURL] + + for _ in 0.. [URL] { + ((try? FileManager.default.contentsOfDirectory( + at: directory, + includingPropertiesForKeys: [.isDirectoryKey], + options: [] + )) ?? []) + .map(\.standardizedFileURL) + .sorted(by: { $0.path < $1.path }) + } +}