From 8913bfbcd517157545170f94258de854f99d8007 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 7 Jan 2026 19:30:01 +0000 Subject: [PATCH] refactor(macos): drop duplicate AnyCodable --- .../Sources/Clawdbot/AgentEventsWindow.swift | 1 + apps/macos/Sources/Clawdbot/AnyCodable.swift | 54 ------------------- .../Clawdbot/Bridge/BridgeServer.swift | 22 ++++---- .../Sources/Clawdbot/ClawdbotConfigFile.swift | 1 + .../Sources/Clawdbot/ClawdbotPaths.swift | 6 +-- apps/macos/Sources/Clawdbot/ConfigStore.swift | 1 + .../Clawdbot/CronJobEditor+Helpers.swift | 1 + .../Sources/Clawdbot/CronJobEditor.swift | 1 + .../Clawdbot/CronSettings+Actions.swift | 1 + .../Sources/Clawdbot/WorkActivityStore.swift | 11 ++-- .../AgentEventStoreTests.swift | 5 +- .../AnyCodableEncodingTests.swift | 2 +- .../CronJobEditorSmokeTests.swift | 2 +- .../ClawdbotIPCTests/CronModelsTests.swift | 2 +- .../GatewayChannelConfigureTests.swift | 10 ++-- .../GatewayEnvironmentTests.swift | 18 ++++++- .../LowCoverageHelperTests.swift | 3 +- .../LowCoverageViewSmokeTests.swift | 1 + .../MenuSessionsInjectorTests.swift | 4 +- .../ClawdbotIPCTests/SessionDataTests.swift | 2 +- .../SettingsViewSmokeTests.swift | 2 +- .../SkillsSettingsSmokeTests.swift | 1 + .../VoiceWakeForwarderTests.swift | 2 +- .../WorkActivityStoreTests.swift | 1 + 24 files changed, 64 insertions(+), 90 deletions(-) delete mode 100644 apps/macos/Sources/Clawdbot/AnyCodable.swift diff --git a/apps/macos/Sources/Clawdbot/AgentEventsWindow.swift b/apps/macos/Sources/Clawdbot/AgentEventsWindow.swift index f37961ae3..e3ccc87bc 100644 --- a/apps/macos/Sources/Clawdbot/AgentEventsWindow.swift +++ b/apps/macos/Sources/Clawdbot/AgentEventsWindow.swift @@ -1,3 +1,4 @@ +import ClawdbotProtocol import SwiftUI @MainActor diff --git a/apps/macos/Sources/Clawdbot/AnyCodable.swift b/apps/macos/Sources/Clawdbot/AnyCodable.swift deleted file mode 100644 index 7c9a4668d..000000000 --- a/apps/macos/Sources/Clawdbot/AnyCodable.swift +++ /dev/null @@ -1,54 +0,0 @@ -import Foundation - -/// Lightweight `Codable` wrapper that round-trips heterogeneous JSON payloads. -/// Marked `@unchecked Sendable` because it can hold reference types. -struct AnyCodable: Codable, @unchecked Sendable { - let value: Any - - init(_ value: Any) { self.value = value } - - init(from decoder: Decoder) throws { - let container = try decoder.singleValueContainer() - if let intVal = try? container.decode(Int.self) { self.value = intVal; return } - if let doubleVal = try? container.decode(Double.self) { self.value = doubleVal; return } - if let boolVal = try? container.decode(Bool.self) { self.value = boolVal; return } - if let stringVal = try? container.decode(String.self) { self.value = stringVal; return } - if container.decodeNil() { self.value = NSNull(); return } - if let dict = try? container.decode([String: AnyCodable].self) { self.value = dict; return } - if let array = try? container.decode([AnyCodable].self) { self.value = array; return } - throw DecodingError.dataCorruptedError( - in: container, - debugDescription: "Unsupported type") - } - - func encode(to encoder: Encoder) throws { - var container = encoder.singleValueContainer() - switch self.value { - case let intVal as Int: try container.encode(intVal) - case let doubleVal as Double: try container.encode(doubleVal) - case let boolVal as Bool: try container.encode(boolVal) - case let stringVal as String: try container.encode(stringVal) - case is NSNull: try container.encodeNil() - case let dict as [String: AnyCodable]: try container.encode(dict) - case let array as [AnyCodable]: try container.encode(array) - case let dict as [String: Any]: - try container.encode(dict.mapValues { AnyCodable($0) }) - case let array as [Any]: - try container.encode(array.map { AnyCodable($0) }) - case let dict as NSDictionary: - var converted: [String: AnyCodable] = [:] - for (k, v) in dict { - guard let key = k as? String else { continue } - converted[key] = AnyCodable(v) - } - try container.encode(converted) - case let array as NSArray: - try container.encode(array.map { AnyCodable($0) }) - default: - let context = EncodingError.Context( - codingPath: encoder.codingPath, - debugDescription: "Unsupported type") - throw EncodingError.invalidValue(self.value, context) - } - } -} diff --git a/apps/macos/Sources/Clawdbot/Bridge/BridgeServer.swift b/apps/macos/Sources/Clawdbot/Bridge/BridgeServer.swift index 60d01459a..4b71e6dec 100644 --- a/apps/macos/Sources/Clawdbot/Bridge/BridgeServer.swift +++ b/apps/macos/Sources/Clawdbot/Bridge/BridgeServer.swift @@ -229,7 +229,7 @@ actor BridgeServer { error: BridgeRPCError(code: "FORBIDDEN", message: "Method not allowed")) } - let params: [String: AnyCodable]? + let params: [String: ClawdbotProtocol.AnyCodable]? if let json = req.paramsJSON?.trimmingCharacters(in: .whitespacesAndNewlines), !json.isEmpty { guard let data = json.data(using: .utf8) else { return BridgeRPCResponse( @@ -238,7 +238,7 @@ actor BridgeServer { error: BridgeRPCError(code: "INVALID_REQUEST", message: "paramsJSON not UTF-8")) } do { - params = try JSONDecoder().decode([String: AnyCodable].self, from: data) + params = try JSONDecoder().decode([String: ClawdbotProtocol.AnyCodable].self, from: data) } catch { return BridgeRPCResponse( id: req.id, @@ -360,16 +360,16 @@ actor BridgeServer { "reason \(reason)", ].compactMap(\.self).joined(separator: " ยท ") - var params: [String: AnyCodable] = [ - "text": AnyCodable(summary), - "instanceId": AnyCodable(nodeId), - "host": AnyCodable(host), - "mode": AnyCodable("node"), - "reason": AnyCodable(reason), - "tags": AnyCodable(tags), + var params: [String: ClawdbotProtocol.AnyCodable] = [ + "text": ClawdbotProtocol.AnyCodable(summary), + "instanceId": ClawdbotProtocol.AnyCodable(nodeId), + "host": ClawdbotProtocol.AnyCodable(host), + "mode": ClawdbotProtocol.AnyCodable("node"), + "reason": ClawdbotProtocol.AnyCodable(reason), + "tags": ClawdbotProtocol.AnyCodable(tags), ] - if let ip { params["ip"] = AnyCodable(ip) } - if let version { params["version"] = AnyCodable(version) } + if let ip { params["ip"] = ClawdbotProtocol.AnyCodable(ip) } + if let version { params["version"] = ClawdbotProtocol.AnyCodable(version) } await GatewayConnection.shared.sendSystemEvent(params) } diff --git a/apps/macos/Sources/Clawdbot/ClawdbotConfigFile.swift b/apps/macos/Sources/Clawdbot/ClawdbotConfigFile.swift index 433b3e1c8..a5fad5f0a 100644 --- a/apps/macos/Sources/Clawdbot/ClawdbotConfigFile.swift +++ b/apps/macos/Sources/Clawdbot/ClawdbotConfigFile.swift @@ -1,3 +1,4 @@ +import ClawdbotProtocol import Foundation enum ClawdbotConfigFile { diff --git a/apps/macos/Sources/Clawdbot/ClawdbotPaths.swift b/apps/macos/Sources/Clawdbot/ClawdbotPaths.swift index 9cd7985ea..3e32782c0 100644 --- a/apps/macos/Sources/Clawdbot/ClawdbotPaths.swift +++ b/apps/macos/Sources/Clawdbot/ClawdbotPaths.swift @@ -3,9 +3,9 @@ import Foundation enum ClawdbotEnv { static func path(_ key: String) -> String? { // Normalize env overrides once so UI + file IO stay consistent. - guard let value = ProcessInfo.processInfo.environment[key]? - .trimmingCharacters(in: .whitespacesAndNewlines), - !value.isEmpty + guard let raw = getenv(key) else { return nil } + let value = String(cString: raw).trimmingCharacters(in: .whitespacesAndNewlines) + guard !value.isEmpty else { return nil } diff --git a/apps/macos/Sources/Clawdbot/ConfigStore.swift b/apps/macos/Sources/Clawdbot/ConfigStore.swift index 9090dd1d8..93b10cff4 100644 --- a/apps/macos/Sources/Clawdbot/ConfigStore.swift +++ b/apps/macos/Sources/Clawdbot/ConfigStore.swift @@ -1,3 +1,4 @@ +import ClawdbotProtocol import Foundation enum ConfigStore { diff --git a/apps/macos/Sources/Clawdbot/CronJobEditor+Helpers.swift b/apps/macos/Sources/Clawdbot/CronJobEditor+Helpers.swift index ec07cc5e4..877c0c6c7 100644 --- a/apps/macos/Sources/Clawdbot/CronJobEditor+Helpers.swift +++ b/apps/macos/Sources/Clawdbot/CronJobEditor+Helpers.swift @@ -1,3 +1,4 @@ +import ClawdbotProtocol import Foundation import SwiftUI diff --git a/apps/macos/Sources/Clawdbot/CronJobEditor.swift b/apps/macos/Sources/Clawdbot/CronJobEditor.swift index 93d2615bf..144368bf1 100644 --- a/apps/macos/Sources/Clawdbot/CronJobEditor.swift +++ b/apps/macos/Sources/Clawdbot/CronJobEditor.swift @@ -1,3 +1,4 @@ +import ClawdbotProtocol import SwiftUI struct CronJobEditor: View { diff --git a/apps/macos/Sources/Clawdbot/CronSettings+Actions.swift b/apps/macos/Sources/Clawdbot/CronSettings+Actions.swift index 8ae63704b..0de686bad 100644 --- a/apps/macos/Sources/Clawdbot/CronSettings+Actions.swift +++ b/apps/macos/Sources/Clawdbot/CronSettings+Actions.swift @@ -1,3 +1,4 @@ +import ClawdbotProtocol import Foundation extension CronSettings { diff --git a/apps/macos/Sources/Clawdbot/WorkActivityStore.swift b/apps/macos/Sources/Clawdbot/WorkActivityStore.swift index 47d241ace..9ab5b93d4 100644 --- a/apps/macos/Sources/Clawdbot/WorkActivityStore.swift +++ b/apps/macos/Sources/Clawdbot/WorkActivityStore.swift @@ -1,4 +1,5 @@ import ClawdbotKit +import ClawdbotProtocol import Foundation import Observation import SwiftUI @@ -53,7 +54,7 @@ final class WorkActivityStore { phase: String, name: String?, meta: String?, - args: [String: AnyCodable]?) + args: [String: ClawdbotProtocol.AnyCodable]?) { let toolKind = Self.mapToolKind(name) let label = Self.buildLabel(name: name, meta: meta, args: args) @@ -211,7 +212,7 @@ final class WorkActivityStore { private static func buildLabel( name: String?, meta: String?, - args: [String: AnyCodable]?) -> String + args: [String: ClawdbotProtocol.AnyCodable]?) -> String { let wrappedArgs = self.wrapToolArgs(args) let display = ToolDisplayRegistry.resolve(name: name ?? "tool", args: wrappedArgs, meta: meta) @@ -221,17 +222,17 @@ final class WorkActivityStore { return display.label } - private static func wrapToolArgs(_ args: [String: AnyCodable]?) -> ClawdbotKit.AnyCodable? { + private static func wrapToolArgs(_ args: [String: ClawdbotProtocol.AnyCodable]?) -> ClawdbotKit.AnyCodable? { guard let args else { return nil } let converted: [String: Any] = args.mapValues { self.unwrapJSONValue($0.value) } return ClawdbotKit.AnyCodable(converted) } private static func unwrapJSONValue(_ value: Any) -> Any { - if let dict = value as? [String: AnyCodable] { + if let dict = value as? [String: ClawdbotProtocol.AnyCodable] { return dict.mapValues { self.unwrapJSONValue($0.value) } } - if let array = value as? [AnyCodable] { + if let array = value as? [ClawdbotProtocol.AnyCodable] { return array.map { self.unwrapJSONValue($0.value) } } if let dict = value as? [String: Any] { diff --git a/apps/macos/Tests/ClawdbotIPCTests/AgentEventStoreTests.swift b/apps/macos/Tests/ClawdbotIPCTests/AgentEventStoreTests.swift index 1353c8b4f..1b0e75207 100644 --- a/apps/macos/Tests/ClawdbotIPCTests/AgentEventStoreTests.swift +++ b/apps/macos/Tests/ClawdbotIPCTests/AgentEventStoreTests.swift @@ -1,5 +1,6 @@ import Foundation import Testing +import ClawdbotProtocol @testable import Clawdbot @Suite @@ -15,7 +16,7 @@ struct AgentEventStoreTests { seq: 1, stream: "test", ts: 0, - data: [:] as [String: AnyCodable], + data: [:] as [String: ClawdbotProtocol.AnyCodable], summary: nil)) #expect(store.events.count == 1) @@ -32,7 +33,7 @@ struct AgentEventStoreTests { seq: i, stream: "test", ts: Double(i), - data: [:] as [String: AnyCodable], + data: [:] as [String: ClawdbotProtocol.AnyCodable], summary: nil)) } diff --git a/apps/macos/Tests/ClawdbotIPCTests/AnyCodableEncodingTests.swift b/apps/macos/Tests/ClawdbotIPCTests/AnyCodableEncodingTests.swift index 897ab6433..cb1cec109 100644 --- a/apps/macos/Tests/ClawdbotIPCTests/AnyCodableEncodingTests.swift +++ b/apps/macos/Tests/ClawdbotIPCTests/AnyCodableEncodingTests.swift @@ -12,7 +12,7 @@ import Testing "null": NSNull(), ] - let data = try JSONEncoder().encode(Clawdbot.AnyCodable(payload)) + let data = try JSONEncoder().encode(ClawdbotProtocol.AnyCodable(payload)) let obj = try #require(JSONSerialization.jsonObject(with: data) as? [String: Any]) #expect(obj["tags"] as? [String] == ["node", "ios"]) diff --git a/apps/macos/Tests/ClawdbotIPCTests/CronJobEditorSmokeTests.swift b/apps/macos/Tests/ClawdbotIPCTests/CronJobEditorSmokeTests.swift index efa369e5c..ea5f86579 100644 --- a/apps/macos/Tests/ClawdbotIPCTests/CronJobEditorSmokeTests.swift +++ b/apps/macos/Tests/ClawdbotIPCTests/CronJobEditorSmokeTests.swift @@ -35,7 +35,7 @@ struct CronJobEditorSmokeTests { thinking: "low", timeoutSeconds: 120, deliver: true, - channel: "whatsapp", + provider: "whatsapp", to: "+15551234567", bestEffortDeliver: true), isolation: CronIsolation(postToMainPrefix: "Cron"), diff --git a/apps/macos/Tests/ClawdbotIPCTests/CronModelsTests.swift b/apps/macos/Tests/ClawdbotIPCTests/CronModelsTests.swift index fe478ac14..81ef2e96e 100644 --- a/apps/macos/Tests/ClawdbotIPCTests/CronModelsTests.swift +++ b/apps/macos/Tests/ClawdbotIPCTests/CronModelsTests.swift @@ -31,7 +31,7 @@ struct CronModelsTests { thinking: "low", timeoutSeconds: 15, deliver: true, - channel: "whatsapp", + provider: "whatsapp", to: "+15551234567", bestEffortDeliver: false) let data = try JSONEncoder().encode(payload) diff --git a/apps/macos/Tests/ClawdbotIPCTests/GatewayChannelConfigureTests.swift b/apps/macos/Tests/ClawdbotIPCTests/GatewayChannelConfigureTests.swift index 7893dafe7..22c83d4fd 100644 --- a/apps/macos/Tests/ClawdbotIPCTests/GatewayChannelConfigureTests.swift +++ b/apps/macos/Tests/ClawdbotIPCTests/GatewayChannelConfigureTests.swift @@ -170,7 +170,7 @@ import Testing let url = URL(string: "ws://example.invalid")! let cfg = ConfigSource(token: nil) let conn = GatewayConnection( - configProvider: { (url, cfg.snapshotToken()) }, + configProvider: { (url: url, token: cfg.snapshotToken(), password: nil) }, sessionBox: WebSocketSessionBox(session: session)) _ = try await conn.request(method: "status", params: nil) @@ -186,7 +186,7 @@ import Testing let url = URL(string: "ws://example.invalid")! let cfg = ConfigSource(token: "a") let conn = GatewayConnection( - configProvider: { (url, cfg.snapshotToken()) }, + configProvider: { (url: url, token: cfg.snapshotToken(), password: nil) }, sessionBox: WebSocketSessionBox(session: session)) _ = try await conn.request(method: "status", params: nil) @@ -203,7 +203,7 @@ import Testing let url = URL(string: "ws://example.invalid")! let cfg = ConfigSource(token: nil) let conn = GatewayConnection( - configProvider: { (url, cfg.snapshotToken()) }, + configProvider: { (url: url, token: cfg.snapshotToken(), password: nil) }, sessionBox: WebSocketSessionBox(session: session)) async let r1: Data = conn.request(method: "status", params: nil) @@ -218,7 +218,7 @@ import Testing let url = URL(string: "ws://example.invalid")! let cfg = ConfigSource(token: nil) let conn = GatewayConnection( - configProvider: { (url, cfg.snapshotToken()) }, + configProvider: { (url: url, token: cfg.snapshotToken(), password: nil) }, sessionBox: WebSocketSessionBox(session: session)) _ = try await conn.request(method: "status", params: nil) @@ -239,7 +239,7 @@ import Testing let url = URL(string: "ws://example.invalid")! let cfg = ConfigSource(token: nil) let conn = GatewayConnection( - configProvider: { (url, cfg.snapshotToken()) }, + configProvider: { (url: url, token: cfg.snapshotToken(), password: nil) }, sessionBox: WebSocketSessionBox(session: session)) let stream = await conn.subscribe(bufferingNewest: 10) diff --git a/apps/macos/Tests/ClawdbotIPCTests/GatewayEnvironmentTests.swift b/apps/macos/Tests/ClawdbotIPCTests/GatewayEnvironmentTests.swift index 0e4e35e6f..e27df5b21 100644 --- a/apps/macos/Tests/ClawdbotIPCTests/GatewayEnvironmentTests.swift +++ b/apps/macos/Tests/ClawdbotIPCTests/GatewayEnvironmentTests.swift @@ -20,11 +20,27 @@ import Testing } @Test func gatewayPortDefaultsAndRespectsOverride() { + let envKey = "CLAWDBOT_CONFIG_PATH" + let previousEnv = getenv(envKey).map { String(cString: $0) } + let configPath = FileManager.default.temporaryDirectory + .appendingPathComponent("clawdbot-test-config-\(UUID().uuidString).json") + .path + setenv(envKey, configPath, 1) + defer { + if let previousEnv { + setenv(envKey, previousEnv, 1) + } else { + unsetenv(envKey) + } + } + + UserDefaults.standard.removeObject(forKey: "gatewayPort") + defer { UserDefaults.standard.removeObject(forKey: "gatewayPort") } + let defaultPort = GatewayEnvironment.gatewayPort() #expect(defaultPort == 18789) UserDefaults.standard.set(19999, forKey: "gatewayPort") - defer { UserDefaults.standard.removeObject(forKey: "gatewayPort") } #expect(GatewayEnvironment.gatewayPort() == 19999) } diff --git a/apps/macos/Tests/ClawdbotIPCTests/LowCoverageHelperTests.swift b/apps/macos/Tests/ClawdbotIPCTests/LowCoverageHelperTests.swift index e7b745b08..080a29589 100644 --- a/apps/macos/Tests/ClawdbotIPCTests/LowCoverageHelperTests.swift +++ b/apps/macos/Tests/ClawdbotIPCTests/LowCoverageHelperTests.swift @@ -1,6 +1,7 @@ import AppKit import Foundation import Testing +import ClawdbotProtocol @testable import Clawdbot @@ -23,7 +24,7 @@ struct LowCoverageHelperTests { #expect(dict["list"]?.arrayValue?.count == 2) let foundation = any.foundationValue as? [String: Any] - #expect(foundation?["title"] as? String == "Hello") + #expect((foundation?["title"] as? String) == "Hello") } @Test func attributedStringStripsForegroundColor() { diff --git a/apps/macos/Tests/ClawdbotIPCTests/LowCoverageViewSmokeTests.swift b/apps/macos/Tests/ClawdbotIPCTests/LowCoverageViewSmokeTests.swift index 98018035b..27aff597e 100644 --- a/apps/macos/Tests/ClawdbotIPCTests/LowCoverageViewSmokeTests.swift +++ b/apps/macos/Tests/ClawdbotIPCTests/LowCoverageViewSmokeTests.swift @@ -1,6 +1,7 @@ import AppKit import SwiftUI import Testing +import ClawdbotProtocol @testable import Clawdbot diff --git a/apps/macos/Tests/ClawdbotIPCTests/MenuSessionsInjectorTests.swift b/apps/macos/Tests/ClawdbotIPCTests/MenuSessionsInjectorTests.swift index 2e5bafcfd..cae8b7be4 100644 --- a/apps/macos/Tests/ClawdbotIPCTests/MenuSessionsInjectorTests.swift +++ b/apps/macos/Tests/ClawdbotIPCTests/MenuSessionsInjectorTests.swift @@ -30,7 +30,7 @@ struct MenuSessionsInjectorTests { key: "main", kind: .direct, displayName: nil, - surface: nil, + provider: nil, subject: nil, room: nil, space: nil, @@ -47,7 +47,7 @@ struct MenuSessionsInjectorTests { key: "discord:group:alpha", kind: .group, displayName: nil, - surface: nil, + provider: nil, subject: nil, room: nil, space: nil, diff --git a/apps/macos/Tests/ClawdbotIPCTests/SessionDataTests.swift b/apps/macos/Tests/ClawdbotIPCTests/SessionDataTests.swift index 96f21ab0c..d52c9aecb 100644 --- a/apps/macos/Tests/ClawdbotIPCTests/SessionDataTests.swift +++ b/apps/macos/Tests/ClawdbotIPCTests/SessionDataTests.swift @@ -28,7 +28,7 @@ struct SessionDataTests { key: "user@example.com", kind: .direct, displayName: nil, - surface: nil, + provider: nil, subject: nil, room: nil, space: nil, diff --git a/apps/macos/Tests/ClawdbotIPCTests/SettingsViewSmokeTests.swift b/apps/macos/Tests/ClawdbotIPCTests/SettingsViewSmokeTests.swift index d3fe9e07d..c59aba43a 100644 --- a/apps/macos/Tests/ClawdbotIPCTests/SettingsViewSmokeTests.swift +++ b/apps/macos/Tests/ClawdbotIPCTests/SettingsViewSmokeTests.swift @@ -45,7 +45,7 @@ struct SettingsViewSmokeTests { thinking: "low", timeoutSeconds: 30, deliver: true, - channel: "sms", + provider: "sms", to: "+15551234567", bestEffortDeliver: true), isolation: CronIsolation(postToMainPrefix: "[cron] "), diff --git a/apps/macos/Tests/ClawdbotIPCTests/SkillsSettingsSmokeTests.swift b/apps/macos/Tests/ClawdbotIPCTests/SkillsSettingsSmokeTests.swift index afa028dcf..f2d8a61bf 100644 --- a/apps/macos/Tests/ClawdbotIPCTests/SkillsSettingsSmokeTests.swift +++ b/apps/macos/Tests/ClawdbotIPCTests/SkillsSettingsSmokeTests.swift @@ -1,4 +1,5 @@ import Testing +import ClawdbotProtocol @testable import Clawdbot @Suite(.serialized) diff --git a/apps/macos/Tests/ClawdbotIPCTests/VoiceWakeForwarderTests.swift b/apps/macos/Tests/ClawdbotIPCTests/VoiceWakeForwarderTests.swift index b8318c3fe..35a96626b 100644 --- a/apps/macos/Tests/ClawdbotIPCTests/VoiceWakeForwarderTests.swift +++ b/apps/macos/Tests/ClawdbotIPCTests/VoiceWakeForwarderTests.swift @@ -17,6 +17,6 @@ import Testing #expect(opts.thinking == "low") #expect(opts.deliver == true) #expect(opts.to == nil) - #expect(opts.channel == .last) + #expect(opts.provider == .last) } } diff --git a/apps/macos/Tests/ClawdbotIPCTests/WorkActivityStoreTests.swift b/apps/macos/Tests/ClawdbotIPCTests/WorkActivityStoreTests.swift index 50a4e69d6..983c394b3 100644 --- a/apps/macos/Tests/ClawdbotIPCTests/WorkActivityStoreTests.swift +++ b/apps/macos/Tests/ClawdbotIPCTests/WorkActivityStoreTests.swift @@ -1,5 +1,6 @@ import Foundation import Testing +import ClawdbotProtocol @testable import Clawdbot @Suite