import Foundation#if canImport(Darwin)import Darwin#elseimport Glibc#endif public enum PathPurpose: Hashable, Sendable { case rpc case tty case nodeTooling} public struct PathDebugSnapshot: Equatable, Sendable { public let codexBinary: String? public let claudeBinary: String? public let geminiBinary: String? public let effectivePATH: String public let loginShellPATH: String? public static let empty = PathDebugSnapshot( codexBinary: nil, claudeBinary: nil, geminiBinary: nil, effectivePATH: "", loginShellPATH: nil) public init( codexBinary: String?, claudeBinary: String?, geminiBinary: String? = nil, effectivePATH: String, loginShellPATH: String?) { self.codexBinary = codexBinary self.claudeBinary = claudeBinary self.geminiBinary = geminiBinary self.effectivePATH = effectivePATH self.loginShellPATH = loginShellPATH }} public enum BinaryLocator { public static func resolveClaudeBinary( env: [String: String] = ProcessInfo.processInfo.environment, loginPATH: [String]? = LoginShellPathCache.shared.current, commandV: (String, String?, TimeInterval, FileManager) -> String? = ShellCommandLocator.commandV, aliasResolver: (String, String?, TimeInterval, FileManager, String) -> String? = ShellCommandLocator .resolveAlias, fileManager: FileManager = .default, home: String = NSHomeDirectory()) -> String? { self.resolveBinary( name: "claude", overrideKey: "CLAUDE_CLI_PATH", env: env, loginPATH: loginPATH, commandV: commandV, aliasResolver: aliasResolver, wellKnownPaths: self.claudeWellKnownPaths(home: home), fileManager: fileManager, home: home) } /// Well-known installation paths for the Claude CLI binary. /// Covers Anthropic's native installer (`~/.local/bin`), the `claude migrate-installer` /// self-updating location (`~/.claude/local`), the legacy per-user installer /// (`~/.claude/bin`), Homebrew, and the macOS Terminal installer (cmux.app). static func claudeWellKnownPaths(home: String) -> [String] { [ "\(home)/.local/bin/claude", "\(home)/.claude/local/claude", "\(home)/.claude/bin/claude", "/opt/homebrew/bin/claude", "/usr/local/bin/claude", "/Applications/cmux.app/Contents/Resources/bin/claude", ] } public static func resolveCodexBinary( env: [String: String] = ProcessInfo.processInfo.environment, loginPATH: [String]? = LoginShellPathCache.shared.current, commandV: (String, String?, TimeInterval, FileManager) -> String? = ShellCommandLocator.commandV, aliasResolver: (String, String?, TimeInterval, FileManager, String) -> String? = ShellCommandLocator .resolveAlias, launchCandidateFilter: (String, FileManager) -> Bool = CodexLaunchPreflight.isLaunchCandidateAllowed, fileManager: FileManager = .default, home: String = NSHomeDirectory()) -> String? { self.resolveBinary( name: "codex", overrideKey: "CODEX_CLI_PATH", env: env, loginPATH: loginPATH, commandV: commandV, aliasResolver: aliasResolver, wellKnownPaths: self.codexWellKnownPaths(home: home), launchCandidateFilter: launchCandidateFilter, fileManager: fileManager, home: home) } /// Well-known installation paths for the signed Codex desktop app CLI. /// Keep these after PATH lookups, but use them as a safe fallback when a PATH shim is blocked. static func codexWellKnownPaths(home: String) -> [String] { #if os(macOS) [ "\(home)/Applications/Codex.app/Contents/Resources/codex", "/Applications/Codex.app/Contents/Resources/codex", ] #else [] #endif } public static func resolveGeminiBinary( env: [String: String] = ProcessInfo.processInfo.environment, loginPATH: [String]? = LoginShellPathCache.shared.current, commandV: (String, String?, TimeInterval, FileManager) -> String? = ShellCommandLocator.commandV, aliasResolver: (String, String?, TimeInterval, FileManager, String) -> String? = ShellCommandLocator .resolveAlias, fileManager: FileManager = .default, home: String = NSHomeDirectory()) -> String? { self.resolveBinary( name: "gemini", overrideKey: "GEMINI_CLI_PATH", env: env, loginPATH: loginPATH, commandV: commandV, aliasResolver: aliasResolver, fileManager: fileManager, home: home) } public static func resolveGrokBinary( env: [String: String] = ProcessInfo.processInfo.environment, loginPATH: [String]? = LoginShellPathCache.shared.current, commandV: (String, String?, TimeInterval, FileManager) -> String? = ShellCommandLocator.commandV, aliasResolver: (String, String?, TimeInterval, FileManager, String) -> String? = ShellCommandLocator .resolveAlias, fileManager: FileManager = .default, home: String = NSHomeDirectory()) -> String? { self.resolveBinary( name: "grok", overrideKey: "GROK_CLI_PATH", env: env, loginPATH: loginPATH, commandV: commandV, aliasResolver: aliasResolver, wellKnownPaths: self.grokWellKnownPaths(home: home), fileManager: fileManager, home: home) } /// Well-known install locations for the Grok Build CLI binary. /// Covers the installer's default (`~/.grok/bin/grok`) and the symlinks it sometimes /// creates into `~/.local/bin` and `/usr/local/bin`. static func grokWellKnownPaths(home: String) -> [String] { [ "\(home)/.grok/bin/grok", "\(home)/.local/bin/grok", "/usr/local/bin/grok", "/opt/homebrew/bin/grok", ] } public static func resolveAWSBinary( env: [String: String] = ProcessInfo.processInfo.environment, loginPATH: [String]? = LoginShellPathCache.shared.current, commandV: (String, String?, TimeInterval, FileManager) -> String? = ShellCommandLocator.commandV, aliasResolver: (String, String?, TimeInterval, FileManager, String) -> String? = ShellCommandLocator .resolveAlias, fileManager: FileManager = .default, home: String = NSHomeDirectory()) -> String? { self.resolveBinary( name: "aws", overrideKey: "AWS_CLI_PATH", env: env, loginPATH: loginPATH, commandV: commandV, aliasResolver: aliasResolver, wellKnownPaths: self.awsWellKnownPaths(home: home), fileManager: fileManager, home: home) } /// Well-known install locations for the AWS CLI v2 (`aws`). /// Covers Homebrew (Apple Silicon + Intel) and the per-user pip/uv install path. static func awsWellKnownPaths(home: String) -> [String] { [ "/opt/homebrew/bin/aws", "/usr/local/bin/aws", "\(home)/.local/bin/aws", ] } public static func resolveAuggieBinary( env: [String: String] = ProcessInfo.processInfo.environment, loginPATH: [String]? = LoginShellPathCache.shared.current, commandV: (String, String?, TimeInterval, FileManager) -> String? = ShellCommandLocator.commandV, aliasResolver: (String, String?, TimeInterval, FileManager, String) -> String? = ShellCommandLocator .resolveAlias, fileManager: FileManager = .default, home: String = NSHomeDirectory()) -> String? { self.resolveBinary( name: "auggie", overrideKey: "AUGGIE_CLI_PATH", env: env, loginPATH: loginPATH, commandV: commandV, aliasResolver: aliasResolver, fileManager: fileManager, home: home) } // swiftlint:disable function_parameter_count private static func resolveBinary( name: String, overrideKey: String, env: [String: String], loginPATH: [String]?, commandV: (String, String?, TimeInterval, FileManager) -> String?, aliasResolver: (String, String?, TimeInterval, FileManager, String) -> String?, wellKnownPaths: [String] = [], launchCandidateFilter: (String, FileManager) -> Bool = { _, _ in true }, fileManager: FileManager, home: String) -> String? { // swiftlint:enable function_parameter_count // 1) Explicit override if let override = env[overrideKey], fileManager.isExecutableFile(atPath: override) { return override } // 2) Login-shell PATH (captured once per launch) if let loginPATH, let pathHit = self.find( name, in: loginPATH, fileManager: fileManager, launchCandidateFilter: launchCandidateFilter) { return pathHit } // 3) Existing PATH if let existingPATH = env["PATH"], let pathHit = self.find( name, in: existingPATH.split(separator: ":").map(String.init), fileManager: fileManager, launchCandidateFilter: launchCandidateFilter) { return pathHit } // 4) Well-known installation paths (e.g. Homebrew, cmux.app bundle, ~/.claude/bin). // Prefer these before shell probing to avoid running interactive shell init for common installs. for candidate in wellKnownPaths where fileManager.isExecutableFile(atPath: candidate) && launchCandidateFilter(candidate, fileManager) { return candidate } // 5) Interactive login shell lookup (captures nvm/fnm/mise paths from .zshrc/.bashrc) if let shellHit = commandV(name, env["SHELL"], 2.0, fileManager), fileManager.isExecutableFile(atPath: shellHit), launchCandidateFilter(shellHit, fileManager) { return shellHit } // 5b) Alias fallback (login shell); only attempt after all standard lookups fail. if let aliasHit = aliasResolver(name, env["SHELL"], 2.0, fileManager, home), fileManager.isExecutableFile(atPath: aliasHit), launchCandidateFilter(aliasHit, fileManager) { return aliasHit } // 6) Minimal fallback let fallback = ["/usr/bin", "/bin", "/usr/sbin", "/sbin"] if let pathHit = self.find( name, in: fallback, fileManager: fileManager, launchCandidateFilter: launchCandidateFilter) { return pathHit } return nil } private static func find( _ binary: String, in paths: [String], fileManager: FileManager, launchCandidateFilter: (String, FileManager) -> Bool = { _, _ in true }) -> String? { for path in paths where !path.isEmpty { let candidate = "\(path.hasSuffix("/") ? String(path.dropLast()) : path)/\(binary)" if fileManager.isExecutableFile(atPath: candidate), launchCandidateFilter(candidate, fileManager) { return candidate } } return nil }} public enum CodexLaunchPreflight { public static func isLaunchCandidateAllowed(path: String, fileManager: FileManager = .default) -> Bool { #if os(macOS) self.isLaunchCandidateAllowed( path: path, fileManager: fileManager, hasExtendedAttribute: self.hasExtendedAttribute, spctlAssessment: { self.spctlAssessment(path: $0) }, isMachOExecutable: self.isMachOExecutable) #else _ = path _ = fileManager return true #endif } #if os(macOS) static func isLaunchCandidateAllowed( path: String, fileManager: FileManager, hasExtendedAttribute: (String, String) -> Bool, spctlAssessment: (String) -> String?, isMachOExecutable: (String) -> Bool) -> Bool { let realPath = URL(fileURLWithPath: path).resolvingSymlinksInPath().path let pathsToCheck = [path, realPath] + self.nativeCodexExecutableCandidates( for: realPath, fileManager: fileManager) for candidate in Set(pathsToCheck) where hasExtendedAttribute(candidate, "com.apple.malware") { return false } let hasQuarantine = Set(pathsToCheck).contains { hasExtendedAttribute($0, "com.apple.quarantine") } guard let native = pathsToCheck.first(where: isMachOExecutable) else { return !hasQuarantine } guard let assessment = spctlAssessment(native) else { return !hasQuarantine } return !self.isExplicitlyBlockedAssessment(assessment, path: native) } private static func nativeCodexExecutableCandidates(for path: String, fileManager: FileManager) -> [String] { let url = URL(fileURLWithPath: path) guard url.lastPathComponent == "codex.js" else { return [] } let packageRoot = url.deletingLastPathComponent().deletingLastPathComponent() return self.npmNativeCodexCandidates(packageRoot: packageRoot) .map(\.path) .filter { fileManager.isExecutableFile(atPath: $0) } } private static func npmNativeCodexCandidates(packageRoot: URL) -> [URL] { guard let target = self.darwinCodexTarget else { return [] } let optionalPackage = packageRoot .appendingPathComponent("node_modules") .appendingPathComponent("@openai") .appendingPathComponent(target.packageName) return [ optionalPackage, packageRoot, ].map { $0.appendingPathComponent("vendor") .appendingPathComponent(target.triple) .appendingPathComponent("codex") .appendingPathComponent("codex") } } private static var darwinCodexTarget: (packageName: String, triple: String)? { #if arch(arm64) ("codex-darwin-arm64", "aarch64-apple-darwin") #elseif arch(x86_64) ("codex-darwin-x64", "x86_64-apple-darwin") #else nil #endif } private static func hasExtendedAttribute(path: String, name: String) -> Bool { path.withCString { pathPointer in name.withCString { namePointer in getxattr(pathPointer, namePointer, nil, 0, 0, 0) >= 0 } } } private static func isMachOExecutable(path: String) -> Bool { guard let handle = try? FileHandle(forReadingFrom: URL(fileURLWithPath: path)) else { return false } defer { try? handle.close() } guard let data = try? handle.read(upToCount: 4), data.count == 4 else { return false } let bytes = [UInt8](data) return bytes == [0xFE, 0xED, 0xFA, 0xCE] || bytes == [0xCE, 0xFA, 0xED, 0xFE] || bytes == [0xFE, 0xED, 0xFA, 0xCF] || bytes == [0xCF, 0xFA, 0xED, 0xFE] || bytes == [0xCA, 0xFE, 0xBA, 0xBE] || bytes == [0xCA, 0xFE, 0xBA, 0xBF] } private static func spctlAssessment(path: String, timeout: TimeInterval = 2.0) -> String? { let spctlPath = "/usr/sbin/spctl" guard FileManager.default.isExecutableFile(atPath: spctlPath) else { return nil } let process = Process() process.executableURL = URL(fileURLWithPath: spctlPath) process.arguments = ["--assess", "--type", "execute", "--verbose=4", path] let output = Pipe() process.standardOutput = output process.standardError = output let finished = DispatchSemaphore(value: 0) process.terminationHandler = { _ in finished.signal() } do { try process.run() } catch { return nil } if finished.wait(timeout: .now() + timeout) != .success { process.terminate() return nil } let data = output.fileHandleForReading.readDataToEndOfFile() return String(data: data, encoding: .utf8) } private static func isExplicitlyBlockedAssessment(_ assessment: String, path: String) -> Bool { let lower = self.assessmentDiagnosticText(assessment, path: path).lowercased() if lower.contains("denied") || lower.contains("cssmerr_tp_cert_revoked") || lower.contains("revoked") || lower.contains("malware") || lower.contains("quarantine") { return true } if lower.contains("rejected") { return !lower.contains("code is valid but does not seem to be an app") } return false } private static func assessmentDiagnosticText(_ assessment: String, path: String) -> String { assessment .split(whereSeparator: \.isNewline) .enumerated() .compactMap { offset, line -> String? in var text = line.trimmingCharacters(in: .whitespacesAndNewlines) if offset == 0, text.hasPrefix("\(path):") { text = String(text.dropFirst(path.count + 1)) .trimmingCharacters(in: .whitespacesAndNewlines) } let lower = text.lowercased() guard !lower.hasPrefix("source="), !lower.hasPrefix("origin=") else { return nil } return text } .joined(separator: "\n") } #endif} public enum ShellCommandLocator { static func test_runShellCommand( shell: String, arguments: [String], timeout: TimeInterval) -> Data? { self.runShellCommand(shell: shell, arguments: arguments, timeout: timeout) } public static func commandV( _ tool: String, _ shell: String?, _ timeout: TimeInterval,Lines 1–500 of 1042. Load more
import Foundation #if canImport(Darwin) import Darwin #else import Glibc #endif public enum PathPurpose: Hashable, Sendable { case rpc case tty case nodeTooling } public struct PathDebugSnapshot: Equatable, Sendable { public let codexBinary: String? public let claudeBinary: String? public let geminiBinary: String? public let effectivePATH: String public let loginShellPATH: String? public static let empty = PathDebugSnapshot( codexBinary: nil, claudeBinary: nil, geminiBinary: nil, effectivePATH: "", loginShellPATH: nil) public init( codexBinary: String?, claudeBinary: String?, geminiBinary: String? = nil, effectivePATH: String, loginShellPATH: String?) { self.codexBinary = codexBinary self.claudeBinary = claudeBinary self.geminiBinary = geminiBinary self.effectivePATH = effectivePATH self.loginShellPATH = loginShellPATH } } public enum BinaryLocator { public static func resolveClaudeBinary( env: [String: String] = ProcessInfo.processInfo.environment, loginPATH: [String]? = LoginShellPathCache.shared.current, commandV: (String, String?, TimeInterval, FileManager) -> String? = ShellCommandLocator.commandV, aliasResolver: (String, String?, TimeInterval, FileManager, String) -> String? = ShellCommandLocator .resolveAlias, fileManager: FileManager = .default, home: String = NSHomeDirectory()) -> String? { self.resolveBinary( name: "claude", overrideKey: "CLAUDE_CLI_PATH", env: env, loginPATH: loginPATH, commandV: commandV, aliasResolver: aliasResolver, wellKnownPaths: self.claudeWellKnownPaths(home: home), fileManager: fileManager, home: home) } /// Well-known installation paths for the Claude CLI binary. /// Covers Anthropic's native installer (`~/.local/bin`), the `claude migrate-installer` /// self-updating location (`~/.claude/local`), the legacy per-user installer /// (`~/.claude/bin`), Homebrew, and the macOS Terminal installer (cmux.app). static func claudeWellKnownPaths(home: String) -> [String] { [ "\(home)/.local/bin/claude", "\(home)/.claude/local/claude", "\(home)/.claude/bin/claude", "/opt/homebrew/bin/claude", "/usr/local/bin/claude", "/Applications/cmux.app/Contents/Resources/bin/claude", ] } public static func resolveCodexBinary( env: [String: String] = ProcessInfo.processInfo.environment, loginPATH: [String]? = LoginShellPathCache.shared.current, commandV: (String, String?, TimeInterval, FileManager) -> String? = ShellCommandLocator.commandV, aliasResolver: (String, String?, TimeInterval, FileManager, String) -> String? = ShellCommandLocator .resolveAlias, launchCandidateFilter: (String, FileManager) -> Bool = CodexLaunchPreflight.isLaunchCandidateAllowed, fileManager: FileManager = .default, home: String = NSHomeDirectory()) -> String? { self.resolveBinary( name: "codex", overrideKey: "CODEX_CLI_PATH", env: env, loginPATH: loginPATH, commandV: commandV, aliasResolver: aliasResolver, wellKnownPaths: self.codexWellKnownPaths(home: home), launchCandidateFilter: launchCandidateFilter, fileManager: fileManager, home: home) } /// Well-known installation paths for the signed Codex desktop app CLI. /// Keep these after PATH lookups, but use them as a safe fallback when a PATH shim is blocked. static func codexWellKnownPaths(home: String) -> [String] { #if os(macOS) [ "\(home)/Applications/Codex.app/Contents/Resources/codex", "/Applications/Codex.app/Contents/Resources/codex", ] #else [] #endif } public static func resolveGeminiBinary( env: [String: String] = ProcessInfo.processInfo.environment, loginPATH: [String]? = LoginShellPathCache.shared.current, commandV: (String, String?, TimeInterval, FileManager) -> String? = ShellCommandLocator.commandV, aliasResolver: (String, String?, TimeInterval, FileManager, String) -> String? = ShellCommandLocator .resolveAlias, fileManager: FileManager = .default, home: String = NSHomeDirectory()) -> String? { self.resolveBinary( name: "gemini", overrideKey: "GEMINI_CLI_PATH", env: env, loginPATH: loginPATH, commandV: commandV, aliasResolver: aliasResolver, fileManager: fileManager, home: home) } public static func resolveGrokBinary( env: [String: String] = ProcessInfo.processInfo.environment, loginPATH: [String]? = LoginShellPathCache.shared.current, commandV: (String, String?, TimeInterval, FileManager) -> String? = ShellCommandLocator.commandV, aliasResolver: (String, String?, TimeInterval, FileManager, String) -> String? = ShellCommandLocator .resolveAlias, fileManager: FileManager = .default, home: String = NSHomeDirectory()) -> String? { self.resolveBinary( name: "grok", overrideKey: "GROK_CLI_PATH", env: env, loginPATH: loginPATH, commandV: commandV, aliasResolver: aliasResolver, wellKnownPaths: self.grokWellKnownPaths(home: home), fileManager: fileManager, home: home) } /// Well-known install locations for the Grok Build CLI binary. /// Covers the installer's default (`~/.grok/bin/grok`) and the symlinks it sometimes /// creates into `~/.local/bin` and `/usr/local/bin`. static func grokWellKnownPaths(home: String) -> [String] { [ "\(home)/.grok/bin/grok", "\(home)/.local/bin/grok", "/usr/local/bin/grok", "/opt/homebrew/bin/grok", ] } public static func resolveAWSBinary( env: [String: String] = ProcessInfo.processInfo.environment, loginPATH: [String]? = LoginShellPathCache.shared.current, commandV: (String, String?, TimeInterval, FileManager) -> String? = ShellCommandLocator.commandV, aliasResolver: (String, String?, TimeInterval, FileManager, String) -> String? = ShellCommandLocator .resolveAlias, fileManager: FileManager = .default, home: String = NSHomeDirectory()) -> String? { self.resolveBinary( name: "aws", overrideKey: "AWS_CLI_PATH", env: env, loginPATH: loginPATH, commandV: commandV, aliasResolver: aliasResolver, wellKnownPaths: self.awsWellKnownPaths(home: home), fileManager: fileManager, home: home) } /// Well-known install locations for the AWS CLI v2 (`aws`). /// Covers Homebrew (Apple Silicon + Intel) and the per-user pip/uv install path. static func awsWellKnownPaths(home: String) -> [String] { [ "/opt/homebrew/bin/aws", "/usr/local/bin/aws", "\(home)/.local/bin/aws", ] } public static func resolveAuggieBinary( env: [String: String] = ProcessInfo.processInfo.environment, loginPATH: [String]? = LoginShellPathCache.shared.current, commandV: (String, String?, TimeInterval, FileManager) -> String? = ShellCommandLocator.commandV, aliasResolver: (String, String?, TimeInterval, FileManager, String) -> String? = ShellCommandLocator .resolveAlias, fileManager: FileManager = .default, home: String = NSHomeDirectory()) -> String? { self.resolveBinary( name: "auggie", overrideKey: "AUGGIE_CLI_PATH", env: env, loginPATH: loginPATH, commandV: commandV, aliasResolver: aliasResolver, fileManager: fileManager, home: home) } // swiftlint:disable function_parameter_count private static func resolveBinary( name: String, overrideKey: String, env: [String: String], loginPATH: [String]?, commandV: (String, String?, TimeInterval, FileManager) -> String?, aliasResolver: (String, String?, TimeInterval, FileManager, String) -> String?, wellKnownPaths: [String] = [], launchCandidateFilter: (String, FileManager) -> Bool = { _, _ in true }, fileManager: FileManager, home: String) -> String? { // swiftlint:enable function_parameter_count // 1) Explicit override if let override = env[overrideKey], fileManager.isExecutableFile(atPath: override) { return override } // 2) Login-shell PATH (captured once per launch) if let loginPATH, let pathHit = self.find( name, in: loginPATH, fileManager: fileManager, launchCandidateFilter: launchCandidateFilter) { return pathHit } // 3) Existing PATH if let existingPATH = env["PATH"], let pathHit = self.find( name, in: existingPATH.split(separator: ":").map(String.init), fileManager: fileManager, launchCandidateFilter: launchCandidateFilter) { return pathHit } // 4) Well-known installation paths (e.g. Homebrew, cmux.app bundle, ~/.claude/bin). // Prefer these before shell probing to avoid running interactive shell init for common installs. for candidate in wellKnownPaths where fileManager.isExecutableFile(atPath: candidate) && launchCandidateFilter(candidate, fileManager) { return candidate } // 5) Interactive login shell lookup (captures nvm/fnm/mise paths from .zshrc/.bashrc) if let shellHit = commandV(name, env["SHELL"], 2.0, fileManager), fileManager.isExecutableFile(atPath: shellHit), launchCandidateFilter(shellHit, fileManager) { return shellHit } // 5b) Alias fallback (login shell); only attempt after all standard lookups fail. if let aliasHit = aliasResolver(name, env["SHELL"], 2.0, fileManager, home), fileManager.isExecutableFile(atPath: aliasHit), launchCandidateFilter(aliasHit, fileManager) { return aliasHit } // 6) Minimal fallback let fallback = ["/usr/bin", "/bin", "/usr/sbin", "/sbin"] if let pathHit = self.find( name, in: fallback, fileManager: fileManager, launchCandidateFilter: launchCandidateFilter) { return pathHit } return nil } private static func find( _ binary: String, in paths: [String], fileManager: FileManager, launchCandidateFilter: (String, FileManager) -> Bool = { _, _ in true }) -> String? { for path in paths where !path.isEmpty { let candidate = "\(path.hasSuffix("/") ? String(path.dropLast()) : path)/\(binary)" if fileManager.isExecutableFile(atPath: candidate), launchCandidateFilter(candidate, fileManager) { return candidate } } return nil } } public enum CodexLaunchPreflight { public static func isLaunchCandidateAllowed(path: String, fileManager: FileManager = .default) -> Bool { #if os(macOS) self.isLaunchCandidateAllowed( path: path, fileManager: fileManager, hasExtendedAttribute: self.hasExtendedAttribute, spctlAssessment: { self.spctlAssessment(path: $0) }, isMachOExecutable: self.isMachOExecutable) #else _ = path _ = fileManager return true #endif } #if os(macOS) static func isLaunchCandidateAllowed( path: String, fileManager: FileManager, hasExtendedAttribute: (String, String) -> Bool, spctlAssessment: (String) -> String?, isMachOExecutable: (String) -> Bool) -> Bool { let realPath = URL(fileURLWithPath: path).resolvingSymlinksInPath().path let pathsToCheck = [path, realPath] + self.nativeCodexExecutableCandidates( for: realPath, fileManager: fileManager) for candidate in Set(pathsToCheck) where hasExtendedAttribute(candidate, "com.apple.malware") { return false } let hasQuarantine = Set(pathsToCheck).contains { hasExtendedAttribute($0, "com.apple.quarantine") } guard let native = pathsToCheck.first(where: isMachOExecutable) else { return !hasQuarantine } guard let assessment = spctlAssessment(native) else { return !hasQuarantine } return !self.isExplicitlyBlockedAssessment(assessment, path: native) } private static func nativeCodexExecutableCandidates(for path: String, fileManager: FileManager) -> [String] { let url = URL(fileURLWithPath: path) guard url.lastPathComponent == "codex.js" else { return [] } let packageRoot = url.deletingLastPathComponent().deletingLastPathComponent() return self.npmNativeCodexCandidates(packageRoot: packageRoot) .map(\.path) .filter { fileManager.isExecutableFile(atPath: $0) } } private static func npmNativeCodexCandidates(packageRoot: URL) -> [URL] { guard let target = self.darwinCodexTarget else { return [] } let optionalPackage = packageRoot .appendingPathComponent("node_modules") .appendingPathComponent("@openai") .appendingPathComponent(target.packageName) return [ optionalPackage, packageRoot, ].map { $0.appendingPathComponent("vendor") .appendingPathComponent(target.triple) .appendingPathComponent("codex") .appendingPathComponent("codex") } } private static var darwinCodexTarget: (packageName: String, triple: String)? { #if arch(arm64) ("codex-darwin-arm64", "aarch64-apple-darwin") #elseif arch(x86_64) ("codex-darwin-x64", "x86_64-apple-darwin") #else nil #endif } private static func hasExtendedAttribute(path: String, name: String) -> Bool { path.withCString { pathPointer in name.withCString { namePointer in getxattr(pathPointer, namePointer, nil, 0, 0, 0) >= 0 } } } private static func isMachOExecutable(path: String) -> Bool { guard let handle = try? FileHandle(forReadingFrom: URL(fileURLWithPath: path)) else { return false } defer { try? handle.close() } guard let data = try? handle.read(upToCount: 4), data.count == 4 else { return false } let bytes = [UInt8](data) return bytes == [0xFE, 0xED, 0xFA, 0xCE] || bytes == [0xCE, 0xFA, 0xED, 0xFE] || bytes == [0xFE, 0xED, 0xFA, 0xCF] || bytes == [0xCF, 0xFA, 0xED, 0xFE] || bytes == [0xCA, 0xFE, 0xBA, 0xBE] || bytes == [0xCA, 0xFE, 0xBA, 0xBF] } private static func spctlAssessment(path: String, timeout: TimeInterval = 2.0) -> String? { let spctlPath = "/usr/sbin/spctl" guard FileManager.default.isExecutableFile(atPath: spctlPath) else { return nil } let process = Process() process.executableURL = URL(fileURLWithPath: spctlPath) process.arguments = ["--assess", "--type", "execute", "--verbose=4", path] let output = Pipe() process.standardOutput = output process.standardError = output let finished = DispatchSemaphore(value: 0) process.terminationHandler = { _ in finished.signal() } do { try process.run() } catch { return nil } if finished.wait(timeout: .now() + timeout) != .success { process.terminate() return nil } let data = output.fileHandleForReading.readDataToEndOfFile() return String(data: data, encoding: .utf8) } private static func isExplicitlyBlockedAssessment(_ assessment: String, path: String) -> Bool { let lower = self.assessmentDiagnosticText(assessment, path: path).lowercased() if lower.contains("denied") || lower.contains("cssmerr_tp_cert_revoked") || lower.contains("revoked") || lower.contains("malware") || lower.contains("quarantine") { return true } if lower.contains("rejected") { return !lower.contains("code is valid but does not seem to be an app") } return false } private static func assessmentDiagnosticText(_ assessment: String, path: String) -> String { assessment .split(whereSeparator: \.isNewline) .enumerated() .compactMap { offset, line -> String? in var text = line.trimmingCharacters(in: .whitespacesAndNewlines) if offset == 0, text.hasPrefix("\(path):") { text = String(text.dropFirst(path.count + 1)) .trimmingCharacters(in: .whitespacesAndNewlines) } let lower = text.lowercased() guard !lower.hasPrefix("source="), !lower.hasPrefix("origin=") else { return nil } return text } .joined(separator: "\n") } #endif } public enum ShellCommandLocator { static func test_runShellCommand( shell: String, arguments: [String], timeout: TimeInterval) -> Data? { self.runShellCommand(shell: shell, arguments: arguments, timeout: timeout) } public static func commandV( _ tool: String, _ shell: String?, _ timeout: TimeInterval,