Files
openclaw/apps/macos/Sources/OpenClaw/QuickChatController+Testing.swift
Peter Steinberger 1859cdb231 feat(mac): Quick Chat — global-shortcut floating composer for the main session (#109720)
* feat(mac): add Quick Chat floating composer with global shortcut

- Spotlight-style non-activating key panel on Option+Space (KeyboardShortcuts
  3.0.1 exact-pinned, recorder row in Settings -> General) plus a menu bar item
- shows the main-session agent identity via agent.identity.get with a
  'main session' chip; Return sends via chat.send reusing the idempotency key
  on ambiguous retries; Cmd+Return also opens full chat; Shift+Return newline
- targeted permission strip (notifications/accessibility/screen recording)
  with a scoped 1s status poll while visible; grant flow keeps the bar alive
  and avoids PermissionMonitor's AppleScript probe
- extract shared ChatSendStatus acceptance mapping; TalkModeRuntime adopts it
- rename anchored-panel 'quick chat' wording to 'compact chat panel'; docs

* chore(mac): regenerate docs map and native i18n inventory for Quick Chat

* ci: retrigger checks after stalled push event

* chore(mac): refresh native locale artifacts for Quick Chat strings

* chore(android): regenerate locale strings for refreshed shared translations
2026-07-17 01:00:45 -07:00

51 lines
1.8 KiB
Swift

import Foundation
#if DEBUG
@MainActor
extension QuickChatController {
struct TestingSnapshot: Equatable {
let isVisible: Bool
let hasGlobalMonitor: Bool
let hasLocalMonitor: Bool
let hotkeyRegistered: Bool
}
static func exerciseForTesting() -> [TestingSnapshot] {
let model = QuickChatModel(
sessionKeyProvider: { "main" },
agentIdentityProvider: { _ in .placeholder },
sendProvider: { _, _, _ in "started" },
permissionStatusProvider: { capabilities in
Dictionary(uniqueKeysWithValues: capabilities.map { ($0, true) })
},
permissionGrantProvider: { capabilities in
Dictionary(uniqueKeysWithValues: capabilities.map { ($0, true) })
},
connectionGateProvider: { .available })
let controller = QuickChatController(
enableUI: false,
model: model,
monitoringEnabled: true,
globalMonitorInstaller: { _, _ in NSObject() },
localMonitorInstaller: { _, _ in NSObject() },
monitorClearer: { $0 = nil })
controller.start()
let started = controller.testingSnapshot
controller.present()
let presented = controller.testingSnapshot
controller.dismiss()
let dismissed = controller.testingSnapshot
controller.stop()
return [started, presented, dismissed, controller.testingSnapshot]
}
var testingSnapshot: TestingSnapshot {
TestingSnapshot(
isVisible: self.isVisible,
hasGlobalMonitor: self.hasGlobalMonitorForTesting,
hasLocalMonitor: self.hasLocalMonitorForTesting,
hotkeyRegistered: self.hotkeyRegisteredForTesting)
}
}
#endif