refactor: rename clawdbot to moltbot with legacy compat

This commit is contained in:
Peter Steinberger
2026-01-27 12:19:58 +00:00
parent 83460df96f
commit 6d16a658e5
1839 changed files with 11250 additions and 11199 deletions

View File

@@ -1,6 +1,6 @@
import AppKit
import ClawdbotIPC
import ClawdbotKit
import MoltbotIPC
import MoltbotKit
import Foundation
actor MacNodeRuntime {
@@ -34,39 +34,39 @@ actor MacNodeRuntime {
return BridgeInvokeResponse(
id: req.id,
ok: false,
error: ClawdbotNodeError(
error: MoltbotNodeError(
code: .unavailable,
message: "CANVAS_DISABLED: enable Canvas in Settings"))
}
do {
switch command {
case ClawdbotCanvasCommand.present.rawValue,
ClawdbotCanvasCommand.hide.rawValue,
ClawdbotCanvasCommand.navigate.rawValue,
ClawdbotCanvasCommand.evalJS.rawValue,
ClawdbotCanvasCommand.snapshot.rawValue:
case MoltbotCanvasCommand.present.rawValue,
MoltbotCanvasCommand.hide.rawValue,
MoltbotCanvasCommand.navigate.rawValue,
MoltbotCanvasCommand.evalJS.rawValue,
MoltbotCanvasCommand.snapshot.rawValue:
return try await self.handleCanvasInvoke(req)
case ClawdbotCanvasA2UICommand.reset.rawValue,
ClawdbotCanvasA2UICommand.push.rawValue,
ClawdbotCanvasA2UICommand.pushJSONL.rawValue:
case MoltbotCanvasA2UICommand.reset.rawValue,
MoltbotCanvasA2UICommand.push.rawValue,
MoltbotCanvasA2UICommand.pushJSONL.rawValue:
return try await self.handleA2UIInvoke(req)
case ClawdbotCameraCommand.snap.rawValue,
ClawdbotCameraCommand.clip.rawValue,
ClawdbotCameraCommand.list.rawValue:
case MoltbotCameraCommand.snap.rawValue,
MoltbotCameraCommand.clip.rawValue,
MoltbotCameraCommand.list.rawValue:
return try await self.handleCameraInvoke(req)
case ClawdbotLocationCommand.get.rawValue:
case MoltbotLocationCommand.get.rawValue:
return try await self.handleLocationInvoke(req)
case MacNodeScreenCommand.record.rawValue:
return try await self.handleScreenRecordInvoke(req)
case ClawdbotSystemCommand.run.rawValue:
case MoltbotSystemCommand.run.rawValue:
return try await self.handleSystemRun(req)
case ClawdbotSystemCommand.which.rawValue:
case MoltbotSystemCommand.which.rawValue:
return try await self.handleSystemWhich(req)
case ClawdbotSystemCommand.notify.rawValue:
case MoltbotSystemCommand.notify.rawValue:
return try await self.handleSystemNotify(req)
case ClawdbotSystemCommand.execApprovalsGet.rawValue:
case MoltbotSystemCommand.execApprovalsGet.rawValue:
return try await self.handleSystemExecApprovalsGet(req)
case ClawdbotSystemCommand.execApprovalsSet.rawValue:
case MoltbotSystemCommand.execApprovalsSet.rawValue:
return try await self.handleSystemExecApprovalsSet(req)
default:
return Self.errorResponse(req, code: .invalidRequest, message: "INVALID_REQUEST: unknown command")
@@ -82,9 +82,9 @@ actor MacNodeRuntime {
private func handleCanvasInvoke(_ req: BridgeInvokeRequest) async throws -> BridgeInvokeResponse {
switch req.command {
case ClawdbotCanvasCommand.present.rawValue:
let params = (try? Self.decodeParams(ClawdbotCanvasPresentParams.self, from: req.paramsJSON)) ??
ClawdbotCanvasPresentParams()
case MoltbotCanvasCommand.present.rawValue:
let params = (try? Self.decodeParams(MoltbotCanvasPresentParams.self, from: req.paramsJSON)) ??
MoltbotCanvasPresentParams()
let urlTrimmed = params.url?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
let url = urlTrimmed.isEmpty ? nil : urlTrimmed
let placement = params.placement.map {
@@ -98,29 +98,29 @@ actor MacNodeRuntime {
placement: placement)
}
return BridgeInvokeResponse(id: req.id, ok: true)
case ClawdbotCanvasCommand.hide.rawValue:
case MoltbotCanvasCommand.hide.rawValue:
let sessionKey = self.mainSessionKey
await MainActor.run {
CanvasManager.shared.hide(sessionKey: sessionKey)
}
return BridgeInvokeResponse(id: req.id, ok: true)
case ClawdbotCanvasCommand.navigate.rawValue:
let params = try Self.decodeParams(ClawdbotCanvasNavigateParams.self, from: req.paramsJSON)
case MoltbotCanvasCommand.navigate.rawValue:
let params = try Self.decodeParams(MoltbotCanvasNavigateParams.self, from: req.paramsJSON)
let sessionKey = self.mainSessionKey
try await MainActor.run {
_ = try CanvasManager.shared.show(sessionKey: sessionKey, path: params.url)
}
return BridgeInvokeResponse(id: req.id, ok: true)
case ClawdbotCanvasCommand.evalJS.rawValue:
let params = try Self.decodeParams(ClawdbotCanvasEvalParams.self, from: req.paramsJSON)
case MoltbotCanvasCommand.evalJS.rawValue:
let params = try Self.decodeParams(MoltbotCanvasEvalParams.self, from: req.paramsJSON)
let sessionKey = self.mainSessionKey
let result = try await CanvasManager.shared.eval(
sessionKey: sessionKey,
javaScript: params.javaScript)
let payload = try Self.encodePayload(["result": result] as [String: String])
return BridgeInvokeResponse(id: req.id, ok: true, payloadJSON: payload)
case ClawdbotCanvasCommand.snapshot.rawValue:
let params = try? Self.decodeParams(ClawdbotCanvasSnapshotParams.self, from: req.paramsJSON)
case MoltbotCanvasCommand.snapshot.rawValue:
let params = try? Self.decodeParams(MoltbotCanvasSnapshotParams.self, from: req.paramsJSON)
let format = params?.format ?? .jpeg
let maxWidth: Int? = {
if let raw = params?.maxWidth, raw > 0 { return raw }
@@ -155,10 +155,10 @@ actor MacNodeRuntime {
private func handleA2UIInvoke(_ req: BridgeInvokeRequest) async throws -> BridgeInvokeResponse {
switch req.command {
case ClawdbotCanvasA2UICommand.reset.rawValue:
case MoltbotCanvasA2UICommand.reset.rawValue:
try await self.handleA2UIReset(req)
case ClawdbotCanvasA2UICommand.push.rawValue,
ClawdbotCanvasA2UICommand.pushJSONL.rawValue:
case MoltbotCanvasA2UICommand.push.rawValue,
MoltbotCanvasA2UICommand.pushJSONL.rawValue:
try await self.handleA2UIPush(req)
default:
Self.errorResponse(req, code: .invalidRequest, message: "INVALID_REQUEST: unknown command")
@@ -170,14 +170,14 @@ actor MacNodeRuntime {
return BridgeInvokeResponse(
id: req.id,
ok: false,
error: ClawdbotNodeError(
error: MoltbotNodeError(
code: .unavailable,
message: "CAMERA_DISABLED: enable Camera in Settings"))
}
switch req.command {
case ClawdbotCameraCommand.snap.rawValue:
let params = (try? Self.decodeParams(ClawdbotCameraSnapParams.self, from: req.paramsJSON)) ??
ClawdbotCameraSnapParams()
case MoltbotCameraCommand.snap.rawValue:
let params = (try? Self.decodeParams(MoltbotCameraSnapParams.self, from: req.paramsJSON)) ??
MoltbotCameraSnapParams()
let delayMs = min(10000, max(0, params.delayMs ?? 2000))
let res = try await self.cameraCapture.snap(
facing: CameraFacing(rawValue: params.facing?.rawValue ?? "") ?? .front,
@@ -197,9 +197,9 @@ actor MacNodeRuntime {
width: Int(res.size.width),
height: Int(res.size.height)))
return BridgeInvokeResponse(id: req.id, ok: true, payloadJSON: payload)
case ClawdbotCameraCommand.clip.rawValue:
let params = (try? Self.decodeParams(ClawdbotCameraClipParams.self, from: req.paramsJSON)) ??
ClawdbotCameraClipParams()
case MoltbotCameraCommand.clip.rawValue:
let params = (try? Self.decodeParams(MoltbotCameraClipParams.self, from: req.paramsJSON)) ??
MoltbotCameraClipParams()
let res = try await self.cameraCapture.clip(
facing: CameraFacing(rawValue: params.facing?.rawValue ?? "") ?? .front,
durationMs: params.durationMs,
@@ -220,7 +220,7 @@ actor MacNodeRuntime {
durationMs: res.durationMs,
hasAudio: res.hasAudio))
return BridgeInvokeResponse(id: req.id, ok: true, payloadJSON: payload)
case ClawdbotCameraCommand.list.rawValue:
case MoltbotCameraCommand.list.rawValue:
let devices = await self.cameraCapture.listDevices()
let payload = try Self.encodePayload(["devices": devices])
return BridgeInvokeResponse(id: req.id, ok: true, payloadJSON: payload)
@@ -235,12 +235,12 @@ actor MacNodeRuntime {
return BridgeInvokeResponse(
id: req.id,
ok: false,
error: ClawdbotNodeError(
error: MoltbotNodeError(
code: .unavailable,
message: "LOCATION_DISABLED: enable Location in Settings"))
}
let params = (try? Self.decodeParams(ClawdbotLocationGetParams.self, from: req.paramsJSON)) ??
ClawdbotLocationGetParams()
let params = (try? Self.decodeParams(MoltbotLocationGetParams.self, from: req.paramsJSON)) ??
MoltbotLocationGetParams()
let desired = params.desiredAccuracy ??
(Self.locationPreciseEnabled() ? .precise : .balanced)
let services = await self.mainActorServices()
@@ -257,7 +257,7 @@ actor MacNodeRuntime {
return BridgeInvokeResponse(
id: req.id,
ok: false,
error: ClawdbotNodeError(
error: MoltbotNodeError(
code: .unavailable,
message: "LOCATION_PERMISSION_REQUIRED: grant Location permission"))
}
@@ -267,7 +267,7 @@ actor MacNodeRuntime {
maxAgeMs: params.maxAgeMs,
timeoutMs: params.timeoutMs)
let isPrecise = await services.locationAccuracyAuthorization() == .fullAccuracy
let payload = ClawdbotLocationPayload(
let payload = MoltbotLocationPayload(
lat: location.coordinate.latitude,
lon: location.coordinate.longitude,
accuracyMeters: location.horizontalAccuracy,
@@ -283,14 +283,14 @@ actor MacNodeRuntime {
return BridgeInvokeResponse(
id: req.id,
ok: false,
error: ClawdbotNodeError(
error: MoltbotNodeError(
code: .unavailable,
message: "LOCATION_TIMEOUT: no fix in time"))
} catch {
return BridgeInvokeResponse(
id: req.id,
ok: false,
error: ClawdbotNodeError(
error: MoltbotNodeError(
code: .unavailable,
message: "LOCATION_UNAVAILABLE: \(error.localizedDescription)"))
}
@@ -345,7 +345,7 @@ actor MacNodeRuntime {
let sessionKey = self.mainSessionKey
let json = try await CanvasManager.shared.eval(sessionKey: sessionKey, javaScript: """
(() => {
if (!globalThis.clawdbotA2UI) return JSON.stringify({ ok: false, error: "missing clawdbotA2UI" });
if (!globalThis.clawdbotA2UI) return JSON.stringify({ ok: false, error: "missing moltbotA2UI" });
return JSON.stringify(globalThis.clawdbotA2UI.reset());
})()
""")
@@ -354,27 +354,27 @@ actor MacNodeRuntime {
private func handleA2UIPush(_ req: BridgeInvokeRequest) async throws -> BridgeInvokeResponse {
let command = req.command
let messages: [ClawdbotKit.AnyCodable]
if command == ClawdbotCanvasA2UICommand.pushJSONL.rawValue {
let params = try Self.decodeParams(ClawdbotCanvasA2UIPushJSONLParams.self, from: req.paramsJSON)
messages = try ClawdbotCanvasA2UIJSONL.decodeMessagesFromJSONL(params.jsonl)
let messages: [MoltbotKit.AnyCodable]
if command == MoltbotCanvasA2UICommand.pushJSONL.rawValue {
let params = try Self.decodeParams(MoltbotCanvasA2UIPushJSONLParams.self, from: req.paramsJSON)
messages = try MoltbotCanvasA2UIJSONL.decodeMessagesFromJSONL(params.jsonl)
} else {
do {
let params = try Self.decodeParams(ClawdbotCanvasA2UIPushParams.self, from: req.paramsJSON)
let params = try Self.decodeParams(MoltbotCanvasA2UIPushParams.self, from: req.paramsJSON)
messages = params.messages
} catch {
let params = try Self.decodeParams(ClawdbotCanvasA2UIPushJSONLParams.self, from: req.paramsJSON)
messages = try ClawdbotCanvasA2UIJSONL.decodeMessagesFromJSONL(params.jsonl)
let params = try Self.decodeParams(MoltbotCanvasA2UIPushJSONLParams.self, from: req.paramsJSON)
messages = try MoltbotCanvasA2UIJSONL.decodeMessagesFromJSONL(params.jsonl)
}
}
try await self.ensureA2UIHost()
let messagesJSON = try ClawdbotCanvasA2UIJSONL.encodeMessagesJSONArray(messages)
let messagesJSON = try MoltbotCanvasA2UIJSONL.encodeMessagesJSONArray(messages)
let js = """
(() => {
try {
if (!globalThis.clawdbotA2UI) return JSON.stringify({ ok: false, error: "missing clawdbotA2UI" });
if (!globalThis.clawdbotA2UI) return JSON.stringify({ ok: false, error: "missing moltbotA2UI" });
const messages = \(messagesJSON);
return JSON.stringify(globalThis.clawdbotA2UI.applyMessages(messages));
} catch (e) {
@@ -408,7 +408,7 @@ actor MacNodeRuntime {
guard let raw = await GatewayConnection.shared.canvasHostUrl() else { return nil }
let trimmed = raw.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty, let baseUrl = URL(string: trimmed) else { return nil }
return baseUrl.appendingPathComponent("__clawdbot__/a2ui/").absoluteString + "?platform=macos"
return baseUrl.appendingPathComponent("__moltbot__/a2ui/").absoluteString + "?platform=macos"
}
private func isA2UIReady(poll: Bool = false) async -> Bool {
@@ -431,7 +431,7 @@ actor MacNodeRuntime {
}
private func handleSystemRun(_ req: BridgeInvokeRequest) async throws -> BridgeInvokeResponse {
let params = try Self.decodeParams(ClawdbotSystemRunParams.self, from: req.paramsJSON)
let params = try Self.decodeParams(MoltbotSystemRunParams.self, from: req.paramsJSON)
let command = params.command
guard !command.isEmpty else {
return Self.errorResponse(req, code: .invalidRequest, message: "INVALID_REQUEST: command required")
@@ -593,7 +593,7 @@ actor MacNodeRuntime {
}
private func handleSystemWhich(_ req: BridgeInvokeRequest) async throws -> BridgeInvokeResponse {
let params = try Self.decodeParams(ClawdbotSystemWhichParams.self, from: req.paramsJSON)
let params = try Self.decodeParams(MoltbotSystemWhichParams.self, from: req.paramsJSON)
let bins = params.bins
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
.filter { !$0.isEmpty }
@@ -639,7 +639,7 @@ actor MacNodeRuntime {
private func resolveSystemRunApproval(
req: BridgeInvokeRequest,
params: ClawdbotSystemRunParams,
params: MoltbotSystemRunParams,
context: ExecRunContext) async -> ExecApprovalOutcome
{
let requiresAsk = ExecApprovalHelpers.requiresAsk(
@@ -790,7 +790,7 @@ actor MacNodeRuntime {
}
private func handleSystemNotify(_ req: BridgeInvokeRequest) async throws -> BridgeInvokeResponse {
let params = try Self.decodeParams(ClawdbotSystemNotifyParams.self, from: req.paramsJSON)
let params = try Self.decodeParams(MoltbotSystemNotifyParams.self, from: req.paramsJSON)
let title = params.title.trimmingCharacters(in: .whitespacesAndNewlines)
let body = params.body.trimmingCharacters(in: .whitespacesAndNewlines)
if title.isEmpty, body.isEmpty {
@@ -886,9 +886,9 @@ extension MacNodeRuntime {
return merged
}
private nonisolated static func locationMode() -> ClawdbotLocationMode {
private nonisolated static func locationMode() -> MoltbotLocationMode {
let raw = UserDefaults.standard.string(forKey: locationModeKey) ?? "off"
return ClawdbotLocationMode(rawValue: raw) ?? .off
return MoltbotLocationMode(rawValue: raw) ?? .off
}
private nonisolated static func locationPreciseEnabled() -> Bool {
@@ -898,18 +898,18 @@ extension MacNodeRuntime {
private static func errorResponse(
_ req: BridgeInvokeRequest,
code: ClawdbotNodeErrorCode,
code: MoltbotNodeErrorCode,
message: String) -> BridgeInvokeResponse
{
BridgeInvokeResponse(
id: req.id,
ok: false,
error: ClawdbotNodeError(code: code, message: message))
error: MoltbotNodeError(code: code, message: message))
}
private static func encodeCanvasSnapshot(
image: NSImage,
format: ClawdbotCanvasSnapshotFormat,
format: MoltbotCanvasSnapshotFormat,
maxWidth: Int?,
quality: Double) throws -> Data
{