Relay: force app to run relay via system node

This commit is contained in:
Peter Steinberger
2025-12-09 04:36:05 +00:00
parent d66a05dc41
commit 2ebad55a59
2 changed files with 23 additions and 12 deletions

View File

@@ -193,15 +193,26 @@ final class RelayProcessManager: ObservableObject {
} }
private func resolveCommand() -> [String] { private func resolveCommand() -> [String] {
// Keep it simple: rely on a system-installed clawdis binary. // Force the app-managed relay to use system Node (no bundled runtime, no bun).
// Default to `clawdis relay`; users can provide an override via env if needed. let runtimeResult = CommandResolver.runtimeResolution()
if let override = ProcessInfo.processInfo.environment["CLAWDIS_RELAY_CMD"], guard case let .success(runtime) = runtimeResult else {
!override.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty if case let .failure(err) = runtimeResult {
{ return CommandResolver.runtimeErrorCommand(err)
return override.split(separator: " ").map(String.init) }
return ["/bin/sh", "-c", "echo 'runtime resolution failed' >&2; exit 1"]
} }
return CommandResolver.clawdisCommand(subcommand: "relay") let relayRoot = CommandResolver.projectRoot()
if let entry = CommandResolver.relayEntrypoint(in: relayRoot) {
return CommandResolver.makeRuntimeCommand(
runtime: runtime,
entrypoint: entry,
subcommand: "relay",
extraArgs: [])
}
return CommandResolver.errorCommand(
with: "clawdis entrypoint missing (looked for dist/index.js or bin/clawdis.js); run pnpm build.")
} }
private func makeEnvironment() -> Environment { private func makeEnvironment() -> Environment {

View File

@@ -207,7 +207,7 @@ enum CommandResolver {
return FileManager.default.fileExists(atPath: relay.path) ? relay : nil return FileManager.default.fileExists(atPath: relay.path) ? relay : nil
} }
private static func relayEntrypoint(in root: URL) -> String? { static func relayEntrypoint(in root: URL) -> String? {
let distEntry = root.appendingPathComponent("dist/index.js").path let distEntry = root.appendingPathComponent("dist/index.js").path
if FileManager.default.isReadableFile(atPath: distEntry) { return distEntry } if FileManager.default.isReadableFile(atPath: distEntry) { return distEntry }
let binEntry = root.appendingPathComponent("bin/clawdis.js").path let binEntry = root.appendingPathComponent("bin/clawdis.js").path
@@ -215,11 +215,11 @@ enum CommandResolver {
return nil return nil
} }
private static func runtimeResolution() -> Result<RuntimeResolution, RuntimeResolutionError> { static func runtimeResolution() -> Result<RuntimeResolution, RuntimeResolutionError> {
RuntimeLocator.resolve(searchPaths: self.preferredPaths()) RuntimeLocator.resolve(searchPaths: self.preferredPaths())
} }
private static func makeRuntimeCommand( static func makeRuntimeCommand(
runtime: RuntimeResolution, runtime: RuntimeResolution,
entrypoint: String, entrypoint: String,
subcommand: String, subcommand: String,
@@ -228,12 +228,12 @@ enum CommandResolver {
[runtime.path, entrypoint, subcommand] + extraArgs [runtime.path, entrypoint, subcommand] + extraArgs
} }
private static func runtimeErrorCommand(_ error: RuntimeResolutionError) -> [String] { static func runtimeErrorCommand(_ error: RuntimeResolutionError) -> [String] {
let message = RuntimeLocator.describeFailure(error) let message = RuntimeLocator.describeFailure(error)
return self.errorCommand(with: message) return self.errorCommand(with: message)
} }
private static func errorCommand(with message: String) -> [String] { static func errorCommand(with message: String) -> [String] {
let script = """ let script = """
cat <<'__CLAWDIS_ERR__' >&2 cat <<'__CLAWDIS_ERR__' >&2
\(message) \(message)