mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
fix(macos): prefer openclaw binary while keeping pnpm fallback (#25512)
Co-authored-by: Peter Machona <7957943+chilu18@users.noreply.github.com>
This commit is contained in:
@@ -246,15 +246,17 @@ enum CommandResolver {
|
||||
return ssh
|
||||
}
|
||||
|
||||
let runtimeResult = self.runtimeResolution(searchPaths: searchPaths)
|
||||
let root = self.projectRoot()
|
||||
if let openclawPath = self.projectOpenClawExecutable(projectRoot: root) {
|
||||
return [openclawPath, subcommand] + extraArgs
|
||||
}
|
||||
if let openclawPath = self.openclawExecutable(searchPaths: searchPaths) {
|
||||
return [openclawPath, subcommand] + extraArgs
|
||||
}
|
||||
|
||||
let runtimeResult = self.runtimeResolution(searchPaths: searchPaths)
|
||||
switch runtimeResult {
|
||||
case let .success(runtime):
|
||||
let root = self.projectRoot()
|
||||
if let openclawPath = self.projectOpenClawExecutable(projectRoot: root) {
|
||||
return [openclawPath, subcommand] + extraArgs
|
||||
}
|
||||
|
||||
if let entry = self.gatewayEntrypoint(in: root) {
|
||||
return self.makeRuntimeCommand(
|
||||
runtime: runtime,
|
||||
@@ -262,19 +264,21 @@ enum CommandResolver {
|
||||
subcommand: subcommand,
|
||||
extraArgs: extraArgs)
|
||||
}
|
||||
if let pnpm = self.findExecutable(named: "pnpm", searchPaths: searchPaths) {
|
||||
// Use --silent to avoid pnpm lifecycle banners that would corrupt JSON outputs.
|
||||
return [pnpm, "--silent", "openclaw", subcommand] + extraArgs
|
||||
}
|
||||
if let openclawPath = self.openclawExecutable(searchPaths: searchPaths) {
|
||||
return [openclawPath, subcommand] + extraArgs
|
||||
}
|
||||
case .failure:
|
||||
break
|
||||
}
|
||||
|
||||
if let pnpm = self.findExecutable(named: "pnpm", searchPaths: searchPaths) {
|
||||
// Use --silent to avoid pnpm lifecycle banners that would corrupt JSON outputs.
|
||||
return [pnpm, "--silent", "openclaw", subcommand] + extraArgs
|
||||
}
|
||||
|
||||
switch runtimeResult {
|
||||
case .success:
|
||||
let missingEntry = """
|
||||
openclaw entrypoint missing (looked for dist/index.js or openclaw.mjs); run pnpm build.
|
||||
"""
|
||||
return self.errorCommand(with: missingEntry)
|
||||
|
||||
case let .failure(error):
|
||||
return self.runtimeErrorCommand(error)
|
||||
}
|
||||
|
||||
@@ -66,6 +66,48 @@ import Testing
|
||||
}
|
||||
}
|
||||
|
||||
@Test func prefersOpenClawBinaryOverPnpm() async throws {
|
||||
let defaults = self.makeDefaults()
|
||||
defaults.set(AppState.ConnectionMode.local.rawValue, forKey: connectionModeKey)
|
||||
|
||||
let tmp = try makeTempDir()
|
||||
CommandResolver.setProjectRoot(tmp.path)
|
||||
|
||||
let binDir = tmp.appendingPathComponent("bin")
|
||||
let openclawPath = binDir.appendingPathComponent("openclaw")
|
||||
let pnpmPath = binDir.appendingPathComponent("pnpm")
|
||||
try self.makeExec(at: openclawPath)
|
||||
try self.makeExec(at: pnpmPath)
|
||||
|
||||
let cmd = CommandResolver.openclawCommand(
|
||||
subcommand: "rpc",
|
||||
defaults: defaults,
|
||||
configRoot: [:],
|
||||
searchPaths: [binDir.path])
|
||||
|
||||
#expect(cmd.prefix(2).elementsEqual([openclawPath.path, "rpc"]))
|
||||
}
|
||||
|
||||
@Test func usesOpenClawBinaryWithoutNodeRuntime() async throws {
|
||||
let defaults = self.makeDefaults()
|
||||
defaults.set(AppState.ConnectionMode.local.rawValue, forKey: connectionModeKey)
|
||||
|
||||
let tmp = try makeTempDir()
|
||||
CommandResolver.setProjectRoot(tmp.path)
|
||||
|
||||
let binDir = tmp.appendingPathComponent("bin")
|
||||
let openclawPath = binDir.appendingPathComponent("openclaw")
|
||||
try self.makeExec(at: openclawPath)
|
||||
|
||||
let cmd = CommandResolver.openclawCommand(
|
||||
subcommand: "gateway",
|
||||
defaults: defaults,
|
||||
configRoot: [:],
|
||||
searchPaths: [binDir.path])
|
||||
|
||||
#expect(cmd.prefix(2).elementsEqual([openclawPath.path, "gateway"]))
|
||||
}
|
||||
|
||||
@Test func fallsBackToPnpm() async throws {
|
||||
let defaults = self.makeDefaults()
|
||||
defaults.set(AppState.ConnectionMode.local.rawValue, forKey: connectionModeKey)
|
||||
@@ -76,7 +118,11 @@ import Testing
|
||||
let pnpmPath = tmp.appendingPathComponent("node_modules/.bin/pnpm")
|
||||
try self.makeExec(at: pnpmPath)
|
||||
|
||||
let cmd = CommandResolver.openclawCommand(subcommand: "rpc", defaults: defaults, configRoot: [:])
|
||||
let cmd = CommandResolver.openclawCommand(
|
||||
subcommand: "rpc",
|
||||
defaults: defaults,
|
||||
configRoot: [:],
|
||||
searchPaths: [tmp.appendingPathComponent("node_modules/.bin").path])
|
||||
|
||||
#expect(cmd.prefix(4).elementsEqual([pnpmPath.path, "--silent", "openclaw", "rpc"]))
|
||||
}
|
||||
@@ -95,7 +141,8 @@ import Testing
|
||||
subcommand: "health",
|
||||
extraArgs: ["--json", "--timeout", "5"],
|
||||
defaults: defaults,
|
||||
configRoot: [:])
|
||||
configRoot: [:],
|
||||
searchPaths: [tmp.appendingPathComponent("node_modules/.bin").path])
|
||||
|
||||
#expect(cmd.prefix(5).elementsEqual([pnpmPath.path, "--silent", "openclaw", "health", "--json"]))
|
||||
#expect(cmd.suffix(2).elementsEqual(["--timeout", "5"]))
|
||||
|
||||
Reference in New Issue
Block a user