Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions Echo/Sources/Accessibility/AccessibleApplication.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -18,16 +18,15 @@ final class AccessbilableApplication: NSObject {
self.application = application
}

private static let editableRoles: Set<String> = ["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
}
}
Expand Down
2 changes: 1 addition & 1 deletion Echo/Sources/Model/Agent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ final class Agent {
func query(inputString: String, prompt: String, reply: @escaping ((Result<String, Error>) -> 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 {
Expand Down
4 changes: 2 additions & 2 deletions Echo/Sources/Screens/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand Down
Loading