Browse Source

fix: precise disambiguation between Antigravity (white icon) and Antigravity IDE (black icon)

main
Ali Alavi 14 hours ago
parent
commit
fa152e16d7
  1. 53
      src/VoiceCommandExecutor.swift

53
src/VoiceCommandExecutor.swift

@ -420,17 +420,22 @@ public final class VoiceCommandExecutor {
let hasAnti = normalized.contains("انتی") || normalized.contains("anti") let hasAnti = normalized.contains("انتی") || normalized.contains("anti")
let hasGravity = normalized.contains("گراویتی") || normalized.contains("گرویتی") || normalized.contains("gravity") let hasGravity = normalized.contains("گراویتی") || normalized.contains("گرویتی") || normalized.contains("gravity")
if (hasAnti && hasGravity) || normalized.contains("antigravity") || normalized.contains("انتیگراویتی") || normalized.contains("انتیگرویتی") {
guard (hasAnti && hasGravity) || normalized.contains("antigravity") || normalized.contains("انتیگراویتی") || normalized.contains("انتیگرویتی") else {
return nil
}
// Strict explicit check for IDE / Editor (Black Icon App)
let isIDE = normalized.contains("ای دی ای") || let isIDE = normalized.contains("ای دی ای") ||
normalized.contains("ایدی ای") || normalized.contains("ایدی ای") ||
normalized.contains("ایدیای") || normalized.contains("ایدیای") ||
normalized.contains("آیدی ای") ||
normalized.contains("ide") || normalized.contains("ide") ||
normalized.contains("ادیتور") ||
normalized.contains("کد")
normalized.contains("ادیتور")
// If IDE is mentioned -> "Antigravity IDE" (Black icon)
// If standalone / "2" -> "Antigravity" (White icon app, Antigravity 2)
return isIDE ? "Antigravity IDE" : "Antigravity" return isIDE ? "Antigravity IDE" : "Antigravity"
} }
return nil
}
// MARK: - Web Search & Direct Navigation // MARK: - Web Search & Direct Navigation
private func handleWebSearchAndNavigation(normalized: String, original: String) -> String? { private func handleWebSearchAndNavigation(normalized: String, original: String) -> String? {
@ -660,6 +665,7 @@ public final class VoiceCommandExecutor {
private func parseAppAndNumber(normalized: String) -> (appName: String, number: Int, type: String)? { private func parseAppAndNumber(normalized: String) -> (appName: String, number: Int, type: String)? {
var targetApp: String? = nil var targetApp: String? = nil
var isTelegram = false var isTelegram = false
var isAntigravity = false
if normalized.contains("تلگرام") || normalized.contains("telegram") { if normalized.contains("تلگرام") || normalized.contains("telegram") {
targetApp = "Telegram" targetApp = "Telegram"
@ -671,6 +677,7 @@ public final class VoiceCommandExecutor {
} else if normalized.contains("سافاری") || normalized.contains("safari") { } else if normalized.contains("سافاری") || normalized.contains("safari") {
targetApp = "Safari" targetApp = "Safari"
} else if normalized.contains("انتی") && (normalized.contains("گراویتی") || normalized.contains("گرویتی")) { } else if normalized.contains("انتی") && (normalized.contains("گراویتی") || normalized.contains("گرویتی")) {
isAntigravity = true
if normalized.contains("ای دی ای") || normalized.contains("ایدی ای") || normalized.contains("ide") { if normalized.contains("ای دی ای") || normalized.contains("ایدی ای") || normalized.contains("ide") {
targetApp = "Antigravity IDE" targetApp = "Antigravity IDE"
} else { } else {
@ -683,6 +690,12 @@ public final class VoiceCommandExecutor {
} }
guard let app = targetApp else { return nil } guard let app = targetApp else { return nil }
// For Antigravity: "آنتی گرویتی ۲" / "antigravity 2" without explicit "تب"/"tab" refers to Antigravity.app (the white icon app)!
if isAntigravity && !normalized.contains("تب") && !normalized.contains("tab") {
return nil
}
guard let num = extractTrailingOrEmbeddedNumber(from: normalized) else { return nil } guard let num = extractTrailingOrEmbeddedNumber(from: normalized) else { return nil }
let type = isTelegram ? "Account" : "Tab" let type = isTelegram ? "Account" : "Tab"
@ -1073,13 +1086,41 @@ public final class VoiceCommandExecutor {
private func launchOrActivateApp(named appName: String) { private func launchOrActivateApp(named appName: String) {
let ws = NSWorkspace.shared let ws = NSWorkspace.shared
// 1. Precise bundle identifier map (prevents "Antigravity" substring matching "Antigravity IDE")
let bundleIDMap: [String: String] = [
"Antigravity": "com.google.antigravity",
"Antigravity IDE": "com.google.antigravity-ide",
"Telegram": "com.tdesktop.Telegram",
"Firefox": "org.mozilla.firefox",
"Google Chrome": "com.google.Chrome",
"Safari": "com.apple.Safari"
]
if let bid = bundleIDMap[appName] {
// Check currently running app by exact bundleIdentifier
if let running = ws.runningApplications.first(where: { $0.bundleIdentifier == bid }) {
running.activate(options: [.activateIgnoringOtherApps])
return
}
// If not running, launch via exact URL
if let appURL = ws.urlForApplication(withBundleIdentifier: bid) {
let conf = NSWorkspace.OpenConfiguration()
conf.activates = true
ws.openApplication(at: appURL, configuration: conf, completionHandler: nil)
return
}
}
// 2. Strict EXACT localized name match (NOT contains!)
if let running = ws.runningApplications.first(where: { if let running = ws.runningApplications.first(where: {
$0.localizedName?.localizedCaseInsensitiveContains(appName) == true
$0.localizedName?.caseInsensitiveCompare(appName) == .orderedSame
}) { }) {
running.activate(options: [.activateIgnoringOtherApps]) running.activate(options: [.activateIgnoringOtherApps])
return return
} }
// 3. Fallback: launch via /usr/bin/open -a with exact app name
let task = Process() let task = Process()
task.executableURL = URL(fileURLWithPath: "/usr/bin/open") task.executableURL = URL(fileURLWithPath: "/usr/bin/open")
task.arguments = ["-a", appName] task.arguments = ["-a", appName]

Loading…
Cancel
Save