From 0e2b6030c8caf9b8adf9a53e6eb3234ffc0dda6b Mon Sep 17 00:00:00 2001 From: Krivoblotsky Date: Fri, 1 May 2026 19:40:14 +0300 Subject: [PATCH] fix: rename AccessbilableApplication, use system role, match AXTextField - Rename misspelled class AccessbilableApplication -> AccessibleApplication (file was already named AccessibleApplication.swift; the type inside was not). Update call site and README reference. - Agent: send the system prompt with role .system instead of .assistant. Using .assistant treated the instructions as prior model output rather than a system directive, which subtly changes how GPT-4o behaves. - AccessibleApplication: match both AXTextArea and AXTextField, so Echo can target single-line text inputs (search bars, address fields, etc.) in addition to multi-line editors. Tightened the empty-value filter with String.trimmingCharacters(in: .whitespacesAndNewlines). Co-Authored-By: Claude Sonnet 4.6 --- .../Accessibility/AccessibleApplication.swift | 13 ++++++------- Echo/Sources/Model/Agent.swift | 2 +- Echo/Sources/Screens/ViewController.swift | 4 ++-- README.md | 6 +++--- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Echo/Sources/Accessibility/AccessibleApplication.swift b/Echo/Sources/Accessibility/AccessibleApplication.swift index 31f85eb..b7e2918 100644 --- a/Echo/Sources/Accessibility/AccessibleApplication.swift +++ b/Echo/Sources/Accessibility/AccessibleApplication.swift @@ -9,7 +9,7 @@ import Foundation import Accessibility import ApplicationServices -final class AccessbilableApplication: NSObject { +final class AccessibleApplication: NSObject { private let accessibility = Accessibility() private let application: Application @@ -18,16 +18,15 @@ final class AccessbilableApplication: NSObject { self.application = application } + private static let editableRoles: Set = ["AXTextArea", "AXTextField"] + func fetchEditor() -> AccessibilityItem? { accessibility.requestAccess() - + let app: AXUIElement = .from(pid: application.pid) let items = accessibility.searchItem(from: app, criteria: { - if $0.role == "AXTextArea" { - return true//$0.isFocused - } - return false - }).filter { $0.value.isEmpty == false && $0.value.replacingOccurrences(of: " ", with: "").isEmpty == false } + Self.editableRoles.contains($0.role) + }).filter { !$0.value.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty } return items.first } } diff --git a/Echo/Sources/Model/Agent.swift b/Echo/Sources/Model/Agent.swift index 7eebc65..d23a283 100644 --- a/Echo/Sources/Model/Agent.swift +++ b/Echo/Sources/Model/Agent.swift @@ -25,7 +25,7 @@ final class Agent { func query(inputString: String, prompt: String, reply: @escaping ((Result) -> Void)) { let input = "\(inputString)\n\n---------\n\n\(prompt)" openAI.chats(query: .init(messages: [ - .assistant(.init(content: systemMessage)), + .system(.init(content: systemMessage)), .user(.init(content: .init(string: input))) ], model: .gpt4_o)) { result in switch result { diff --git a/Echo/Sources/Screens/ViewController.swift b/Echo/Sources/Screens/ViewController.swift index 37dba54..b3b96d7 100644 --- a/Echo/Sources/Screens/ViewController.swift +++ b/Echo/Sources/Screens/ViewController.swift @@ -75,8 +75,8 @@ private extension ViewController { return } - let accessbilableApplication = AccessbilableApplication(application: currentApplication) - guard let editor = accessbilableApplication.fetchEditor() else { + let accessibleApplication = AccessibleApplication(application: currentApplication) + guard let editor = accessibleApplication.fetchEditor() else { self.store.add(message: .textAnswer("No editable text area found in the frontmost application.")) return } diff --git a/README.md b/README.md index d50847b..71721e6 100644 --- a/README.md +++ b/README.md @@ -73,8 +73,8 @@ Echo requires macOS Accessibility permissions and will prompt you automatically **App crashes immediately on launch** The `OPEN_AI` environment variable is not set. Follow the [Development Setup](#development-setup) steps above to configure it in your Xcode scheme. -**Echo does not detect the frontmost window / "No editor" in the log** -The target application must expose an `AXTextArea` element. This works in most native text editors (Xcode, TextMate, BBEdit). Browser address bars and some web text areas may not be accessible via the Accessibility API. +**Echo does not detect the frontmost window / "No editor" message** +The target application must expose an `AXTextArea` or `AXTextField` element. This works in most native text editors (Xcode, TextMate, BBEdit) and many text fields. Browser address bars and some web text areas may not be accessible via the Accessibility API. **Accessibility permission is denied** Open **System Settings > Privacy & Security > Accessibility** and verify that Echo is listed and toggled on. Re-building from Xcode may require re-granting the permission. @@ -98,7 +98,7 @@ Verify your API key is valid and has GPT-4o access. Check your [OpenAI usage das - **`FrontmostApplication`**: Observes and detects the currently active macOS application. -- **`AccessbilableApplication`**: +- **`AccessibleApplication`**: Provides Accessibility API integration to fetch and update content in the frontmost application. ### View Hierarchy