From 3d749e8139c90f7dc477d450d48dae940a221113 Mon Sep 17 00:00:00 2001 From: BigMarc Date: Thu, 18 Jun 2026 16:49:55 +0200 Subject: [PATCH] feat: Implement LiveMonitor for real-time grammar and spelling checks across applications - Added LiveMonitor class to scan text areas in the frontmost window for grammar and spelling issues. - Introduced DetectedField struct to represent text areas with issues, including suggestions for corrections. - Implemented functionality to apply corrections and dismiss suggestions. - Added Permissions class to manage Accessibility permissions required for monitoring. - Created SnippetStore for managing text-expansion snippets, including persistence to UserDefaults. - Developed TextCapture class to read and write text from the frontmost application using Accessibility API and clipboard fallback. - Implemented TextFieldScanner to traverse the Accessibility tree and collect editable text elements. - Added TextReplacementCoordinator to orchestrate the text correction process. - Integrated UpdaterManager for handling application updates using Sparkle. - Created comprehensive unit tests for various components, including grammar corrections and entitlement checks. --- AppSupport/{GrammaGem.entitlements => GrammarGem.entitlements} | 0 Sources/{GrammaGem => GrammarGem}/AI/AIEngine.swift | 0 Sources/{GrammaGem => GrammarGem}/AI/CustomModesStore.swift | 0 Sources/{GrammaGem => GrammarGem}/AI/MLXEngine.swift | 0 Sources/{GrammaGem => GrammarGem}/AI/ModeRegistry.swift | 0 Sources/{GrammaGem => GrammarGem}/AI/ModelManager.swift | 0 Sources/{GrammaGem => GrammarGem}/App/AppState.swift | 0 Sources/{GrammaGem => GrammarGem}/App/AskView.swift | 0 .../App/GrammaGemApp.swift => GrammarGem/App/GrammarGemApp.swift} | 0 .../{GrammaGem => GrammarGem}/App/MainWindow/AccountViews.swift | 0 .../{GrammaGem => GrammarGem}/App/MainWindow/DashboardView.swift | 0 Sources/{GrammaGem => GrammarGem}/App/MainWindow/DataViews.swift | 0 .../{GrammaGem => GrammarGem}/App/MainWindow/DevicesView.swift | 0 .../{GrammaGem => GrammarGem}/App/MainWindow/ExclusionsView.swift | 0 .../{GrammaGem => GrammarGem}/App/MainWindow/LiveCheckView.swift | 0 .../{GrammaGem => GrammarGem}/App/MainWindow/MainWindowView.swift | 0 .../{GrammaGem => GrammarGem}/App/MainWindow/SystemViews.swift | 0 .../App/MainWindow/WritingModesView.swift | 0 Sources/{GrammaGem => GrammarGem}/App/MenuBarContent.swift | 0 Sources/{GrammaGem => GrammarGem}/App/OnboardingView.swift | 0 Sources/{GrammaGem => GrammarGem}/App/SettingsView.swift | 0 Sources/{GrammaGem => GrammarGem}/Core/AppConfig.swift | 0 Sources/{GrammaGem => GrammarGem}/Core/Logger.swift | 0 Sources/{GrammaGem => GrammarGem}/Core/Models.swift | 0 Sources/{GrammaGem => GrammarGem}/Entitlements/Entitlements.swift | 0 Sources/{GrammaGem => GrammarGem}/Entitlements/FeatureGate.swift | 0 Sources/{GrammaGem => GrammarGem}/Grammar/GrammarEngine.swift | 0 Sources/{GrammaGem => GrammarGem}/Grammar/HarperEngine.swift | 0 .../{GrammaGem => GrammarGem}/Grammar/PersonalDictionary.swift | 0 .../{GrammaGem => GrammarGem}/Grammar/SystemGrammarEngine.swift | 0 Sources/{GrammaGem => GrammarGem}/Grammar/WritingScore.swift | 0 .../{GrammaGem => GrammarGem}/Licensing/DeviceFingerprint.swift | 0 Sources/{GrammaGem => GrammarGem}/Licensing/Keychain.swift | 0 .../{GrammaGem => GrammarGem}/Licensing/LemonSqueezyClient.swift | 0 Sources/{GrammaGem => GrammarGem}/Licensing/LicenseManager.swift | 0 Sources/{GrammaGem => GrammarGem}/Licensing/LicenseModels.swift | 0 Sources/{GrammaGem => GrammarGem}/Preferences/Preferences.swift | 0 Sources/{GrammaGem => GrammarGem}/Stats/UsageStats.swift | 0 Sources/{GrammaGem => GrammarGem}/System/AXSupport.swift | 0 Sources/{GrammaGem => GrammarGem}/System/AppDetector.swift | 0 Sources/{GrammaGem => GrammarGem}/System/Exclusions.swift | 0 Sources/{GrammaGem => GrammarGem}/System/HotkeyCombo.swift | 0 Sources/{GrammaGem => GrammarGem}/System/HotkeyManager.swift | 0 Sources/{GrammaGem => GrammarGem}/System/LiveMonitor.swift | 0 Sources/{GrammaGem => GrammarGem}/System/Permissions.swift | 0 Sources/{GrammaGem => GrammarGem}/System/SnippetStore.swift | 0 Sources/{GrammaGem => GrammarGem}/System/TextCapture.swift | 0 Sources/{GrammaGem => GrammarGem}/System/TextFieldScanner.swift | 0 .../System/TextReplacementCoordinator.swift | 0 Sources/{GrammaGem => GrammarGem}/System/UpdaterManager.swift | 0 .../GrammarGemTests.swift} | 0 51 files changed, 0 insertions(+), 0 deletions(-) rename AppSupport/{GrammaGem.entitlements => GrammarGem.entitlements} (100%) rename Sources/{GrammaGem => GrammarGem}/AI/AIEngine.swift (100%) rename Sources/{GrammaGem => GrammarGem}/AI/CustomModesStore.swift (100%) rename Sources/{GrammaGem => GrammarGem}/AI/MLXEngine.swift (100%) rename Sources/{GrammaGem => GrammarGem}/AI/ModeRegistry.swift (100%) rename Sources/{GrammaGem => GrammarGem}/AI/ModelManager.swift (100%) rename Sources/{GrammaGem => GrammarGem}/App/AppState.swift (100%) rename Sources/{GrammaGem => GrammarGem}/App/AskView.swift (100%) rename Sources/{GrammaGem/App/GrammaGemApp.swift => GrammarGem/App/GrammarGemApp.swift} (100%) rename Sources/{GrammaGem => GrammarGem}/App/MainWindow/AccountViews.swift (100%) rename Sources/{GrammaGem => GrammarGem}/App/MainWindow/DashboardView.swift (100%) rename Sources/{GrammaGem => GrammarGem}/App/MainWindow/DataViews.swift (100%) rename Sources/{GrammaGem => GrammarGem}/App/MainWindow/DevicesView.swift (100%) rename Sources/{GrammaGem => GrammarGem}/App/MainWindow/ExclusionsView.swift (100%) rename Sources/{GrammaGem => GrammarGem}/App/MainWindow/LiveCheckView.swift (100%) rename Sources/{GrammaGem => GrammarGem}/App/MainWindow/MainWindowView.swift (100%) rename Sources/{GrammaGem => GrammarGem}/App/MainWindow/SystemViews.swift (100%) rename Sources/{GrammaGem => GrammarGem}/App/MainWindow/WritingModesView.swift (100%) rename Sources/{GrammaGem => GrammarGem}/App/MenuBarContent.swift (100%) rename Sources/{GrammaGem => GrammarGem}/App/OnboardingView.swift (100%) rename Sources/{GrammaGem => GrammarGem}/App/SettingsView.swift (100%) rename Sources/{GrammaGem => GrammarGem}/Core/AppConfig.swift (100%) rename Sources/{GrammaGem => GrammarGem}/Core/Logger.swift (100%) rename Sources/{GrammaGem => GrammarGem}/Core/Models.swift (100%) rename Sources/{GrammaGem => GrammarGem}/Entitlements/Entitlements.swift (100%) rename Sources/{GrammaGem => GrammarGem}/Entitlements/FeatureGate.swift (100%) rename Sources/{GrammaGem => GrammarGem}/Grammar/GrammarEngine.swift (100%) rename Sources/{GrammaGem => GrammarGem}/Grammar/HarperEngine.swift (100%) rename Sources/{GrammaGem => GrammarGem}/Grammar/PersonalDictionary.swift (100%) rename Sources/{GrammaGem => GrammarGem}/Grammar/SystemGrammarEngine.swift (100%) rename Sources/{GrammaGem => GrammarGem}/Grammar/WritingScore.swift (100%) rename Sources/{GrammaGem => GrammarGem}/Licensing/DeviceFingerprint.swift (100%) rename Sources/{GrammaGem => GrammarGem}/Licensing/Keychain.swift (100%) rename Sources/{GrammaGem => GrammarGem}/Licensing/LemonSqueezyClient.swift (100%) rename Sources/{GrammaGem => GrammarGem}/Licensing/LicenseManager.swift (100%) rename Sources/{GrammaGem => GrammarGem}/Licensing/LicenseModels.swift (100%) rename Sources/{GrammaGem => GrammarGem}/Preferences/Preferences.swift (100%) rename Sources/{GrammaGem => GrammarGem}/Stats/UsageStats.swift (100%) rename Sources/{GrammaGem => GrammarGem}/System/AXSupport.swift (100%) rename Sources/{GrammaGem => GrammarGem}/System/AppDetector.swift (100%) rename Sources/{GrammaGem => GrammarGem}/System/Exclusions.swift (100%) rename Sources/{GrammaGem => GrammarGem}/System/HotkeyCombo.swift (100%) rename Sources/{GrammaGem => GrammarGem}/System/HotkeyManager.swift (100%) rename Sources/{GrammaGem => GrammarGem}/System/LiveMonitor.swift (100%) rename Sources/{GrammaGem => GrammarGem}/System/Permissions.swift (100%) rename Sources/{GrammaGem => GrammarGem}/System/SnippetStore.swift (100%) rename Sources/{GrammaGem => GrammarGem}/System/TextCapture.swift (100%) rename Sources/{GrammaGem => GrammarGem}/System/TextFieldScanner.swift (100%) rename Sources/{GrammaGem => GrammarGem}/System/TextReplacementCoordinator.swift (100%) rename Sources/{GrammaGem => GrammarGem}/System/UpdaterManager.swift (100%) rename Tests/{GrammaGemTests/GrammaGemTests.swift => GrammarGemTests/GrammarGemTests.swift} (100%) diff --git a/AppSupport/GrammaGem.entitlements b/AppSupport/GrammarGem.entitlements similarity index 100% rename from AppSupport/GrammaGem.entitlements rename to AppSupport/GrammarGem.entitlements diff --git a/Sources/GrammaGem/AI/AIEngine.swift b/Sources/GrammarGem/AI/AIEngine.swift similarity index 100% rename from Sources/GrammaGem/AI/AIEngine.swift rename to Sources/GrammarGem/AI/AIEngine.swift diff --git a/Sources/GrammaGem/AI/CustomModesStore.swift b/Sources/GrammarGem/AI/CustomModesStore.swift similarity index 100% rename from Sources/GrammaGem/AI/CustomModesStore.swift rename to Sources/GrammarGem/AI/CustomModesStore.swift diff --git a/Sources/GrammaGem/AI/MLXEngine.swift b/Sources/GrammarGem/AI/MLXEngine.swift similarity index 100% rename from Sources/GrammaGem/AI/MLXEngine.swift rename to Sources/GrammarGem/AI/MLXEngine.swift diff --git a/Sources/GrammaGem/AI/ModeRegistry.swift b/Sources/GrammarGem/AI/ModeRegistry.swift similarity index 100% rename from Sources/GrammaGem/AI/ModeRegistry.swift rename to Sources/GrammarGem/AI/ModeRegistry.swift diff --git a/Sources/GrammaGem/AI/ModelManager.swift b/Sources/GrammarGem/AI/ModelManager.swift similarity index 100% rename from Sources/GrammaGem/AI/ModelManager.swift rename to Sources/GrammarGem/AI/ModelManager.swift diff --git a/Sources/GrammaGem/App/AppState.swift b/Sources/GrammarGem/App/AppState.swift similarity index 100% rename from Sources/GrammaGem/App/AppState.swift rename to Sources/GrammarGem/App/AppState.swift diff --git a/Sources/GrammaGem/App/AskView.swift b/Sources/GrammarGem/App/AskView.swift similarity index 100% rename from Sources/GrammaGem/App/AskView.swift rename to Sources/GrammarGem/App/AskView.swift diff --git a/Sources/GrammaGem/App/GrammaGemApp.swift b/Sources/GrammarGem/App/GrammarGemApp.swift similarity index 100% rename from Sources/GrammaGem/App/GrammaGemApp.swift rename to Sources/GrammarGem/App/GrammarGemApp.swift diff --git a/Sources/GrammaGem/App/MainWindow/AccountViews.swift b/Sources/GrammarGem/App/MainWindow/AccountViews.swift similarity index 100% rename from Sources/GrammaGem/App/MainWindow/AccountViews.swift rename to Sources/GrammarGem/App/MainWindow/AccountViews.swift diff --git a/Sources/GrammaGem/App/MainWindow/DashboardView.swift b/Sources/GrammarGem/App/MainWindow/DashboardView.swift similarity index 100% rename from Sources/GrammaGem/App/MainWindow/DashboardView.swift rename to Sources/GrammarGem/App/MainWindow/DashboardView.swift diff --git a/Sources/GrammaGem/App/MainWindow/DataViews.swift b/Sources/GrammarGem/App/MainWindow/DataViews.swift similarity index 100% rename from Sources/GrammaGem/App/MainWindow/DataViews.swift rename to Sources/GrammarGem/App/MainWindow/DataViews.swift diff --git a/Sources/GrammaGem/App/MainWindow/DevicesView.swift b/Sources/GrammarGem/App/MainWindow/DevicesView.swift similarity index 100% rename from Sources/GrammaGem/App/MainWindow/DevicesView.swift rename to Sources/GrammarGem/App/MainWindow/DevicesView.swift diff --git a/Sources/GrammaGem/App/MainWindow/ExclusionsView.swift b/Sources/GrammarGem/App/MainWindow/ExclusionsView.swift similarity index 100% rename from Sources/GrammaGem/App/MainWindow/ExclusionsView.swift rename to Sources/GrammarGem/App/MainWindow/ExclusionsView.swift diff --git a/Sources/GrammaGem/App/MainWindow/LiveCheckView.swift b/Sources/GrammarGem/App/MainWindow/LiveCheckView.swift similarity index 100% rename from Sources/GrammaGem/App/MainWindow/LiveCheckView.swift rename to Sources/GrammarGem/App/MainWindow/LiveCheckView.swift diff --git a/Sources/GrammaGem/App/MainWindow/MainWindowView.swift b/Sources/GrammarGem/App/MainWindow/MainWindowView.swift similarity index 100% rename from Sources/GrammaGem/App/MainWindow/MainWindowView.swift rename to Sources/GrammarGem/App/MainWindow/MainWindowView.swift diff --git a/Sources/GrammaGem/App/MainWindow/SystemViews.swift b/Sources/GrammarGem/App/MainWindow/SystemViews.swift similarity index 100% rename from Sources/GrammaGem/App/MainWindow/SystemViews.swift rename to Sources/GrammarGem/App/MainWindow/SystemViews.swift diff --git a/Sources/GrammaGem/App/MainWindow/WritingModesView.swift b/Sources/GrammarGem/App/MainWindow/WritingModesView.swift similarity index 100% rename from Sources/GrammaGem/App/MainWindow/WritingModesView.swift rename to Sources/GrammarGem/App/MainWindow/WritingModesView.swift diff --git a/Sources/GrammaGem/App/MenuBarContent.swift b/Sources/GrammarGem/App/MenuBarContent.swift similarity index 100% rename from Sources/GrammaGem/App/MenuBarContent.swift rename to Sources/GrammarGem/App/MenuBarContent.swift diff --git a/Sources/GrammaGem/App/OnboardingView.swift b/Sources/GrammarGem/App/OnboardingView.swift similarity index 100% rename from Sources/GrammaGem/App/OnboardingView.swift rename to Sources/GrammarGem/App/OnboardingView.swift diff --git a/Sources/GrammaGem/App/SettingsView.swift b/Sources/GrammarGem/App/SettingsView.swift similarity index 100% rename from Sources/GrammaGem/App/SettingsView.swift rename to Sources/GrammarGem/App/SettingsView.swift diff --git a/Sources/GrammaGem/Core/AppConfig.swift b/Sources/GrammarGem/Core/AppConfig.swift similarity index 100% rename from Sources/GrammaGem/Core/AppConfig.swift rename to Sources/GrammarGem/Core/AppConfig.swift diff --git a/Sources/GrammaGem/Core/Logger.swift b/Sources/GrammarGem/Core/Logger.swift similarity index 100% rename from Sources/GrammaGem/Core/Logger.swift rename to Sources/GrammarGem/Core/Logger.swift diff --git a/Sources/GrammaGem/Core/Models.swift b/Sources/GrammarGem/Core/Models.swift similarity index 100% rename from Sources/GrammaGem/Core/Models.swift rename to Sources/GrammarGem/Core/Models.swift diff --git a/Sources/GrammaGem/Entitlements/Entitlements.swift b/Sources/GrammarGem/Entitlements/Entitlements.swift similarity index 100% rename from Sources/GrammaGem/Entitlements/Entitlements.swift rename to Sources/GrammarGem/Entitlements/Entitlements.swift diff --git a/Sources/GrammaGem/Entitlements/FeatureGate.swift b/Sources/GrammarGem/Entitlements/FeatureGate.swift similarity index 100% rename from Sources/GrammaGem/Entitlements/FeatureGate.swift rename to Sources/GrammarGem/Entitlements/FeatureGate.swift diff --git a/Sources/GrammaGem/Grammar/GrammarEngine.swift b/Sources/GrammarGem/Grammar/GrammarEngine.swift similarity index 100% rename from Sources/GrammaGem/Grammar/GrammarEngine.swift rename to Sources/GrammarGem/Grammar/GrammarEngine.swift diff --git a/Sources/GrammaGem/Grammar/HarperEngine.swift b/Sources/GrammarGem/Grammar/HarperEngine.swift similarity index 100% rename from Sources/GrammaGem/Grammar/HarperEngine.swift rename to Sources/GrammarGem/Grammar/HarperEngine.swift diff --git a/Sources/GrammaGem/Grammar/PersonalDictionary.swift b/Sources/GrammarGem/Grammar/PersonalDictionary.swift similarity index 100% rename from Sources/GrammaGem/Grammar/PersonalDictionary.swift rename to Sources/GrammarGem/Grammar/PersonalDictionary.swift diff --git a/Sources/GrammaGem/Grammar/SystemGrammarEngine.swift b/Sources/GrammarGem/Grammar/SystemGrammarEngine.swift similarity index 100% rename from Sources/GrammaGem/Grammar/SystemGrammarEngine.swift rename to Sources/GrammarGem/Grammar/SystemGrammarEngine.swift diff --git a/Sources/GrammaGem/Grammar/WritingScore.swift b/Sources/GrammarGem/Grammar/WritingScore.swift similarity index 100% rename from Sources/GrammaGem/Grammar/WritingScore.swift rename to Sources/GrammarGem/Grammar/WritingScore.swift diff --git a/Sources/GrammaGem/Licensing/DeviceFingerprint.swift b/Sources/GrammarGem/Licensing/DeviceFingerprint.swift similarity index 100% rename from Sources/GrammaGem/Licensing/DeviceFingerprint.swift rename to Sources/GrammarGem/Licensing/DeviceFingerprint.swift diff --git a/Sources/GrammaGem/Licensing/Keychain.swift b/Sources/GrammarGem/Licensing/Keychain.swift similarity index 100% rename from Sources/GrammaGem/Licensing/Keychain.swift rename to Sources/GrammarGem/Licensing/Keychain.swift diff --git a/Sources/GrammaGem/Licensing/LemonSqueezyClient.swift b/Sources/GrammarGem/Licensing/LemonSqueezyClient.swift similarity index 100% rename from Sources/GrammaGem/Licensing/LemonSqueezyClient.swift rename to Sources/GrammarGem/Licensing/LemonSqueezyClient.swift diff --git a/Sources/GrammaGem/Licensing/LicenseManager.swift b/Sources/GrammarGem/Licensing/LicenseManager.swift similarity index 100% rename from Sources/GrammaGem/Licensing/LicenseManager.swift rename to Sources/GrammarGem/Licensing/LicenseManager.swift diff --git a/Sources/GrammaGem/Licensing/LicenseModels.swift b/Sources/GrammarGem/Licensing/LicenseModels.swift similarity index 100% rename from Sources/GrammaGem/Licensing/LicenseModels.swift rename to Sources/GrammarGem/Licensing/LicenseModels.swift diff --git a/Sources/GrammaGem/Preferences/Preferences.swift b/Sources/GrammarGem/Preferences/Preferences.swift similarity index 100% rename from Sources/GrammaGem/Preferences/Preferences.swift rename to Sources/GrammarGem/Preferences/Preferences.swift diff --git a/Sources/GrammaGem/Stats/UsageStats.swift b/Sources/GrammarGem/Stats/UsageStats.swift similarity index 100% rename from Sources/GrammaGem/Stats/UsageStats.swift rename to Sources/GrammarGem/Stats/UsageStats.swift diff --git a/Sources/GrammaGem/System/AXSupport.swift b/Sources/GrammarGem/System/AXSupport.swift similarity index 100% rename from Sources/GrammaGem/System/AXSupport.swift rename to Sources/GrammarGem/System/AXSupport.swift diff --git a/Sources/GrammaGem/System/AppDetector.swift b/Sources/GrammarGem/System/AppDetector.swift similarity index 100% rename from Sources/GrammaGem/System/AppDetector.swift rename to Sources/GrammarGem/System/AppDetector.swift diff --git a/Sources/GrammaGem/System/Exclusions.swift b/Sources/GrammarGem/System/Exclusions.swift similarity index 100% rename from Sources/GrammaGem/System/Exclusions.swift rename to Sources/GrammarGem/System/Exclusions.swift diff --git a/Sources/GrammaGem/System/HotkeyCombo.swift b/Sources/GrammarGem/System/HotkeyCombo.swift similarity index 100% rename from Sources/GrammaGem/System/HotkeyCombo.swift rename to Sources/GrammarGem/System/HotkeyCombo.swift diff --git a/Sources/GrammaGem/System/HotkeyManager.swift b/Sources/GrammarGem/System/HotkeyManager.swift similarity index 100% rename from Sources/GrammaGem/System/HotkeyManager.swift rename to Sources/GrammarGem/System/HotkeyManager.swift diff --git a/Sources/GrammaGem/System/LiveMonitor.swift b/Sources/GrammarGem/System/LiveMonitor.swift similarity index 100% rename from Sources/GrammaGem/System/LiveMonitor.swift rename to Sources/GrammarGem/System/LiveMonitor.swift diff --git a/Sources/GrammaGem/System/Permissions.swift b/Sources/GrammarGem/System/Permissions.swift similarity index 100% rename from Sources/GrammaGem/System/Permissions.swift rename to Sources/GrammarGem/System/Permissions.swift diff --git a/Sources/GrammaGem/System/SnippetStore.swift b/Sources/GrammarGem/System/SnippetStore.swift similarity index 100% rename from Sources/GrammaGem/System/SnippetStore.swift rename to Sources/GrammarGem/System/SnippetStore.swift diff --git a/Sources/GrammaGem/System/TextCapture.swift b/Sources/GrammarGem/System/TextCapture.swift similarity index 100% rename from Sources/GrammaGem/System/TextCapture.swift rename to Sources/GrammarGem/System/TextCapture.swift diff --git a/Sources/GrammaGem/System/TextFieldScanner.swift b/Sources/GrammarGem/System/TextFieldScanner.swift similarity index 100% rename from Sources/GrammaGem/System/TextFieldScanner.swift rename to Sources/GrammarGem/System/TextFieldScanner.swift diff --git a/Sources/GrammaGem/System/TextReplacementCoordinator.swift b/Sources/GrammarGem/System/TextReplacementCoordinator.swift similarity index 100% rename from Sources/GrammaGem/System/TextReplacementCoordinator.swift rename to Sources/GrammarGem/System/TextReplacementCoordinator.swift diff --git a/Sources/GrammaGem/System/UpdaterManager.swift b/Sources/GrammarGem/System/UpdaterManager.swift similarity index 100% rename from Sources/GrammaGem/System/UpdaterManager.swift rename to Sources/GrammarGem/System/UpdaterManager.swift diff --git a/Tests/GrammaGemTests/GrammaGemTests.swift b/Tests/GrammarGemTests/GrammarGemTests.swift similarity index 100% rename from Tests/GrammaGemTests/GrammaGemTests.swift rename to Tests/GrammarGemTests/GrammarGemTests.swift