[BREAKGLASS] AXorcist • Swift wrapper for macOS Accessibility—chainable, fuzzy-matched queries that read, click, and inspect any UI. The power of Swift compels your UI to obey! https://axorcist.dev
Go to file
Peter Steinberger dacf59720b Major refactor
2025-05-27 03:07:10 +02:00
.github/workflows Add SwiftFormat configuration and tooling 2025-05-22 04:42:02 +02:00
.vscode Lerge refactor 2025-05-23 01:09:55 +02:00
assets Add comprehensive magical README and reorganize assets 2025-05-22 03:04:47 +02:00
Examples Larger refactor, improve error handling and app fetching, observers 2025-05-25 13:57:00 +02:00
Sources Major refactor 2025-05-27 03:07:10 +02:00
Tests/AXorcistTests Add observe feature for cli and fix various json encoding issues 2025-05-25 19:59:17 +02:00
.gitignore AXpector: Add logo and Swift .gitignore 2025-05-21 00:29:58 +02:00
.swiftformat Add SwiftFormat configuration and tooling 2025-05-22 04:42:02 +02:00
.swiftlint.yml Add SwiftLint configuration to reduce CI failures 2025-05-22 04:53:17 +02:00
axorc_runner.sh Lerge refactor 2025-05-23 01:09:55 +02:00
axorc_stderr.log Major refactor 2025-05-27 03:07:10 +02:00
LICENSE Initial commit 2025-05-21 00:12:40 +02:00
Makefile Add SwiftFormat configuration and tooling 2025-05-22 04:42:02 +02:00
Package.resolved Add logging 2025-05-27 01:26:46 +02:00
Package.swift Add logging 2025-05-27 01:26:46 +02:00
README.md Major refactor; fix tree recursion, add new point API, improve log subsystem 2025-05-24 18:21:05 +02:00
run_axorc_with_json_content.sh Major refactor 2025-05-27 03:07:10 +02:00
run_tests.sh Convert AXspector to AXorcist Swift package with CLI tool 2025-05-22 02:46:39 +02:00

AXorcist: The power of Swift compels your UI to obey!

AXorcist Logo

Swift wrapper for macOS Accessibility—chainable, fuzzy-matched queries
that read, click, and inspect any UI.


AXorcist harnesses the dark arts of macOS Accessibility APIs to give you supernatural control over any application's interface. Whether you're automating workflows, testing applications, or building assistive technologies, AXorcist provides the incantations you need to make UI elements bend to your will.

Supernatural Powers

  • 🔍 Element Summoning: Conjure UI elements using flexible locator spells
  • 📋 Attribute Divination: Extract mystical properties from accessibility elements
  • Action Invocation: Cast clicks, text input, and menu manipulation spells
  • 🔄 Batch Sorcery: Execute multiple enchantments efficiently in a single ritual
  • 📜 Text Extraction: Harvest textual essence from any UI element
  • 🗺️ Path Navigation: Navigate the ethereal element hierarchies with precision
  • 🐛 Debug Scrying: Comprehensive logging to troubleshoot your incantations
  • 📊 JSON Grimoire: Clean JSON input/output for seamless spell integration

📦 Summoning AXorcist

Swift Package Manager

Invoke AXorcist into your project by adding it to your Package.swift grimoire:

dependencies: [
    .package(url: "https://github.com/steipete/AXorcist.git", from: "0.1.0")
]

Command Line Familiar

Conjure the axorc command-line familiar:

git clone https://github.com/steipete/AXorcist.git
cd AXorcist
make build
make install

🚀 First Incantations

Casting Swift Spells

import AXorcist

@MainActor
func example() async {
    let axorcist = AXorcist()
    
    // Configure logging for the operation (optional)
    // AXorcist.GlobalAXLogger.startCollecting(enableDebugLogging: .verbose, forCommandID: "exampleFocusedElement")

    // Summon the focused element
    let result = await axorcist.handleGetFocusedElement(
        for: "Safari", 
        requestedAttributes: ["AXRole", "AXTitle"]
    )
    
    if let element = result.data {
        print("Behold! Element with attributes:", element.attributes)
    }

    // Retrieve and print logs (optional)
    // let collectedLogs = await AXorcist.GlobalAXLogger.getLogsAsStrings()
    // if !collectedLogs.isEmpty {
    //     print("\\nArcane Logs:")
    //     collectedLogs.forEach { print($0) }
    // }
    // await AXorcist.GlobalAXLogger.stopCollecting() // Clears logs and stops collection for this ID
}

Command Line Rituals

# Divine the focused element in any application
echo '{"command_id": "1", "command": "getFocusedElement"}' | axorc --stdin

# Summon a specific button with precise locator magic
echo '{
  "command_id": "2", 
  "command": "query",
  "locator": {
    "criteria": {
      "AXRole": "AXButton",
      "AXTitle": "Submit"
    }
  }
}' | axorc --stdin

📖 The Spell Book

The AXorcist Entity

Your primary conduit to the accessibility realm, wielding eight powerful enchantments:

Core Enchantments

  • handleGetFocusedElement: Divine the currently focused UI element
  • handleGetAttributes: Extract mystical properties using locator spells
  • handleQuery: Summon elements matching your criteria
  • handleDescribeElement: Reveal comprehensive element secrets
  • handlePerformAction: Command UI elements to perform your bidding
  • handleExtractText: Harvest textual essence from any element
  • handleBatchCommands: Execute multiple spells in a single ritual
  • handleCollectAll: Recursively gather all matching elements from the UI realm

🧙‍♂️ Spell Components

All enchantments accept these mystical parameters:

  • appIdentifierOrNil: Target application realm (bundle ID, name, or "focused")
  • locator: Magical search criteria for element summoning
  • pathHint: Array of breadcrumbs for UI navigation
  • maxDepth: Maximum depth to traverse the element abyss
  • requestedAttributes: Specific mystical properties to harvest
  • outputFormat: Revelation format (.smart, .verbose, .json_string)

For debug logging, AXorcist now uses a global, MainActor-isolated logger (AXorcist.GlobalAXLogger). Call GlobalAXLogger.startCollecting(...) before an operation and GlobalAXLogger.stopCollecting() / GlobalAXLogger.getLogsAsStrings() afterwards if you need to inspect logs programmatically.

🎯 Locator Spells

Locators are your targeting spells for finding UI elements in the digital realm:

let locator = Locator(
    criteria: [
        "AXRole": "AXButton",
        "AXTitle": "Save Document"
    ],
    requireAction: "AXPress"  // Ensure the element can be commanded
)

📜 Prophecy Format

All spells return visions in the form of HandlerResponse:

public struct HandlerResponse {
    public var data: AXElement?        // The summoned element's essence
    public var error: String?          // Curse description if spell failed
    public var debug_logs: [String]?   // Scrying logs and mystical insights
}

🔮 Element Essence Structure

The harvested element data contains:

public struct AXElement {
    public var attributes: [String: AnyCodable]  // Mystical element properties
    public var path: [String]                    // Journey from app realm to element
}

🖥️ Command Line Grimoire

The axorc familiar accepts JSON incantations through multiple mystical channels:

📥 Invocation Methods

# Channel through the ethereal STDIN
echo '{"command": "ping", "command_id": "1"}' | axorc --stdin

# Read from a spell scroll (file)
axorc --file command.json

# Direct magical utterance
axorc '{"command": "ping", "command_id": "1"}'

🎭 Available Enchantments

  • ping: Test the spiritual connection
  • getFocusedElement: Divine the currently focused element
  • getAttributes: Extract element properties using locator magic
  • query: Summon elements matching your desires
  • describeElement: Reveal comprehensive element mysteries
  • performAction: Command elements to do your bidding
  • extractText: Harvest textual essence from the digital realm
  • batch: Execute multiple rituals in sequence
  • collectAll: Gather all matching elements from the UI cosmos

📋 Example Incantation

{
  "command_id": "summon_back_button",
  "command": "query", 
  "application": "Safari",
  "locator": {
    "criteria": {
      "AXRole": "AXButton",
      "AXTitle": "Back"
    }
  },
  "attributes": ["AXRole", "AXTitle", "AXEnabled"]
}

🔐 Mystical Permissions

AXorcist requires sacred accessibility permissions to commune with the UI spirits. macOS will present you with a permission ritual upon first use, or you may grant access manually through:

System Preferences → Security & Privacy → Privacy → Accessibility

Grant AXorcist the power it needs to serve your digital dominion!

🔨 Forging Your Arsenal

# Forge the mystical artifacts
make build

# Test the enchantments (requires local machine - CI spirits cannot grant accessibility permissions)
make test

# Complete ritual: build and test
make all

# Purify the workspace
make clean

🌙 Testing in the Shadows

The test rituals require accessibility permissions to commune with the UI spirits—permissions that cannot be granted automatically on CI. While automated build specters can verify your Swift incantations compile correctly, the full test ceremonies must be performed on a local machine where you can manually grant the sacred accessibility permissions through System Preferences.

The spirits of continuous integration watch over your builds, but only mortal hands can unlock the accessibility gates.

⚔️ Minimum Requirements

  • macOS 13.0 or later (The realm of Ventura and beyond)
  • Swift 5.9 or later (Modern Swift sorcery)
  • Xcode 15.0 or later (For apprentice developers)

🤝 Join the Coven

  1. Fork this mystical repository
  2. Create your feature branch (git checkout -b feature/amazing-spell)
  3. Craft your enhancements
  4. Add tests for new magical abilities
  5. Ensure all enchantments pass (make test)
  6. Submit a pull request to the main grimoire

📜 Sacred License

MIT License - see LICENSE scroll for the complete binding agreement.

🌟 Allied Magical Artifacts


May your UI elements bend to your will, and may your accessibility spells never fail. 🧙‍♂️