···24242525 /// Start listening for CLI connections.
2626 func start() throws {
2727+ // Ensure parent directory exists (e.g. ~/Library/Application Support/com.onevcat.prowl)
2828+ let parentDir = (socketPath as NSString).deletingLastPathComponent
2929+ try? FileManager.default.createDirectory(
3030+ atPath: parentDir,
3131+ withIntermediateDirectories: true
3232+ )
3333+2734 // Clean up stale socket file
2835 unlink(socketPath)
2936
+16-1
supacode/CLIService/Shared/SocketConstants.swift
···1616 public static let cliOpenPathArgument = "--prowl-cli-open-path"
17171818 /// Default Unix domain socket path.
1919- /// Located in user's temporary directory to avoid permission issues.
1919+ ///
2020+ /// Located under `~/Library/Application Support/com.onevcat.prowl/` because macOS periodically
2121+ /// sweeps `/var/folders/.../T/` (NSTemporaryDirectory) and removes the socket file out from
2222+ /// under a long-running app, leaving a bound FD with no path entry — connect() then fails with
2323+ /// ENOENT and the CLI mistakenly reports `APP_NOT_RUNNING`.
2024 ///
2125 /// If `PROWL_CLI_SOCKET` is set and not empty, it takes precedence.
2626+ /// Falls back to NSTemporaryDirectory if the preferred path would exceed the AF_UNIX limit.
2227 public static var defaultPath: String {
2328 if let override = ProcessInfo.processInfo.environment[environmentKey], !override.isEmpty {
2429 return override
3030+ }
3131+ let preferred = FileManager.default.homeDirectoryForCurrentUser
3232+ .appending(path: "Library", directoryHint: .isDirectory)
3333+ .appending(path: "Application Support", directoryHint: .isDirectory)
3434+ .appending(path: "com.onevcat.prowl", directoryHint: .isDirectory)
3535+ .appending(path: "cli.sock", directoryHint: .notDirectory)
3636+ .path(percentEncoded: false)
3737+ // sockaddr_un.sun_path is 104 bytes on Darwin (including NUL terminator).
3838+ if preferred.utf8.count < 104 {
3939+ return preferred
2540 }
2641 let tmpDir = NSTemporaryDirectory()
2742 return (tmpDir as NSString).appendingPathComponent("prowl-cli.sock")