diff --git a/apps/macos/Sources/Clawdis/PermissionManager.swift b/apps/macos/Sources/Clawdis/PermissionManager.swift
index 7017a10ca..517825aeb 100644
--- a/apps/macos/Sources/Clawdis/PermissionManager.swift
+++ b/apps/macos/Sources/Clawdis/PermissionManager.swift
@@ -67,12 +67,27 @@ enum PermissionManager {
results[cap] = ScreenRecordingProbe.isAuthorized()
case .microphone:
- let granted = AVCaptureDevice.authorizationStatus(for: .audio) == .authorized
- if interactive, !granted {
- let ok = await AVCaptureDevice.requestAccess(for: .audio)
- results[cap] = ok
- } else {
- results[cap] = granted
+ let status = AVCaptureDevice.authorizationStatus(for: .audio)
+ switch status {
+ case .authorized:
+ results[cap] = true
+
+ case .notDetermined:
+ if interactive {
+ let ok = await AVCaptureDevice.requestAccess(for: .audio)
+ results[cap] = ok
+ } else {
+ results[cap] = false
+ }
+
+ case .denied, .restricted:
+ results[cap] = false
+ if interactive {
+ MicrophonePermissionHelper.openSettings()
+ }
+
+ @unknown default:
+ results[cap] = false
}
case .speechRecognition:
@@ -150,6 +165,21 @@ enum NotificationPermissionHelper {
}
}
+enum MicrophonePermissionHelper {
+ static func openSettings() {
+ let candidates = [
+ "x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone",
+ "x-apple.systempreferences:com.apple.preference.security",
+ ]
+
+ for candidate in candidates {
+ if let url = URL(string: candidate), NSWorkspace.shared.open(url) {
+ return
+ }
+ }
+ }
+}
+
enum AppleScriptPermission {
private static let logger = Logger(subsystem: "com.steipete.clawdis", category: "AppleScriptPermission")
diff --git a/scripts/codesign-mac-app.sh b/scripts/codesign-mac-app.sh
index 2276aa514..ca9ca0e93 100755
--- a/scripts/codesign-mac-app.sh
+++ b/scripts/codesign-mac-app.sh
@@ -53,6 +53,8 @@ cat > "$ENT_TMP_BASE" <<'PLIST'
com.apple.security.automation.apple-events
+ com.apple.security.device.audio-input
+
PLIST
@@ -64,6 +66,8 @@ cat > "$ENT_TMP_APP_BASE" <<'PLIST'
com.apple.security.automation.apple-events
+ com.apple.security.device.audio-input
+
PLIST
@@ -77,6 +81,8 @@ cat > "$ENT_TMP_APP" <<'PLIST'
com.apple.security.automation.apple-events
+ com.apple.security.device.audio-input
+
PLIST