From 758f30eb7d956d617abb783b6e189a41b9aad980 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 22 Jan 2026 00:59:36 +0000 Subject: [PATCH] refactor: satisfy swiftlint --- .../Sources/Clawdbot/ExecApprovals.swift | 6 +- .../Sources/Clawdbot/GeneralSettings.swift | 1 - .../Clawdbot/NodeMode/MacNodeRuntime.swift | 165 ++++++++++++------ .../Clawdbot/PermissionsSettings.swift | 1 - .../Sources/Clawdbot/TailscaleService.swift | 2 +- .../GatewayEnvironmentTests.swift | 5 +- 6 files changed, 118 insertions(+), 62 deletions(-) diff --git a/apps/macos/Sources/Clawdbot/ExecApprovals.swift b/apps/macos/Sources/Clawdbot/ExecApprovals.swift index 122176592..ad1a18300 100644 --- a/apps/macos/Sources/Clawdbot/ExecApprovals.swift +++ b/apps/macos/Sources/Clawdbot/ExecApprovals.swift @@ -280,8 +280,10 @@ enum ExecApprovalsStore { let resolvedAgent = ExecApprovalsResolvedDefaults( security: agentEntry.security ?? wildcardEntry.security ?? resolvedDefaults.security, ask: agentEntry.ask ?? wildcardEntry.ask ?? resolvedDefaults.ask, - askFallback: agentEntry.askFallback ?? wildcardEntry.askFallback ?? resolvedDefaults.askFallback, - autoAllowSkills: agentEntry.autoAllowSkills ?? wildcardEntry.autoAllowSkills ?? resolvedDefaults.autoAllowSkills) + askFallback: agentEntry.askFallback ?? wildcardEntry.askFallback + ?? resolvedDefaults.askFallback, + autoAllowSkills: agentEntry.autoAllowSkills ?? wildcardEntry.autoAllowSkills + ?? resolvedDefaults.autoAllowSkills) let allowlist = ((wildcardEntry.allowlist ?? []) + (agentEntry.allowlist ?? [])) .map { entry in ExecAllowlistEntry( diff --git a/apps/macos/Sources/Clawdbot/GeneralSettings.swift b/apps/macos/Sources/Clawdbot/GeneralSettings.swift index b2fdac6f0..5c64f0d63 100644 --- a/apps/macos/Sources/Clawdbot/GeneralSettings.swift +++ b/apps/macos/Sources/Clawdbot/GeneralSettings.swift @@ -191,7 +191,6 @@ struct GeneralSettings: View { if self.state.connectionMode == .remote { self.remoteCard } - } } diff --git a/apps/macos/Sources/Clawdbot/NodeMode/MacNodeRuntime.swift b/apps/macos/Sources/Clawdbot/NodeMode/MacNodeRuntime.swift index 8c6f3f776..184164262 100644 --- a/apps/macos/Sources/Clawdbot/NodeMode/MacNodeRuntime.swift +++ b/apps/macos/Sources/Clawdbot/NodeMode/MacNodeRuntime.swift @@ -480,62 +480,22 @@ actor MacNodeRuntime { message: "SYSTEM_RUN_DISABLED: security=deny") } - let requiresAsk = ExecApprovalHelpers.requiresAsk( - ask: ask, - security: security, - allowlistMatch: allowlistMatch, - skillAllow: skillAllow) - - let decisionFromParams = ExecApprovalHelpers.parseDecision(params.approvalDecision) - var approvedByAsk = params.approved == true || decisionFromParams != nil - var persistAllowlist = decisionFromParams == .allowAlways - if decisionFromParams == .deny { - await self.emitExecEvent( - "exec.denied", - payload: ExecEventPayload( - sessionKey: sessionKey, - runId: runId, - host: "node", - command: displayCommand, - reason: "user-denied")) - return Self.errorResponse( - req, - code: .unavailable, - message: "SYSTEM_RUN_DENIED: user denied") - } - if requiresAsk, !approvedByAsk { - let decision = await MainActor.run { - ExecApprovalsPromptPresenter.prompt( - ExecApprovalPromptRequest( - command: displayCommand, - cwd: params.cwd, - host: "node", - security: security.rawValue, - ask: ask.rawValue, - agentId: agentId, - resolvedPath: resolution?.resolvedPath)) - } - switch decision { - case .deny: - await self.emitExecEvent( - "exec.denied", - payload: ExecEventPayload( - sessionKey: sessionKey, - runId: runId, - host: "node", - command: displayCommand, - reason: "user-denied")) - return Self.errorResponse( - req, - code: .unavailable, - message: "SYSTEM_RUN_DENIED: user denied") - case .allowAlways: - approvedByAsk = true - persistAllowlist = true - case .allowOnce: - approvedByAsk = true - } - } + let approval = await self.resolveSystemRunApproval( + req: req, + params: params, + context: ExecRunContext( + displayCommand: displayCommand, + security: security, + ask: ask, + agentId: agentId, + resolution: resolution, + allowlistMatch: allowlistMatch, + skillAllow: skillAllow, + sessionKey: sessionKey, + runId: runId)) + if let response = approval.response { return response } + let approvedByAsk = approval.approvedByAsk + let persistAllowlist = approval.persistAllowlist if persistAllowlist, security == .allowlist, let pattern = ExecApprovalHelpers.allowlistPattern(command: command, resolution: resolution) { @@ -659,6 +619,99 @@ actor MacNodeRuntime { return BridgeInvokeResponse(id: req.id, ok: true, payloadJSON: payload) } + private struct ExecApprovalOutcome { + var approvedByAsk: Bool + var persistAllowlist: Bool + var response: BridgeInvokeResponse? + } + + private struct ExecRunContext { + var displayCommand: String + var security: ExecSecurity + var ask: ExecAsk + var agentId: String? + var resolution: ExecCommandResolution? + var allowlistMatch: ExecAllowlistEntry? + var skillAllow: Bool + var sessionKey: String + var runId: String + } + + private func resolveSystemRunApproval( + req: BridgeInvokeRequest, + params: ClawdbotSystemRunParams, + context: ExecRunContext) async -> ExecApprovalOutcome + { + let requiresAsk = ExecApprovalHelpers.requiresAsk( + ask: context.ask, + security: context.security, + allowlistMatch: context.allowlistMatch, + skillAllow: context.skillAllow) + + let decisionFromParams = ExecApprovalHelpers.parseDecision(params.approvalDecision) + var approvedByAsk = params.approved == true || decisionFromParams != nil + var persistAllowlist = decisionFromParams == .allowAlways + if decisionFromParams == .deny { + await self.emitExecEvent( + "exec.denied", + payload: ExecEventPayload( + sessionKey: context.sessionKey, + runId: context.runId, + host: "node", + command: context.displayCommand, + reason: "user-denied")) + return ExecApprovalOutcome( + approvedByAsk: approvedByAsk, + persistAllowlist: persistAllowlist, + response: Self.errorResponse( + req, + code: .unavailable, + message: "SYSTEM_RUN_DENIED: user denied")) + } + + if requiresAsk, !approvedByAsk { + let decision = await MainActor.run { + ExecApprovalsPromptPresenter.prompt( + ExecApprovalPromptRequest( + command: context.displayCommand, + cwd: params.cwd, + host: "node", + security: context.security.rawValue, + ask: context.ask.rawValue, + agentId: context.agentId, + resolvedPath: context.resolution?.resolvedPath)) + } + switch decision { + case .deny: + await self.emitExecEvent( + "exec.denied", + payload: ExecEventPayload( + sessionKey: context.sessionKey, + runId: context.runId, + host: "node", + command: context.displayCommand, + reason: "user-denied")) + return ExecApprovalOutcome( + approvedByAsk: approvedByAsk, + persistAllowlist: persistAllowlist, + response: Self.errorResponse( + req, + code: .unavailable, + message: "SYSTEM_RUN_DENIED: user denied")) + case .allowAlways: + approvedByAsk = true + persistAllowlist = true + case .allowOnce: + approvedByAsk = true + } + } + + return ExecApprovalOutcome( + approvedByAsk: approvedByAsk, + persistAllowlist: persistAllowlist, + response: nil) + } + private func handleSystemExecApprovalsGet(_ req: BridgeInvokeRequest) async throws -> BridgeInvokeResponse { _ = ExecApprovalsStore.ensureFile() let snapshot = ExecApprovalsStore.readSnapshot() diff --git a/apps/macos/Sources/Clawdbot/PermissionsSettings.swift b/apps/macos/Sources/Clawdbot/PermissionsSettings.swift index 279c938ff..edce7f41b 100644 --- a/apps/macos/Sources/Clawdbot/PermissionsSettings.swift +++ b/apps/macos/Sources/Clawdbot/PermissionsSettings.swift @@ -47,7 +47,6 @@ struct PermissionStatusList: View { .font(.footnote) .padding(.top, 2) .help("Refresh status") - } } diff --git a/apps/macos/Sources/Clawdbot/TailscaleService.swift b/apps/macos/Sources/Clawdbot/TailscaleService.swift index 57424f6a0..413e8d0c8 100644 --- a/apps/macos/Sources/Clawdbot/TailscaleService.swift +++ b/apps/macos/Sources/Clawdbot/TailscaleService.swift @@ -221,6 +221,6 @@ final class TailscaleService { } nonisolated static func fallbackTailnetIPv4() -> String? { - Self.detectTailnetIPv4() + self.detectTailnetIPv4() } } diff --git a/apps/macos/Tests/ClawdbotIPCTests/GatewayEnvironmentTests.swift b/apps/macos/Tests/ClawdbotIPCTests/GatewayEnvironmentTests.swift index 36bed4aa6..9446919e7 100644 --- a/apps/macos/Tests/ClawdbotIPCTests/GatewayEnvironmentTests.swift +++ b/apps/macos/Tests/ClawdbotIPCTests/GatewayEnvironmentTests.swift @@ -48,7 +48,10 @@ import Testing @Test func expectedGatewayVersionFromStringUsesParser() { #expect(GatewayEnvironment.expectedGatewayVersion(from: "v9.1.2") == Semver(major: 9, minor: 1, patch: 2)) - #expect(GatewayEnvironment.expectedGatewayVersion(from: "2026.1.11-4") == Semver(major: 2026, minor: 1, patch: 11)) + #expect(GatewayEnvironment.expectedGatewayVersion(from: "2026.1.11-4") == Semver( + major: 2026, + minor: 1, + patch: 11)) #expect(GatewayEnvironment.expectedGatewayVersion(from: nil) == nil) } }