chore(swabble): apply swiftformat

This commit is contained in:
Peter Steinberger
2025-12-09 15:36:41 +01:00
parent 336c9d6caa
commit 318457cb2c
13 changed files with 74 additions and 75 deletions

View File

@@ -33,5 +33,4 @@ let package = Package(
.product(name: "Testing", package: "swift-testing"),
]),
],
swiftLanguageModes: [.v6]
)
swiftLanguageModes: [.v6])

View File

@@ -17,11 +17,11 @@ public actor HookRunner {
public init(config: SwabbleConfig) {
self.config = config
self.hostname = Host.current().localizedName ?? "host"
hostname = Host.current().localizedName ?? "host"
}
public func shouldRun() -> Bool {
guard self.config.hook.cooldownSeconds > 0 else { return true }
guard config.hook.cooldownSeconds > 0 else { return true }
if let lastRun, Date().timeIntervalSince(lastRun) < config.hook.cooldownSeconds {
return false
}
@@ -29,23 +29,23 @@ public actor HookRunner {
}
public func run(job: HookJob) async throws {
guard self.shouldRun() else { return }
guard !self.config.hook.command.isEmpty else { throw NSError(
guard shouldRun() else { return }
guard !config.hook.command.isEmpty else { throw NSError(
domain: "Hook",
code: 1,
userInfo: [NSLocalizedDescriptionKey: "hook command not set"]) }
let prefix = self.config.hook.prefix.replacingOccurrences(of: "${hostname}", with: self.hostname)
let prefix = config.hook.prefix.replacingOccurrences(of: "${hostname}", with: hostname)
let payload = prefix + job.text
let process = Process()
process.executableURL = URL(fileURLWithPath: self.config.hook.command)
process.arguments = self.config.hook.args + [payload]
process.executableURL = URL(fileURLWithPath: config.hook.command)
process.arguments = config.hook.args + [payload]
var env = ProcessInfo.processInfo.environment
env["SWABBLE_TEXT"] = job.text
env["SWABBLE_PREFIX"] = prefix
for (k, v) in self.config.hook.env {
for (k, v) in config.hook.env {
env[k] = v
}
process.environment = env
@@ -70,6 +70,6 @@ public actor HookRunner {
try await group.next()
group.cancelAll()
}
self.lastRun = Date()
lastRun = Date()
}
}

View File

@@ -35,18 +35,18 @@ public actor SpeechPipeline {
transcriptionOptions: etiquette ? [.etiquetteReplacements] : [],
reportingOptions: [.volatileResults],
attributeOptions: [])
self.transcriber = transcriberModule
transcriber = transcriberModule
guard let analyzerFormat = await SpeechAnalyzer.bestAvailableAudioFormat(compatibleWith: [transcriberModule])
else {
throw SpeechPipelineError.analyzerFormatUnavailable
}
self.analyzer = SpeechAnalyzer(modules: [transcriberModule])
analyzer = SpeechAnalyzer(modules: [transcriberModule])
let (stream, continuation) = AsyncStream<AnalyzerInput>.makeStream()
self.inputContinuation = continuation
inputContinuation = continuation
let inputNode = self.engine.inputNode
let inputNode = engine.inputNode
let inputFormat = inputNode.outputFormat(forBus: 0)
inputNode.removeTap(onBus: 0)
inputNode.installTap(onBus: 0, bufferSize: 2048, format: inputFormat) { [weak self] buffer, _ in
@@ -55,11 +55,11 @@ public actor SpeechPipeline {
Task { await self.handleBuffer(boxed.buffer, targetFormat: analyzerFormat) }
}
self.engine.prepare()
try self.engine.start()
try await self.analyzer?.start(inputSequence: stream)
engine.prepare()
try engine.start()
try await analyzer?.start(inputSequence: stream)
guard let transcriberForStream = self.transcriber else {
guard let transcriberForStream = transcriber else {
throw SpeechPipelineError.transcriberUnavailable
}
@@ -82,18 +82,18 @@ public actor SpeechPipeline {
}
public func stop() async {
self.resultTask?.cancel()
self.inputContinuation?.finish()
self.engine.inputNode.removeTap(onBus: 0)
self.engine.stop()
try? await self.analyzer?.finalizeAndFinishThroughEndOfInput()
resultTask?.cancel()
inputContinuation?.finish()
engine.inputNode.removeTap(onBus: 0)
engine.stop()
try? await analyzer?.finalizeAndFinishThroughEndOfInput()
}
private func handleBuffer(_ buffer: AVAudioPCMBuffer, targetFormat: AVAudioFormat) async {
do {
let converted = try converter.convert(buffer, to: targetFormat)
let input = AnalyzerInput(buffer: converted)
self.inputContinuation?.yield(input)
inputContinuation?.yield(input)
} catch {
// drop on conversion failure
}

View File

@@ -27,11 +27,11 @@ public struct Logger: Sendable {
print("[\(level.rawValue.uppercased())] \(ts) | \(message)")
}
public func trace(_ msg: String) { self.log(.trace, msg) }
public func debug(_ msg: String) { self.log(.debug, msg) }
public func info(_ msg: String) { self.log(.info, msg) }
public func warn(_ msg: String) { self.log(.warn, msg) }
public func error(_ msg: String) { self.log(.error, msg) }
public func trace(_ msg: String) { log(.trace, msg) }
public func debug(_ msg: String) { log(.debug, msg) }
public func info(_ msg: String) { log(.info, msg) }
public func warn(_ msg: String) { log(.warn, msg) }
public func error(_ msg: String) { log(.error, msg) }
}
extension LogLevel {

View File

@@ -11,24 +11,24 @@ public actor TranscriptsStore {
let dir = FileManager.default.homeDirectoryForCurrentUser
.appendingPathComponent("Library/Application Support/swabble", isDirectory: true)
try? FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true)
self.fileURL = dir.appendingPathComponent("transcripts.log")
fileURL = dir.appendingPathComponent("transcripts.log")
if let data = try? Data(contentsOf: fileURL),
let text = String(data: data, encoding: .utf8)
{
self.entries = text.split(separator: "\n").map(String.init).suffix(self.limit)
entries = text.split(separator: "\n").map(String.init).suffix(limit)
}
}
public func append(text: String) {
self.entries.append(text)
if self.entries.count > self.limit {
self.entries.removeFirst(self.entries.count - self.limit)
entries.append(text)
if entries.count > limit {
entries.removeFirst(entries.count - limit)
}
let body = self.entries.joined(separator: "\n")
try? body.write(to: self.fileURL, atomically: false, encoding: .utf8)
let body = entries.joined(separator: "\n")
try? body.write(to: fileURL, atomically: false, encoding: .utf8)
}
public func latest() -> [String] { self.entries }
public func latest() -> [String] { entries }
}
extension String {

View File

@@ -14,14 +14,14 @@ struct DoctorCommand: ParsableCommand {
init() {}
init(parsed: ParsedValues) {
self.init()
if let cfg = parsed.options["config"]?.last { self.configPath = cfg }
if let cfg = parsed.options["config"]?.last { configPath = cfg }
}
mutating func run() async throws {
let auth = await SFSpeechRecognizer.authorizationStatus()
print("Speech auth: \(auth)")
do {
_ = try ConfigLoader.load(at: self.configURL)
_ = try ConfigLoader.load(at: configURL)
print("Config: OK")
} catch {
print("Config missing or invalid; run setup")
@@ -33,5 +33,5 @@ struct DoctorCommand: ParsableCommand {
print("Mics found: \(session.devices.count)")
}
private var configURL: URL? { self.configPath.map { URL(fileURLWithPath: $0) } }
private var configURL: URL? { configPath.map { URL(fileURLWithPath: $0) } }
}

View File

@@ -47,16 +47,16 @@ struct MicSet: ParsableCommand {
init() {}
init(parsed: ParsedValues) {
self.init()
if let value = parsed.positional.first, let intVal = Int(value) { self.index = intVal }
if let cfg = parsed.options["config"]?.last { self.configPath = cfg }
if let value = parsed.positional.first, let intVal = Int(value) { index = intVal }
if let cfg = parsed.options["config"]?.last { configPath = cfg }
}
mutating func run() async throws {
var cfg = try ConfigLoader.load(at: self.configURL)
cfg.audio.deviceIndex = self.index
try ConfigLoader.save(cfg, at: self.configURL)
print("saved device index \(self.index)")
var cfg = try ConfigLoader.load(at: configURL)
cfg.audio.deviceIndex = index
try ConfigLoader.save(cfg, at: configURL)
print("saved device index \(index)")
}
private var configURL: URL? { self.configPath.map { URL(fileURLWithPath: $0) } }
private var configURL: URL? { configPath.map { URL(fileURLWithPath: $0) } }
}

View File

@@ -17,19 +17,19 @@ struct ServeCommand: ParsableCommand {
init(parsed: ParsedValues) {
self.init()
if parsed.flags.contains("noWake") { self.noWake = true }
if let cfg = parsed.options["config"]?.last { self.configPath = cfg }
if parsed.flags.contains("noWake") { noWake = true }
if let cfg = parsed.options["config"]?.last { configPath = cfg }
}
mutating func run() async throws {
var cfg: SwabbleConfig
do {
cfg = try ConfigLoader.load(at: self.configURL)
cfg = try ConfigLoader.load(at: configURL)
} catch {
cfg = SwabbleConfig()
try ConfigLoader.save(cfg, at: self.configURL)
try ConfigLoader.save(cfg, at: configURL)
}
if self.noWake {
if noWake {
cfg.wake.enabled = false
}
@@ -64,7 +64,7 @@ struct ServeCommand: ParsableCommand {
}
private var configURL: URL? {
self.configPath.map { URL(fileURLWithPath: $0) }
configPath.map { URL(fileURLWithPath: $0) }
}
private static func matchesWake(text: String, cfg: SwabbleConfig) -> Bool {

View File

@@ -28,11 +28,11 @@ private enum LaunchdHelper {
"KeepAlive": true,
]
let data = try PropertyListSerialization.data(fromPropertyList: plist, format: .xml, options: 0)
try data.write(to: self.plistURL)
try data.write(to: plistURL)
}
static func removePlist() throws {
try? FileManager.default.removeItem(at: self.plistURL)
try? FileManager.default.removeItem(at: plistURL)
}
}

View File

@@ -13,14 +13,14 @@ struct SetupCommand: ParsableCommand {
init() {}
init(parsed: ParsedValues) {
self.init()
if let cfg = parsed.options["config"]?.last { self.configPath = cfg }
if let cfg = parsed.options["config"]?.last { configPath = cfg }
}
mutating func run() async throws {
let cfg = SwabbleConfig()
try ConfigLoader.save(cfg, at: self.configURL)
print("wrote config to \(self.configURL?.path ?? SwabbleConfig.defaultPath.path)")
try ConfigLoader.save(cfg, at: configURL)
print("wrote config to \(configURL?.path ?? SwabbleConfig.defaultPath.path)")
}
private var configURL: URL? { self.configPath.map { URL(fileURLWithPath: $0) } }
private var configURL: URL? { configPath.map { URL(fileURLWithPath: $0) } }
}

View File

@@ -13,11 +13,11 @@ struct StatusCommand: ParsableCommand {
init() {}
init(parsed: ParsedValues) {
self.init()
if let cfg = parsed.options["config"]?.last { self.configPath = cfg }
if let cfg = parsed.options["config"]?.last { configPath = cfg }
}
mutating func run() async throws {
let cfg = try? ConfigLoader.load(at: self.configURL)
let cfg = try? ConfigLoader.load(at: configURL)
let wake = cfg?.wake.word ?? "clawd"
let wakeEnabled = cfg?.wake.enabled ?? false
let latest = await TranscriptsStore.shared.latest().suffix(3)
@@ -30,5 +30,5 @@ struct StatusCommand: ParsableCommand {
}
}
private var configURL: URL? { self.configPath.map { URL(fileURLWithPath: $0) } }
private var configURL: URL? { configPath.map { URL(fileURLWithPath: $0) } }
}

View File

@@ -15,16 +15,16 @@ struct TestHookCommand: ParsableCommand {
init(parsed: ParsedValues) {
self.init()
if let positional = parsed.positional.first { self.text = positional }
if let cfg = parsed.options["config"]?.last { self.configPath = cfg }
if let positional = parsed.positional.first { text = positional }
if let cfg = parsed.options["config"]?.last { configPath = cfg }
}
mutating func run() async throws {
let cfg = try ConfigLoader.load(at: self.configURL)
let cfg = try ConfigLoader.load(at: configURL)
let runner = HookRunner(config: cfg)
try await runner.run(job: HookJob(text: self.text, timestamp: Date()))
try await runner.run(job: HookJob(text: text, timestamp: Date()))
print("hook invoked")
}
private var configURL: URL? { self.configPath.map { URL(fileURLWithPath: $0) } }
private var configURL: URL? { configPath.map { URL(fileURLWithPath: $0) } }
}

View File

@@ -24,12 +24,12 @@ struct TranscribeCommand: ParsableCommand {
init(parsed: ParsedValues) {
self.init()
if let positional = parsed.positional.first { self.inputFile = positional }
if let loc = parsed.options["locale"]?.last { self.locale = loc }
if parsed.flags.contains("censor") { self.censor = true }
if let out = parsed.options["output"]?.last { self.outputFile = out }
if let fmt = parsed.options["format"]?.last { self.format = fmt }
if let len = parsed.options["maxLength"]?.last, let intVal = Int(len) { self.maxLength = intVal }
if let positional = parsed.positional.first { inputFile = positional }
if let loc = parsed.options["locale"]?.last { locale = loc }
if parsed.flags.contains("censor") { censor = true }
if let out = parsed.options["output"]?.last { outputFile = out }
if let fmt = parsed.options["format"]?.last { format = fmt }
if let len = parsed.options["maxLength"]?.last, let intVal = Int(len) { maxLength = intVal }
}
mutating func run() async throws {
@@ -51,7 +51,7 @@ struct TranscribeCommand: ParsableCommand {
transcript += result.text
}
let output = outputFormat.text(for: transcript, maxLength: self.maxLength)
let output = outputFormat.text(for: transcript, maxLength: maxLength)
if let path = outputFile {
try output.write(to: URL(fileURLWithPath: path), atomically: false, encoding: .utf8)
} else {