diff --git a/README.md b/README.md index c077e63..799e820 100644 --- a/README.md +++ b/README.md @@ -1,87 +1,120 @@ [![MacPaw Research](https://pbs.twimg.com/profile_banners/3993798502/1720615716/1500x500)](https://research.macpaw.com) -![PyPI - Version](https://img.shields.io/pypi/v/macapptree) [![arXiv](https://img.shields.io/badge/arXiv-2510.16051-b31b1b.svg)](https://arxiv.org/abs/2510.16051) +

+ PyPI version + Python versions + Platform + License + arXiv +

# macapptree -`macapptree` is a Python package that extracts the accessibility tree of a macOS applications screen in JSON format. It also provides an option to capture screenshots of the application, including labeled bounding boxes with different colors representing various element types. This tool is useful for accessibility testing, UI automation, and visual debugging. You can also capture the accessibility of all currently running, visible apps and include the Dock and top Menu Bar. +`macapptree` is a Python package that extracts the **accessibility tree** of macOS applications as structured JSON. It can also capture screenshots of application windows with labeled bounding boxes colored by element type — useful for accessibility testing, UI automation, agent training data, and visual debugging. + +You can capture a single app, a specific set of apps, or everything currently visible on screen — including the Dock and Menu Bar. --- ## Features -- **Accessibility Tree Extraction of Apps**: Retrieve the accessibility hierarchy of a single or multiple macOS applications in JSON format. -- **Screenshot Capture**: Capture a cropped screenshot of the application window and full screen. -- **Labeled Visual Output**: Generate a segmented screenshot with bounding boxes highlighting UI elements, colored by their types. +- **Accessibility tree extraction** — retrieve the full AX hierarchy of one or many macOS apps as JSON +- **Single-app or multi-app capture** — target apps by bundle ID or auto-discover all visible apps +- **Window screenshots** — cropped screenshots of individual application windows +- **Segmented visual output** — annotated screenshots with color-coded bounding boxes per element type +- **Menu Bar & Dock support** — include system UI in the captured tree +- **Full-screen annotated output** — overlay all element bounding boxes onto a full-screen capture --- -## Installation +## Prerequisites + +### macOS Accessibility Permissions + +`macapptree` uses the macOS Accessibility API (`AXUIElement`). The process running it **must be granted Accessibility access**: + +1. Open **System Settings → Privacy & Security → Accessibility** +2. Add your terminal application (e.g. Terminal, iTerm2) or the Python interpreter +3. Toggle it **on** -To install `macapptree`, use `pip`: +Without this permission, the library will return empty trees silently. + +### Python 3.8+, macOS only + +--- + +## Installation ```bash pip install macapptree ``` -> Note: This package requires macOS and Python 3.8+. --- -## Usage - -The library provides two primary functions: -* `get_tree`: Extracts the accessibility tree of a macOS app. -* `get_tree_screenshot`: Extracts the accessibility tree and generates screenshots. - -### Example +## Python API ```python from macapptree import get_tree, get_tree_screenshot, get_app_bundle -# Get the app bundle identifier (for example: "com.apple.TextEdit") -bundle = get_app_bundle("TextEdit") +# Resolve bundle ID from app name +bundle = get_app_bundle("TextEdit") # → "com.apple.TextEdit" -# Retrieve the accessibility tree, a cropped screenshot, and a segmented screenshot -tree, im, im_seg = get_tree_screenshot(bundle) +# Accessibility tree only +tree = get_tree(bundle) -# `tree`: JSON-like structure of the accessibility elements -# `im`: Cropped screenshot of the application window -# `im_seg`: Labeled screenshot with bounding boxes indicating UI elements +# Accessibility tree + screenshots +tree, window_img, segmented_img = get_tree_screenshot(bundle) +# tree – dict, the full accessibility hierarchy +# window_img – PIL.Image, cropped screenshot of the app window +# segmented_img – PIL.Image, same screenshot with bounding boxes drawn ``` -### CLI Example (multi-app) +--- -Capture the accessibility of all currently running and visible apps (with upper menu and dock included): -```python +## CLI + +### Capture specific apps + +```bash python -m macapptree.main \ - --oa shots/dump.json \ - --os shots \ - --all-apps \ + -a com.apple.Safari com.google.Chrome \ + --oa output/dump.json \ + --os output/screenshots \ --include-menubar \ --include-dock ``` -Or specify apps explicitly: -```python +### Capture all visible apps + +```bash python -m macapptree.main \ - -a com.apple.Safari com.google.Chrome \ - --oa shots/dump.json \ - --os shots \ + --all-apps \ + --oa output/dump.json \ + --os output/screenshots \ --include-menubar \ --include-dock ``` -### Output +### CLI options -* **tree**: A Python dictionary representing the accessibility hierarchy. -* **im**: A cropped `PIL.Image` object of the app window. -* **im_seg**: A `PIL.Image` object with bounding boxes drawn on top, colored based on the element type. +| Flag | Description | +|------|-------------| +| `-a` / `--apps` | One or more app bundle IDs (space-separated) | +| `--all-apps` | Auto-discover all currently visible apps | +| `--oa` | Output path for the accessibility JSON file (**required**) | +| `--os` | Directory for cropped and segmented screenshots | +| `--max-depth` | Maximum depth of the accessibility tree | +| `--include-menubar` | Also capture the top Menu Bar | +| `--include-dock` | Also capture the Dock | --- +## Output + +### JSON structure -## Example Tree Output +Each element in the tree has the following shape: ```json { @@ -95,54 +128,40 @@ python -m macapptree.main \ "position": "0.00;0.00", "size": "586;476", "enabled": false, - "bbox": [ - 0, - 0, - 586, - 476 - ], - "visible_bbox": [ - 0, - 0, - 586, - 476 - ], - "children": [ - { - "id": "422f5e0df37aa872341d3b6a47faf320", - "name": null, - "role": "AXScrollArea", - "description": null, - "role_description": "scroll area", - "value": null, - "absolute_position": "214.00;175.00", - "position": "0.00;56.00", - "size": "586;420", - "enabled": false, - "bbox": [ - 0, - 56, - 586, - 476 - ], - "visible_bbox": [ - 0, - 56, - 586, - 476 - ], - "children": [ - ... + "bbox": [0, 0, 586, 476], + "visible_bbox": [0, 0, 586, 476], + "children": [...] +} ``` +### Screenshot output + +| File | Description | +|------|-------------| +| `__cropped.png` | Cropped screenshot of the window | +| `__segmented.png` | Annotated screenshot with bounding boxes | +| `full_screen.png` | Full-screen capture | +| `full_screen_annotated.png` | Full-screen capture with all element overlays | + --- ## License This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. +--- + +## Contributing + +Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. + +--- + ## Citation -``` + +If you use `macapptree` in your research, please cite: + +```bibtex @article{garkot2025guirilla, title={GUIrilla: A Scalable Framework for Automated Desktop UI Exploration}, author={Garkot, Sofiya and Shamrai, Maksym and Synytsia, Ivan and Hirna, Mariya}, @@ -152,8 +171,8 @@ This project is licensed under the MIT License. See the [LICENSE](LICENSE) file } ``` -## MacPaw Research +--- -Visit our site to learn more 😉 +## MacPaw Research -https://research.macpaw.com +Built by the [MacPaw Research](https://research.macpaw.com) team.