11import Foundation
22
33actor CLIBridge {
4- private let projectRoot : URL
5-
6- init ( ) {
7- // In dev mode, project root is the working directory
8- // In bundle mode, it's relative to the executable
9- if let bundledCLI = Bundle . main. executableURL?
10- . deletingLastPathComponent ( )
11- . appendingPathComponent ( " rig " ) ,
12- FileManager . default. fileExists ( atPath: bundledCLI. path) {
13- projectRoot = Bundle . main. bundleURL
14- . appendingPathComponent ( " Contents " )
15- . appendingPathComponent ( " Resources " )
16- } else {
17- // Dev mode: assume we're running from project root
18- projectRoot = URL ( fileURLWithPath: FileManager . default. currentDirectoryPath)
19- }
20- }
214
225 func runCommand( _ args: [ String ] ) -> AsyncStream < CLIMessage > {
236 AsyncStream { continuation in
247 Task . detached {
258 do {
269 let process = Process ( )
27- let pipe = Pipe ( )
10+ let stdoutPipe = Pipe ( )
2811
2912 // Try bundled binary first, fall back to uv run
3013 let bundledCLI = Bundle . main. executableURL?
3114 . deletingLastPathComponent ( )
32- . appendingPathComponent ( " rig " )
15+ . appendingPathComponent ( " setmac " )
3316
3417 if let cli = bundledCLI, FileManager . default. fileExists ( atPath: cli. path) {
3518 process. executableURL = cli
3619 process. arguments = args
3720 } else {
3821 process. executableURL = URL ( fileURLWithPath: " /usr/bin/env " )
39- process. arguments = [ " uv " , " run " , " --project " , " cli " , " rig " ] + args
22+ process. arguments = [ " uv " , " run " , " --project " , " cli " , " setmac " ] + args
4023 process. currentDirectoryURL = URL (
4124 fileURLWithPath: FileManager . default. currentDirectoryPath
4225 )
@@ -48,36 +31,28 @@ actor CLIBridge {
4831 " /opt/homebrew/bin " ,
4932 " /opt/homebrew/sbin " ,
5033 " /usr/local/bin " ,
34+ NSHomeDirectory ( ) + " /.local/bin " ,
5135 NSHomeDirectory ( ) + " /.bun/bin " ,
5236 NSHomeDirectory ( ) + " /.cargo/bin " ,
53- NSHomeDirectory ( ) + " /.local/bin " ,
5437 ]
5538 let currentPath = env [ " PATH " ] ?? " /usr/bin:/bin "
5639 env [ " PATH " ] = extraPaths. joined ( separator: " : " ) + " : " + currentPath
5740 process. environment = env
5841
59- process. standardOutput = pipe
42+ process. standardOutput = stdoutPipe
6043 process. standardError = FileHandle . nullDevice
44+ process. standardInput = FileHandle . nullDevice
6145
6246 try process. run ( )
6347
64- let handle = pipe. fileHandleForReading
65- var buffer = Data ( )
66-
67- while true {
68- let chunk = handle. availableData
69- if chunk. isEmpty { break }
70- buffer. append ( chunk)
71-
72- // Process complete lines
73- while let newlineRange = buffer. range ( of: Data ( " \n " . utf8) ) {
74- let lineData = buffer. subdata ( in: buffer. startIndex..< newlineRange. lowerBound)
75- buffer. removeSubrange ( buffer. startIndex... newlineRange. lowerBound)
76-
77- if let msg = try ? JSONDecoder ( ) . decode ( CLIMessage . self, from: lineData) {
78- continuation. yield ( msg)
79- }
80- }
48+ // Read stdout line-by-line, parse JSON
49+ let handle = stdoutPipe. fileHandleForReading
50+ for try await line in handle. bytes. lines {
51+ guard !line. isEmpty else { continue }
52+ guard let data = line. data ( using: . utf8) ,
53+ let msg = try ? JSONDecoder ( ) . decode ( CLIMessage . self, from: data)
54+ else { continue }
55+ continuation. yield ( msg)
8156 }
8257
8358 process. waitUntilExit ( )
0 commit comments