From b826bd668c67de19ef9f7ea255fbd5444f2bf5a6 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 19 Jan 2026 11:14:27 +0000 Subject: [PATCH] fix: pass android lint and swiftformat --- CHANGELOG.md | 1 + apps/android/app/build.gradle.kts | 4 +- .../java/com/clawdbot/android/NodeRuntime.kt | 3 +- .../android/gateway/GatewaySession.kt | 78 ++++++++++--------- .../com/clawdbot/android/ui/SettingsSheet.kt | 7 +- .../DevicePairingApprovalPrompter.swift | 19 +++-- .../Sources/Clawdbot/ExecApprovals.swift | 25 +++--- .../ExecApprovalsGatewayPrompter.swift | 2 +- .../Clawdbot/ExecApprovalsSocket.swift | 42 ++++++---- .../Sources/Clawdbot/GatewayEnvironment.swift | 11 ++- .../Clawdbot/NodeMode/MacNodeRuntime.swift | 10 +-- .../MacNodeRuntimeMainActorServices.swift | 1 - .../Clawdbot/SessionMenuPreviewView.swift | 3 +- .../Clawdbot/SystemRunSettingsView.swift | 5 +- .../Sources/Clawdbot/UsageMenuLabelView.swift | 1 - 15 files changed, 118 insertions(+), 94 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90cb1a637..07756fa55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Docs: https://docs.clawd.bot ### Changes - Android: migrate node transport to the Gateway WebSocket protocol with TLS pinning support + gateway discovery naming. +- Android: bump okhttp + dnsjava to satisfy lint dependency checks. - Docs: refresh Android node discovery docs for the Gateway WS service type. ## 2026.1.19-1 diff --git a/apps/android/app/build.gradle.kts b/apps/android/app/build.gradle.kts index 31c7bc222..d9c7a5c6b 100644 --- a/apps/android/app/build.gradle.kts +++ b/apps/android/app/build.gradle.kts @@ -103,7 +103,7 @@ dependencies { implementation("androidx.security:security-crypto:1.1.0") implementation("androidx.exifinterface:exifinterface:1.4.2") - implementation("com.squareup.okhttp3:okhttp:4.12.0") + implementation("com.squareup.okhttp3:okhttp:5.3.2") // CameraX (for node.invoke camera.* parity) implementation("androidx.camera:camera-core:1.5.2") @@ -113,7 +113,7 @@ dependencies { implementation("androidx.camera:camera-view:1.5.2") // Unicast DNS-SD (Wide-Area Bonjour) for tailnet discovery domains. - implementation("dnsjava:dnsjava:3.6.3") + implementation("dnsjava:dnsjava:3.6.4") testImplementation("junit:junit:4.13.2") testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.10.2") diff --git a/apps/android/app/src/main/java/com/clawdbot/android/NodeRuntime.kt b/apps/android/app/src/main/java/com/clawdbot/android/NodeRuntime.kt index ad705f5d8..302fff989 100644 --- a/apps/android/app/src/main/java/com/clawdbot/android/NodeRuntime.kt +++ b/apps/android/app/src/main/java/com/clawdbot/android/NodeRuntime.kt @@ -13,6 +13,7 @@ import com.clawdbot.android.chat.ChatPendingToolCall import com.clawdbot.android.chat.ChatSessionEntry import com.clawdbot.android.chat.OutgoingAttachment import com.clawdbot.android.gateway.DeviceIdentityStore +import com.clawdbot.android.gateway.GatewayClientInfo import com.clawdbot.android.gateway.GatewayConnectOptions import com.clawdbot.android.gateway.GatewayDiscovery import com.clawdbot.android.gateway.GatewayEndpoint @@ -208,7 +209,7 @@ class NodeRuntime(context: Context) { }, ) - private val chat = + private val chat: ChatController = ChatController( scope = scope, session = operatorSession, diff --git a/apps/android/app/src/main/java/com/clawdbot/android/gateway/GatewaySession.kt b/apps/android/app/src/main/java/com/clawdbot/android/gateway/GatewaySession.kt index 0b08913a4..cf80066de 100644 --- a/apps/android/app/src/main/java/com/clawdbot/android/gateway/GatewaySession.kt +++ b/apps/android/app/src/main/java/com/clawdbot/android/gateway/GatewaySession.kt @@ -219,7 +219,7 @@ class GatewaySession( } } - fun awaitClose() = closedDeferred.await() + suspend fun awaitClose() = closedDeferred.await() fun closeQuietly() { if (isClosed.compareAndSet(false, true)) { @@ -315,41 +315,20 @@ class GatewaySession( client.modelIdentifier?.let { put("modelIdentifier", JsonPrimitive(it)) } } - val params = - buildJsonObject { - put("minProtocol", JsonPrimitive(GATEWAY_PROTOCOL_VERSION)) - put("maxProtocol", JsonPrimitive(GATEWAY_PROTOCOL_VERSION)) - put("client", clientObj) - if (options.caps.isNotEmpty()) put("caps", JsonArray(options.caps.map(::JsonPrimitive))) - if (options.commands.isNotEmpty()) put("commands", JsonArray(options.commands.map(::JsonPrimitive))) - if (options.permissions.isNotEmpty()) { - put( - "permissions", - buildJsonObject { - options.permissions.forEach { (key, value) -> - put(key, JsonPrimitive(value)) - } - }, - ) - } - put("role", JsonPrimitive(options.role)) - if (options.scopes.isNotEmpty()) put("scopes", JsonArray(options.scopes.map(::JsonPrimitive))) - put("locale", JsonPrimitive(locale)) - } - val authToken = token?.trim().orEmpty() val authPassword = password?.trim().orEmpty() - if (authToken.isNotEmpty()) { - params["auth"] = - buildJsonObject { - put("token", JsonPrimitive(authToken)) - } - } else if (authPassword.isNotEmpty()) { - params["auth"] = - buildJsonObject { - put("password", JsonPrimitive(authPassword)) - } - } + val authJson = + when { + authToken.isNotEmpty() -> + buildJsonObject { + put("token", JsonPrimitive(authToken)) + } + authPassword.isNotEmpty() -> + buildJsonObject { + put("password", JsonPrimitive(authPassword)) + } + else -> null + } val identity = identityStore.loadOrCreate() val signedAtMs = System.currentTimeMillis() @@ -365,17 +344,40 @@ class GatewaySession( ) val signature = identityStore.signPayload(payload, identity) val publicKey = identityStore.publicKeyBase64Url(identity) - if (!signature.isNullOrBlank() && !publicKey.isNullOrBlank()) { - params["device"] = + val deviceJson = + if (!signature.isNullOrBlank() && !publicKey.isNullOrBlank()) { buildJsonObject { put("id", JsonPrimitive(identity.deviceId)) put("publicKey", JsonPrimitive(publicKey)) put("signature", JsonPrimitive(signature)) put("signedAt", JsonPrimitive(signedAtMs)) } - } + } else { + null + } - return params + return buildJsonObject { + put("minProtocol", JsonPrimitive(GATEWAY_PROTOCOL_VERSION)) + put("maxProtocol", JsonPrimitive(GATEWAY_PROTOCOL_VERSION)) + put("client", clientObj) + if (options.caps.isNotEmpty()) put("caps", JsonArray(options.caps.map(::JsonPrimitive))) + if (options.commands.isNotEmpty()) put("commands", JsonArray(options.commands.map(::JsonPrimitive))) + if (options.permissions.isNotEmpty()) { + put( + "permissions", + buildJsonObject { + options.permissions.forEach { (key, value) -> + put(key, JsonPrimitive(value)) + } + }, + ) + } + put("role", JsonPrimitive(options.role)) + if (options.scopes.isNotEmpty()) put("scopes", JsonArray(options.scopes.map(::JsonPrimitive))) + authJson?.let { put("auth", it) } + deviceJson?.let { put("device", it) } + put("locale", JsonPrimitive(locale)) + } } private suspend fun handleMessage(text: String) { diff --git a/apps/android/app/src/main/java/com/clawdbot/android/ui/SettingsSheet.kt b/apps/android/app/src/main/java/com/clawdbot/android/ui/SettingsSheet.kt index 15303c742..aee1059bd 100644 --- a/apps/android/app/src/main/java/com/clawdbot/android/ui/SettingsSheet.kt +++ b/apps/android/app/src/main/java/com/clawdbot/android/ui/SettingsSheet.kt @@ -309,11 +309,10 @@ fun SettingsSheet(viewModel: MainViewModel) { add("IP: ${gateway.host}:${gateway.port}") gateway.lanHost?.let { add("LAN: $it") } gateway.tailnetDns?.let { add("Tailnet: $it") } - if (gateway.gatewayPort != null || gateway.bridgePort != null || gateway.canvasPort != null) { - val gw = gateway.gatewayPort?.toString() ?: "—" - val br = (gateway.bridgePort ?: gateway.port).toString() + if (gateway.gatewayPort != null || gateway.canvasPort != null) { + val gw = (gateway.gatewayPort ?: gateway.port).toString() val canvas = gateway.canvasPort?.toString() ?: "—" - add("Ports: gw $gw · bridge $br · canvas $canvas") + add("Ports: gw $gw · canvas $canvas") } } ListItem( diff --git a/apps/macos/Sources/Clawdbot/DevicePairingApprovalPrompter.swift b/apps/macos/Sources/Clawdbot/DevicePairingApprovalPrompter.swift index 9d12b7828..81d87c7d3 100644 --- a/apps/macos/Sources/Clawdbot/DevicePairingApprovalPrompter.swift +++ b/apps/macos/Sources/Clawdbot/DevicePairingApprovalPrompter.swift @@ -117,7 +117,7 @@ final class DevicePairingApprovalPrompter { private func updatePendingCounts() { self.pendingCount = self.queue.count - self.pendingRepairCount = self.queue.filter { $0.isRepair == true }.count + self.pendingRepairCount = self.queue.count(where: { $0.isRepair == true }) } private func presentNextIfNeeded() { @@ -270,7 +270,8 @@ final class DevicePairingApprovalPrompter { let req = try GatewayPayloadDecoding.decode(payload, as: PendingRequest.self) self.enqueue(req) } catch { - self.logger.error("failed to decode device pairing request: \(error.localizedDescription, privacy: .public)") + self.logger + .error("failed to decode device pairing request: \(error.localizedDescription, privacy: .public)") } case let .event(evt) where evt.event == "device.pair.resolved": guard let payload = evt.payload else { return } @@ -278,7 +279,9 @@ final class DevicePairingApprovalPrompter { let resolved = try GatewayPayloadDecoding.decode(payload, as: PairingResolvedEvent.self) self.handleResolved(resolved) } catch { - self.logger.error("failed to decode device pairing resolution: \(error.localizedDescription, privacy: .public)") + self.logger + .error( + "failed to decode device pairing resolution: \(error.localizedDescription, privacy: .public)") } default: break @@ -293,11 +296,15 @@ final class DevicePairingApprovalPrompter { } private func handleResolved(_ resolved: PairingResolvedEvent) { - let resolution = resolved.decision == PairingResolution.approved.rawValue ? PairingResolution.approved : .rejected + let resolution = resolved.decision == PairingResolution.approved.rawValue ? PairingResolution + .approved : .rejected if let activeRequestId, activeRequestId == resolved.requestId { self.resolvedByRequestId.insert(resolved.requestId) self.endActiveAlert() - self.logger.info("device pairing resolved while active requestId=\(resolved.requestId, privacy: .public) decision=\(resolution.rawValue, privacy: .public)") + let decision = resolution.rawValue + self.logger.info( + "device pairing resolved while active requestId=\(resolved.requestId, privacy: .public) " + + "decision=\(decision, privacy: .public)") return } self.queue.removeAll { $0.requestId == resolved.requestId } @@ -314,7 +321,7 @@ final class DevicePairingApprovalPrompter { lines.append("Role: \(role)") } if let scopes = req.scopes, !scopes.isEmpty { - lines.append("Scopes: \(scopes.joined(separator: \", \"))") + lines.append("Scopes: \(scopes.joined(separator: ", "))") } if let remoteIp = req.remoteIp { lines.append("IP: \(remoteIp)") diff --git a/apps/macos/Sources/Clawdbot/ExecApprovals.swift b/apps/macos/Sources/Clawdbot/ExecApprovals.swift index eab1aea11..993e466d3 100644 --- a/apps/macos/Sources/Clawdbot/ExecApprovals.swift +++ b/apps/macos/Sources/Clawdbot/ExecApprovals.swift @@ -53,11 +53,11 @@ enum ExecApprovalQuickMode: String, CaseIterable, Identifiable { static func from(security: ExecSecurity, ask: ExecAsk) -> ExecApprovalQuickMode { switch security { case .deny: - return .deny + .deny case .full: - return .allow + .allow case .allowlist: - return .ask + .ask } } } @@ -106,7 +106,8 @@ struct ExecApprovalsAgent: Codable { var allowlist: [ExecAllowlistEntry]? var isEmpty: Bool { - security == nil && ask == nil && askFallback == nil && autoAllowSkills == nil && (allowlist?.isEmpty ?? true) + self.security == nil && self.ask == nil && self.askFallback == nil && self + .autoAllowSkills == nil && (self.allowlist?.isEmpty ?? true) } } @@ -467,8 +468,8 @@ struct ExecCommandResolution: Sendable { command: [String], rawCommand: String?, cwd: String?, - env: [String: String]? - ) -> ExecCommandResolution? { + env: [String: String]?) -> ExecCommandResolution? + { let trimmedRaw = rawCommand?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "" if !trimmedRaw.isEmpty, let token = self.parseFirstToken(trimmedRaw) { return self.resolveExecutable(rawExecutable: token, cwd: cwd, env: env) @@ -486,8 +487,8 @@ struct ExecCommandResolution: Sendable { private static func resolveExecutable( rawExecutable: String, cwd: String?, - env: [String: String]? - ) -> ExecCommandResolution? { + env: [String: String]?) -> ExecCommandResolution? + { let expanded = rawExecutable.hasPrefix("~") ? (rawExecutable as NSString).expandingTildeInPath : rawExecutable let hasPathSeparator = expanded.contains("/") || expanded.contains("\\") let resolvedPath: String? = { @@ -503,7 +504,11 @@ struct ExecCommandResolution: Sendable { return CommandResolver.findExecutable(named: expanded, searchPaths: searchPaths) }() let name = resolvedPath.map { URL(fileURLWithPath: $0).lastPathComponent } ?? expanded - return ExecCommandResolution(rawExecutable: expanded, resolvedPath: resolvedPath, executableName: name, cwd: cwd) + return ExecCommandResolution( + rawExecutable: expanded, + resolvedPath: resolvedPath, + executableName: name, + cwd: cwd) } private static func parseFirstToken(_ command: String) -> String? { @@ -624,7 +629,7 @@ struct ExecEventPayload: Codable, Sendable { var output: String? var reason: String? - static func truncateOutput(_ raw: String, maxChars: Int = 20_000) -> String? { + static func truncateOutput(_ raw: String, maxChars: Int = 20000) -> String? { let trimmed = raw.trimmingCharacters(in: .whitespacesAndNewlines) guard !trimmed.isEmpty else { return nil } if trimmed.count <= maxChars { return trimmed } diff --git a/apps/macos/Sources/Clawdbot/ExecApprovalsGatewayPrompter.swift b/apps/macos/Sources/Clawdbot/ExecApprovalsGatewayPrompter.swift index 90eab9108..4cd79d5f6 100644 --- a/apps/macos/Sources/Clawdbot/ExecApprovalsGatewayPrompter.swift +++ b/apps/macos/Sources/Clawdbot/ExecApprovalsGatewayPrompter.swift @@ -51,7 +51,7 @@ final class ExecApprovalsGatewayPrompter { "id": AnyCodable(request.id), "decision": AnyCodable(decision.rawValue), ], - timeoutMs: 10_000) + timeoutMs: 10000) } catch { self.logger.error("exec approval handling failed \(error.localizedDescription, privacy: .public)") } diff --git a/apps/macos/Sources/Clawdbot/ExecApprovalsSocket.swift b/apps/macos/Sources/Clawdbot/ExecApprovalsSocket.swift index ca5e85edf..9e1532274 100644 --- a/apps/macos/Sources/Clawdbot/ExecApprovalsSocket.swift +++ b/apps/macos/Sources/Clawdbot/ExecApprovalsSocket.swift @@ -28,7 +28,7 @@ private struct ExecApprovalSocketDecision: Codable { var decision: ExecApprovalDecision } -fileprivate struct ExecHostSocketRequest: Codable { +private struct ExecHostSocketRequest: Codable { var type: String var id: String var nonce: String @@ -37,7 +37,7 @@ fileprivate struct ExecHostSocketRequest: Codable { var requestJson: String } -fileprivate struct ExecHostRequest: Codable { +private struct ExecHostRequest: Codable { var command: [String] var rawCommand: String? var cwd: String? @@ -48,7 +48,7 @@ fileprivate struct ExecHostRequest: Codable { var sessionKey: String? } -fileprivate struct ExecHostRunResult: Codable { +private struct ExecHostRunResult: Codable { var exitCode: Int? var timedOut: Bool var success: Bool @@ -57,13 +57,13 @@ fileprivate struct ExecHostRunResult: Codable { var error: String? } -fileprivate struct ExecHostError: Codable { +private struct ExecHostError: Codable { var code: String var message: String var reason: String? } -fileprivate struct ExecHostResponse: Codable { +private struct ExecHostResponse: Codable { var type: String var id: String var ok: Bool @@ -74,14 +74,14 @@ fileprivate struct ExecHostResponse: Codable { enum ExecApprovalsSocketClient { private struct TimeoutError: LocalizedError { var message: String - var errorDescription: String? { message } + var errorDescription: String? { self.message } } static func requestDecision( socketPath: String, token: String, request: ExecApprovalPromptRequest, - timeoutMs: Int = 15_000) async -> ExecApprovalDecision? + timeoutMs: Int = 15000) async -> ExecApprovalDecision? { let trimmedPath = socketPath.trimmingCharacters(in: .whitespacesAndNewlines) let trimmedToken = token.trimmingCharacters(in: .whitespacesAndNewlines) @@ -254,7 +254,7 @@ enum ExecApprovalsPromptPresenter { } @MainActor -fileprivate enum ExecHostExecutor { +private enum ExecHostExecutor { private static let blockedEnvKeys: Set = [ "PATH", "NODE_OPTIONS", @@ -313,12 +313,15 @@ fileprivate enum ExecHostExecutor { id: UUID().uuidString, ok: false, payload: nil, - error: ExecHostError(code: "UNAVAILABLE", message: "SYSTEM_RUN_DISABLED: security=deny", reason: "security=deny")) + error: ExecHostError( + code: "UNAVAILABLE", + message: "SYSTEM_RUN_DISABLED: security=deny", + reason: "security=deny")) } let requiresAsk: Bool = { if ask == .always { return true } - if ask == .onMiss && security == .allowlist && allowlistMatch == nil && !skillAllow { return true } + if ask == .onMiss, security == .allowlist, allowlistMatch == nil, !skillAllow { return true } return false }() @@ -341,7 +344,10 @@ fileprivate enum ExecHostExecutor { id: UUID().uuidString, ok: false, payload: nil, - error: ExecHostError(code: "UNAVAILABLE", message: "SYSTEM_RUN_DENIED: user denied", reason: "user-denied")) + error: ExecHostError( + code: "UNAVAILABLE", + message: "SYSTEM_RUN_DENIED: user denied", + reason: "user-denied")) case .allowAlways: approvedByAsk = true if security == .allowlist { @@ -355,13 +361,16 @@ fileprivate enum ExecHostExecutor { } } - if security == .allowlist && allowlistMatch == nil && !skillAllow && !approvedByAsk { + if security == .allowlist, allowlistMatch == nil, !skillAllow, !approvedByAsk { return ExecHostResponse( type: "exec-res", id: UUID().uuidString, ok: false, payload: nil, - error: ExecHostError(code: "UNAVAILABLE", message: "SYSTEM_RUN_DENIED: allowlist miss", reason: "allowlist-miss")) + error: ExecHostError( + code: "UNAVAILABLE", + message: "SYSTEM_RUN_DENIED: allowlist miss", + reason: "allowlist-miss")) } if let match = allowlistMatch { @@ -381,7 +390,10 @@ fileprivate enum ExecHostExecutor { id: UUID().uuidString, ok: false, payload: nil, - error: ExecHostError(code: "UNAVAILABLE", message: "PERMISSION_MISSING: screenRecording", reason: "permission:screenRecording")) + error: ExecHostError( + code: "UNAVAILABLE", + message: "PERMISSION_MISSING: screenRecording", + reason: "permission:screenRecording")) } } @@ -621,7 +633,7 @@ private final class ExecApprovalsSocketServer: @unchecked Sendable { private func handleExecRequest(_ request: ExecHostSocketRequest) async -> ExecHostResponse { let nowMs = Int(Date().timeIntervalSince1970 * 1000) - if abs(nowMs - request.ts) > 10_000 { + if abs(nowMs - request.ts) > 10000 { return ExecHostResponse( type: "exec-res", id: request.id, diff --git a/apps/macos/Sources/Clawdbot/GatewayEnvironment.swift b/apps/macos/Sources/Clawdbot/GatewayEnvironment.swift index e66ff2e04..5817a8b3b 100644 --- a/apps/macos/Sources/Clawdbot/GatewayEnvironment.swift +++ b/apps/macos/Sources/Clawdbot/GatewayEnvironment.swift @@ -120,8 +120,8 @@ enum GatewayEnvironment { kind: .missingNode, nodeVersion: nil, gatewayVersion: nil, - requiredGateway: expectedString, - message: RuntimeLocator.describeFailure(err)) + requiredGateway: expectedString, + message: RuntimeLocator.describeFailure(err)) case let .success(runtime): let gatewayBin = CommandResolver.clawdbotExecutable() @@ -237,11 +237,10 @@ enum GatewayEnvironment { static func installGlobal(versionString: String?, statusHandler: @escaping @Sendable (String) -> Void) async { let preferred = CommandResolver.preferredPaths().joined(separator: ":") let trimmed = versionString?.trimmingCharacters(in: .whitespacesAndNewlines) - let target: String - if let trimmed, !trimmed.isEmpty { - target = trimmed + let target: String = if let trimmed, !trimmed.isEmpty { + trimmed } else { - target = "latest" + "latest" } let npm = CommandResolver.findExecutable(named: "npm") let pnpm = CommandResolver.findExecutable(named: "pnpm") diff --git a/apps/macos/Sources/Clawdbot/NodeMode/MacNodeRuntime.swift b/apps/macos/Sources/Clawdbot/NodeMode/MacNodeRuntime.swift index 7fa50cc75..3466bae90 100644 --- a/apps/macos/Sources/Clawdbot/NodeMode/MacNodeRuntime.swift +++ b/apps/macos/Sources/Clawdbot/NodeMode/MacNodeRuntime.swift @@ -482,12 +482,12 @@ actor MacNodeRuntime { let requiresAsk: Bool = { if ask == .always { return true } - if ask == .onMiss && security == .allowlist && allowlistMatch == nil && !skillAllow { return true } + if ask == .onMiss, security == .allowlist, allowlistMatch == nil, !skillAllow { return true } return false }() let approvedByAsk = params.approved == true - if requiresAsk && !approvedByAsk { + if requiresAsk, !approvedByAsk { await self.emitExecEvent( "exec.denied", payload: ExecEventPayload( @@ -502,7 +502,7 @@ actor MacNodeRuntime { message: "SYSTEM_RUN_DENIED: approval required") } - if security == .allowlist && allowlistMatch == nil && !skillAllow && !approvedByAsk { + if security == .allowlist, allowlistMatch == nil, !skillAllow, !approvedByAsk { await self.emitExecEvent( "exec.denied", payload: ExecEventPayload( @@ -558,7 +558,7 @@ actor MacNodeRuntime { env: env, timeout: timeoutSec) let combined = [result.stdout, result.stderr, result.errorMessage] - .compactMap { $0 } + .compactMap(\.self) .filter { !$0.isEmpty } .joined(separator: "\n") await self.emitExecEvent( @@ -668,7 +668,7 @@ actor MacNodeRuntime { let resolvedPath = (socketPath?.isEmpty == false) ? socketPath! : current.socket?.path?.trimmingCharacters(in: .whitespacesAndNewlines) ?? - ExecApprovalsStore.socketPath() + ExecApprovalsStore.socketPath() let resolvedToken = (token?.isEmpty == false) ? token! : current.socket?.token?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "" diff --git a/apps/macos/Sources/Clawdbot/NodeMode/MacNodeRuntimeMainActorServices.swift b/apps/macos/Sources/Clawdbot/NodeMode/MacNodeRuntimeMainActorServices.swift index ef115b178..a6e03e3e3 100644 --- a/apps/macos/Sources/Clawdbot/NodeMode/MacNodeRuntimeMainActorServices.swift +++ b/apps/macos/Sources/Clawdbot/NodeMode/MacNodeRuntimeMainActorServices.swift @@ -57,5 +57,4 @@ final class LiveMacNodeRuntimeMainActorServices: MacNodeRuntimeMainActorServices maxAgeMs: maxAgeMs, timeoutMs: timeoutMs) } - } diff --git a/apps/macos/Sources/Clawdbot/SessionMenuPreviewView.swift b/apps/macos/Sources/Clawdbot/SessionMenuPreviewView.swift index 8fd825b7d..f48840385 100644 --- a/apps/macos/Sources/Clawdbot/SessionMenuPreviewView.swift +++ b/apps/macos/Sources/Clawdbot/SessionMenuPreviewView.swift @@ -168,7 +168,6 @@ struct SessionMenuPreviewView: View { .font(.caption) .foregroundStyle(self.primaryColor) } - } enum SessionMenuPreviewLoader { @@ -182,7 +181,7 @@ enum SessionMenuPreviewLoader { static func load(sessionKey: String, maxItems: Int) async -> SessionMenuPreviewSnapshot { if let cached = await SessionPreviewCache.shared.cachedItems(for: sessionKey, maxAge: cacheMaxAgeSeconds) { - return Self.snapshot(from: cached) + return self.snapshot(from: cached) } do { diff --git a/apps/macos/Sources/Clawdbot/SystemRunSettingsView.swift b/apps/macos/Sources/Clawdbot/SystemRunSettingsView.swift index bb342a874..411568501 100644 --- a/apps/macos/Sources/Clawdbot/SystemRunSettingsView.swift +++ b/apps/macos/Sources/Clawdbot/SystemRunSettingsView.swift @@ -81,8 +81,9 @@ struct SystemRunSettingsView: View { .pickerStyle(.menu) Text(self.model.isDefaultsScope - ? "Defaults apply when an agent has no overrides. Ask controls prompt behavior; fallback is used when no companion UI is reachable." - : "Security controls whether system.run can execute on this Mac when paired as a node. Ask controls prompt behavior; fallback is used when no companion UI is reachable.") + ? "Defaults apply when an agent has no overrides. Ask controls prompt behavior; fallback is used when no companion UI is reachable." + : + "Security controls whether system.run can execute on this Mac when paired as a node. Ask controls prompt behavior; fallback is used when no companion UI is reachable.") .font(.footnote) .foregroundStyle(.tertiary) .fixedSize(horizontal: false, vertical: true) diff --git a/apps/macos/Sources/Clawdbot/UsageMenuLabelView.swift b/apps/macos/Sources/Clawdbot/UsageMenuLabelView.swift index d49bb9efd..c7f95e476 100644 --- a/apps/macos/Sources/Clawdbot/UsageMenuLabelView.swift +++ b/apps/macos/Sources/Clawdbot/UsageMenuLabelView.swift @@ -51,7 +51,6 @@ struct UsageMenuLabelView: View { .padding(.leading, 2) } } - } .padding(.vertical, 10) .padding(.leading, self.paddingLeading)