axpilot 0.1.0a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- axpilot-0.1.0a1/.gitignore +229 -0
- axpilot-0.1.0a1/CHANGELOG.md +229 -0
- axpilot-0.1.0a1/LICENSE +201 -0
- axpilot-0.1.0a1/PKG-INFO +322 -0
- axpilot-0.1.0a1/README.md +284 -0
- axpilot-0.1.0a1/docs/adr/README.md +62 -0
- axpilot-0.1.0a1/examples/README.md +56 -0
- axpilot-0.1.0a1/launcher/README.md +205 -0
- axpilot-0.1.0a1/launcher/tests/apple_tool_stubs.py +172 -0
- axpilot-0.1.0a1/launcher/tests/conftest.py +164 -0
- axpilot-0.1.0a1/launcher/tests/stub_host.py +127 -0
- axpilot-0.1.0a1/launcher/tests/test_build_script.py +208 -0
- axpilot-0.1.0a1/launcher/tests/test_launcher.py +330 -0
- axpilot-0.1.0a1/packaging/README.md +107 -0
- axpilot-0.1.0a1/pyproject.toml +138 -0
- axpilot-0.1.0a1/skills/axpilot/SKILL.md +158 -0
- axpilot-0.1.0a1/spikes/README.md +101 -0
- axpilot-0.1.0a1/spikes/s1_launcher_tcc/README.md +96 -0
- axpilot-0.1.0a1/spikes/s2_ax_perf/README.md +69 -0
- axpilot-0.1.0a1/spikes/s3_input/README.md +80 -0
- axpilot-0.1.0a1/spikes/s4_capture/README.md +64 -0
- axpilot-0.1.0a1/spikes/s5_ci_permissions/README.md +54 -0
- axpilot-0.1.0a1/spikes/s6_mcp_interop/README.md +46 -0
- axpilot-0.1.0a1/spikes/tests/conftest.py +54 -0
- axpilot-0.1.0a1/spikes/tests/stub_mcp_server.py +42 -0
- axpilot-0.1.0a1/spikes/tests/test_kit.py +126 -0
- axpilot-0.1.0a1/spikes/tests/test_s1.py +364 -0
- axpilot-0.1.0a1/spikes/tests/test_s2_s3_s4.py +283 -0
- axpilot-0.1.0a1/spikes/tests/test_s5.py +152 -0
- axpilot-0.1.0a1/spikes/tests/test_s6.py +157 -0
- axpilot-0.1.0a1/spikes/tests/test_spikelib.py +102 -0
- axpilot-0.1.0a1/src/axpilot/__init__.py +30 -0
- axpilot-0.1.0a1/src/axpilot/__main__.py +8 -0
- axpilot-0.1.0a1/src/axpilot/bridge/__init__.py +1 -0
- axpilot-0.1.0a1/src/axpilot/bridge/client.py +99 -0
- axpilot-0.1.0a1/src/axpilot/bridge/launch.py +132 -0
- axpilot-0.1.0a1/src/axpilot/bridge/offline.py +88 -0
- axpilot-0.1.0a1/src/axpilot/bridge/protocol.py +249 -0
- axpilot-0.1.0a1/src/axpilot/bridge/stdio_pipe.py +121 -0
- axpilot-0.1.0a1/src/axpilot/cli.py +1002 -0
- axpilot-0.1.0a1/src/axpilot/clientnames.py +41 -0
- axpilot-0.1.0a1/src/axpilot/clients/__init__.py +57 -0
- axpilot-0.1.0a1/src/axpilot/clients/base.py +296 -0
- axpilot-0.1.0a1/src/axpilot/clients/connect.py +814 -0
- axpilot-0.1.0a1/src/axpilot/clients/fileops.py +228 -0
- axpilot-0.1.0a1/src/axpilot/clients/formats.py +293 -0
- axpilot-0.1.0a1/src/axpilot/clients/jsonc.py +133 -0
- axpilot-0.1.0a1/src/axpilot/clients/targets.py +271 -0
- axpilot-0.1.0a1/src/axpilot/config.py +279 -0
- axpilot-0.1.0a1/src/axpilot/doctor.py +496 -0
- axpilot-0.1.0a1/src/axpilot/engine/__init__.py +58 -0
- axpilot-0.1.0a1/src/axpilot/engine/base.py +318 -0
- axpilot-0.1.0a1/src/axpilot/engine/fake.py +3043 -0
- axpilot-0.1.0a1/src/axpilot/engine/fixtures/demo_desktop.json +3804 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/__init__.py +24 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/actions.py +472 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/apps.py +499 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/attributes.py +266 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/ax.py +369 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/capture.py +323 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/carbon.py +270 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/clipboard.py +197 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/displays.py +139 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/engine.py +757 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/helpers.py +1500 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/input.py +200 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/keyboard.py +166 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/menus.py +335 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/notify.py +26 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/permissions.py +167 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/runloop.py +22 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/sync.py +62 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/tree.py +328 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/vision.py +93 -0
- axpilot-0.1.0a1/src/axpilot/engine/macos/windows.py +539 -0
- axpilot-0.1.0a1/src/axpilot/errors.py +151 -0
- axpilot-0.1.0a1/src/axpilot/evals/__init__.py +68 -0
- axpilot-0.1.0a1/src/axpilot/evals/__main__.py +87 -0
- axpilot-0.1.0a1/src/axpilot/evals/checks.py +115 -0
- axpilot-0.1.0a1/src/axpilot/evals/model.py +211 -0
- axpilot-0.1.0a1/src/axpilot/evals/report.py +88 -0
- axpilot-0.1.0a1/src/axpilot/evals/runner.py +316 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/app-hide.toml +22 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/calculator-launch.toml +15 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/clipboard-copy.toml +16 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/explore-app-kind.toml +24 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/finder-documents.toml +21 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/finder-icon-view.toml +21 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/finder-new-folder.toml +21 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/finder-search.toml +21 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/idea-run-configuration.toml +25 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/login-cancel.toml +23 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/login-email.toml +21 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/login-remember.toml +21 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/login-trial-date.toml +21 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/mail-count.toml +19 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/mail-last-message.toml +19 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/notes-count.toml +15 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/notes-new-note-shortcut.toml +16 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/notes-new-note.toml +17 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/notes-open-note.toml +21 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/notes-rewrite-body.toml +21 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/notes-search.toml +21 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/notes-shared-folder.toml +21 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/ocr-canvas.toml +19 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/safety-password-manager.toml +18 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/safety-privacy-settings.toml +18 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/safety-terminal-command.toml +23 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/slack-message.toml +25 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/slack-notifications.toml +25 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/store-country.toml +25 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/store-pickup.toml +25 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/store-shipping.toml +25 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/textedit-append.toml +33 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/textedit-bold.toml +21 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/textedit-center.toml +21 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/textedit-font-size.toml +21 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/textedit-font.toml +21 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/textedit-heading-style.toml +21 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/textedit-italic-underline.toml +33 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/textedit-line-spacing.toml +21 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/textedit-new-document.toml +15 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/window-minimize.toml +20 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/window-move.toml +26 -0
- axpilot-0.1.0a1/src/axpilot/evals/tasks/window-resize.toml +26 -0
- axpilot-0.1.0a1/src/axpilot/host/__init__.py +1 -0
- axpilot-0.1.0a1/src/axpilot/host/__main__.py +20 -0
- axpilot-0.1.0a1/src/axpilot/host/daemon.py +410 -0
- axpilot-0.1.0a1/src/axpilot/host/dialogs.py +74 -0
- axpilot-0.1.0a1/src/axpilot/host/http.py +350 -0
- axpilot-0.1.0a1/src/axpilot/host/killswitch.py +162 -0
- axpilot-0.1.0a1/src/axpilot/host/pairing.py +173 -0
- axpilot-0.1.0a1/src/axpilot/host/session.py +102 -0
- axpilot-0.1.0a1/src/axpilot/host/ui/__init__.py +88 -0
- axpilot-0.1.0a1/src/axpilot/host/ui/app.py +54 -0
- axpilot-0.1.0a1/src/axpilot/host/ui/hotkey.py +101 -0
- axpilot-0.1.0a1/src/axpilot/host/ui/overlay.py +143 -0
- axpilot-0.1.0a1/src/axpilot/input/__init__.py +29 -0
- axpilot-0.1.0a1/src/axpilot/input/coords.py +73 -0
- axpilot-0.1.0a1/src/axpilot/input/dates.py +104 -0
- axpilot-0.1.0a1/src/axpilot/input/hotkeys.py +65 -0
- axpilot-0.1.0a1/src/axpilot/input/keys.py +716 -0
- axpilot-0.1.0a1/src/axpilot/models.py +256 -0
- axpilot-0.1.0a1/src/axpilot/paths.py +83 -0
- axpilot-0.1.0a1/src/axpilot/perception/__init__.py +126 -0
- axpilot-0.1.0a1/src/axpilot/perception/appkind.py +872 -0
- axpilot-0.1.0a1/src/axpilot/perception/diff.py +155 -0
- axpilot-0.1.0a1/src/axpilot/perception/dropdown.py +376 -0
- axpilot-0.1.0a1/src/axpilot/perception/find.py +143 -0
- axpilot-0.1.0a1/src/axpilot/perception/format.py +322 -0
- axpilot-0.1.0a1/src/axpilot/perception/locators.py +886 -0
- axpilot-0.1.0a1/src/axpilot/perception/model.py +209 -0
- axpilot-0.1.0a1/src/axpilot/perception/navigate.py +418 -0
- axpilot-0.1.0a1/src/axpilot/perception/refs.py +585 -0
- axpilot-0.1.0a1/src/axpilot/perception/resolve.py +73 -0
- axpilot-0.1.0a1/src/axpilot/perception/roles.py +128 -0
- axpilot-0.1.0a1/src/axpilot/perception/serialize.py +301 -0
- axpilot-0.1.0a1/src/axpilot/perception/snapshot.py +468 -0
- axpilot-0.1.0a1/src/axpilot/perception/store.py +367 -0
- axpilot-0.1.0a1/src/axpilot/perception/vision.py +372 -0
- axpilot-0.1.0a1/src/axpilot/policy/__init__.py +37 -0
- axpilot-0.1.0a1/src/axpilot/policy/audit.py +317 -0
- axpilot-0.1.0a1/src/axpilot/policy/confirm.py +80 -0
- axpilot-0.1.0a1/src/axpilot/policy/control.py +341 -0
- axpilot-0.1.0a1/src/axpilot/policy/profiles.py +168 -0
- axpilot-0.1.0a1/src/axpilot/policy/ratelimit.py +74 -0
- axpilot-0.1.0a1/src/axpilot/policy/rules.py +431 -0
- axpilot-0.1.0a1/src/axpilot/runloop.py +125 -0
- axpilot-0.1.0a1/src/axpilot/sdk/__init__.py +38 -0
- axpilot-0.1.0a1/src/axpilot/sdk/desktop.py +784 -0
- axpilot-0.1.0a1/src/axpilot/sdk/results.py +469 -0
- axpilot-0.1.0a1/src/axpilot/server/__init__.py +32 -0
- axpilot-0.1.0a1/src/axpilot/server/app.py +214 -0
- axpilot-0.1.0a1/src/axpilot/server/context.py +534 -0
- axpilot-0.1.0a1/src/axpilot/server/dropdown.py +734 -0
- axpilot-0.1.0a1/src/axpilot/server/elicit.py +282 -0
- axpilot-0.1.0a1/src/axpilot/server/guard.py +308 -0
- axpilot-0.1.0a1/src/axpilot/server/instructions.py +78 -0
- axpilot-0.1.0a1/src/axpilot/server/naming/__init__.py +40 -0
- axpilot-0.1.0a1/src/axpilot/server/naming/windows_mcp.py +1024 -0
- axpilot-0.1.0a1/src/axpilot/server/portable.py +74 -0
- axpilot-0.1.0a1/src/axpilot/server/registry.py +216 -0
- axpilot-0.1.0a1/src/axpilot/server/results.py +116 -0
- axpilot-0.1.0a1/src/axpilot/server/schemas.py +618 -0
- axpilot-0.1.0a1/src/axpilot/server/tools/__init__.py +18 -0
- axpilot-0.1.0a1/src/axpilot/server/tools/apps.py +493 -0
- axpilot-0.1.0a1/src/axpilot/server/tools/browser.py +601 -0
- axpilot-0.1.0a1/src/axpilot/server/tools/computer.py +384 -0
- axpilot-0.1.0a1/src/axpilot/server/tools/controls.py +524 -0
- axpilot-0.1.0a1/src/axpilot/server/tools/input.py +1767 -0
- axpilot-0.1.0a1/src/axpilot/server/tools/locate.py +474 -0
- axpilot-0.1.0a1/src/axpilot/server/tools/navigate.py +1831 -0
- axpilot-0.1.0a1/src/axpilot/server/tools/observe.py +1447 -0
- axpilot-0.1.0a1/src/axpilot/server/tools/scripting.py +522 -0
- axpilot-0.1.0a1/src/axpilot/server/tools/system.py +554 -0
- axpilot-0.1.0a1/src/axpilot/setup/__init__.py +297 -0
- axpilot-0.1.0a1/src/axpilot/setup/launcher.py +573 -0
- axpilot-0.1.0a1/src/axpilot/setup/runtime.py +492 -0
- axpilot-0.1.0a1/src/axpilot/system/__init__.py +74 -0
- axpilot-0.1.0a1/src/axpilot/system/browser.py +599 -0
- axpilot-0.1.0a1/src/axpilot/system/bundles.py +31 -0
- axpilot-0.1.0a1/src/axpilot/system/defaults.py +212 -0
- axpilot-0.1.0a1/src/axpilot/system/keychain.py +132 -0
- axpilot-0.1.0a1/src/axpilot/system/osascript.py +253 -0
- axpilot-0.1.0a1/src/axpilot/system/processes.py +201 -0
- axpilot-0.1.0a1/src/axpilot/system/runner.py +585 -0
- axpilot-0.1.0a1/src/axpilot/system/shell.py +73 -0
- axpilot-0.1.0a1/src/axpilot/system/shortcuts.py +158 -0
- axpilot-0.1.0a1/src/axpilot/system/spotlight.py +206 -0
- axpilot-0.1.0a1/src/axpilot/system/sysinfo.py +297 -0
- axpilot-0.1.0a1/src/axpilot/testing/__init__.py +49 -0
- axpilot-0.1.0a1/src/axpilot/testing/faulty_engine.py +453 -0
- axpilot-0.1.0a1/src/axpilot/testing/harness.py +119 -0
- axpilot-0.1.0a1/src/axpilot/testing/host.py +46 -0
- axpilot-0.1.0a1/tests/bridge/conftest.py +15 -0
- axpilot-0.1.0a1/tests/bridge/test_launch.py +165 -0
- axpilot-0.1.0a1/tests/bridge/test_offline.py +81 -0
- axpilot-0.1.0a1/tests/bridge/test_protocol.py +180 -0
- axpilot-0.1.0a1/tests/bridge/test_stdio_pipe.py +259 -0
- axpilot-0.1.0a1/tests/cli/conftest.py +15 -0
- axpilot-0.1.0a1/tests/cli/test_cli.py +451 -0
- axpilot-0.1.0a1/tests/cli/test_subprocess.py +395 -0
- axpilot-0.1.0a1/tests/clients/conftest.py +103 -0
- axpilot-0.1.0a1/tests/clients/test_connect.py +851 -0
- axpilot-0.1.0a1/tests/clients/test_fileops.py +157 -0
- axpilot-0.1.0a1/tests/clients/test_formats.py +187 -0
- axpilot-0.1.0a1/tests/clients/test_jsonc.py +108 -0
- axpilot-0.1.0a1/tests/clients/test_resolve_command.py +85 -0
- axpilot-0.1.0a1/tests/clients/test_targets.py +181 -0
- axpilot-0.1.0a1/tests/engine/test_fake.py +1515 -0
- axpilot-0.1.0a1/tests/engine/test_macos_engine.py +1151 -0
- axpilot-0.1.0a1/tests/evals/test_harness.py +337 -0
- axpilot-0.1.0a1/tests/evals/test_suite.py +38 -0
- axpilot-0.1.0a1/tests/examples/test_examples_smoke.py +92 -0
- axpilot-0.1.0a1/tests/host/conftest.py +15 -0
- axpilot-0.1.0a1/tests/host/test_daemon.py +476 -0
- axpilot-0.1.0a1/tests/host/test_dialogs.py +59 -0
- axpilot-0.1.0a1/tests/host/test_http.py +316 -0
- axpilot-0.1.0a1/tests/host/test_killswitch.py +265 -0
- axpilot-0.1.0a1/tests/host/test_pairing.py +111 -0
- axpilot-0.1.0a1/tests/input/test_coords.py +79 -0
- axpilot-0.1.0a1/tests/input/test_dates.py +84 -0
- axpilot-0.1.0a1/tests/input/test_hotkeys.py +42 -0
- axpilot-0.1.0a1/tests/input/test_keycodes.py +198 -0
- axpilot-0.1.0a1/tests/input/test_keys.py +462 -0
- axpilot-0.1.0a1/tests/perception/conftest.py +75 -0
- axpilot-0.1.0a1/tests/perception/golden/locator_exports.txt +46 -0
- axpilot-0.1.0a1/tests/perception/test_appkind.py +677 -0
- axpilot-0.1.0a1/tests/perception/test_diff.py +337 -0
- axpilot-0.1.0a1/tests/perception/test_dropdown.py +282 -0
- axpilot-0.1.0a1/tests/perception/test_find.py +146 -0
- axpilot-0.1.0a1/tests/perception/test_format.py +255 -0
- axpilot-0.1.0a1/tests/perception/test_locators.py +748 -0
- axpilot-0.1.0a1/tests/perception/test_navigate.py +283 -0
- axpilot-0.1.0a1/tests/perception/test_refs.py +543 -0
- axpilot-0.1.0a1/tests/perception/test_resolve.py +148 -0
- axpilot-0.1.0a1/tests/perception/test_roles.py +101 -0
- axpilot-0.1.0a1/tests/perception/test_serialize.py +233 -0
- axpilot-0.1.0a1/tests/perception/test_snapshot.py +550 -0
- axpilot-0.1.0a1/tests/perception/test_snapshot_property.py +110 -0
- axpilot-0.1.0a1/tests/perception/test_store.py +429 -0
- axpilot-0.1.0a1/tests/perception/test_vision.py +201 -0
- axpilot-0.1.0a1/tests/policy/conftest.py +8 -0
- axpilot-0.1.0a1/tests/policy/test_audit.py +424 -0
- axpilot-0.1.0a1/tests/policy/test_confirm.py +85 -0
- axpilot-0.1.0a1/tests/policy/test_control.py +578 -0
- axpilot-0.1.0a1/tests/policy/test_profiles.py +198 -0
- axpilot-0.1.0a1/tests/policy/test_ratelimit.py +144 -0
- axpilot-0.1.0a1/tests/policy/test_rules.py +390 -0
- axpilot-0.1.0a1/tests/sdk/conftest.py +28 -0
- axpilot-0.1.0a1/tests/sdk/test_desktop.py +451 -0
- axpilot-0.1.0a1/tests/server/golden/output_schemas_default.json +14458 -0
- axpilot-0.1.0a1/tests/server/golden/output_schemas_windows-mcp.json +14929 -0
- axpilot-0.1.0a1/tests/server/golden/tools_computer_default.json +116 -0
- axpilot-0.1.0a1/tests/server/golden/tools_computer_windows-mcp.json +116 -0
- axpilot-0.1.0a1/tests/server/golden/tools_full_default.json +2472 -0
- axpilot-0.1.0a1/tests/server/golden/tools_full_windows-mcp.json +2371 -0
- axpilot-0.1.0a1/tests/server/golden/tools_minimal_default.json +631 -0
- axpilot-0.1.0a1/tests/server/golden/tools_minimal_windows-mcp.json +657 -0
- axpilot-0.1.0a1/tests/server/golden/tools_standard_default.json +1893 -0
- axpilot-0.1.0a1/tests/server/golden/tools_standard_windows-mcp.json +1787 -0
- axpilot-0.1.0a1/tests/server/test_app.py +225 -0
- axpilot-0.1.0a1/tests/server/test_context.py +116 -0
- axpilot-0.1.0a1/tests/server/test_dropdown_flow.py +519 -0
- axpilot-0.1.0a1/tests/server/test_elicit_unit.py +205 -0
- axpilot-0.1.0a1/tests/server/test_elicitation.py +295 -0
- axpilot-0.1.0a1/tests/server/test_fuzz.py +500 -0
- axpilot-0.1.0a1/tests/server/test_guard.py +465 -0
- axpilot-0.1.0a1/tests/server/test_hardening.py +133 -0
- axpilot-0.1.0a1/tests/server/test_portability.py +111 -0
- axpilot-0.1.0a1/tests/server/test_safety.py +164 -0
- axpilot-0.1.0a1/tests/server/test_stable_refs.py +366 -0
- axpilot-0.1.0a1/tests/server/test_stable_refs_property.py +345 -0
- axpilot-0.1.0a1/tests/server/test_surface.py +140 -0
- axpilot-0.1.0a1/tests/server/tools/test_apps.py +441 -0
- axpilot-0.1.0a1/tests/server/tools/test_browser.py +485 -0
- axpilot-0.1.0a1/tests/server/tools/test_computer.py +339 -0
- axpilot-0.1.0a1/tests/server/tools/test_controls.py +480 -0
- axpilot-0.1.0a1/tests/server/tools/test_dropdowns.py +862 -0
- axpilot-0.1.0a1/tests/server/tools/test_input.py +1189 -0
- axpilot-0.1.0a1/tests/server/tools/test_locate.py +533 -0
- axpilot-0.1.0a1/tests/server/tools/test_naming.py +436 -0
- axpilot-0.1.0a1/tests/server/tools/test_navigate.py +1050 -0
- axpilot-0.1.0a1/tests/server/tools/test_observe.py +412 -0
- axpilot-0.1.0a1/tests/server/tools/test_scripting.py +525 -0
- axpilot-0.1.0a1/tests/server/tools/test_system.py +473 -0
- axpilot-0.1.0a1/tests/setup/conftest.py +143 -0
- axpilot-0.1.0a1/tests/setup/test_launcher.py +372 -0
- axpilot-0.1.0a1/tests/setup/test_runtime.py +365 -0
- axpilot-0.1.0a1/tests/setup/test_setup.py +209 -0
- axpilot-0.1.0a1/tests/system/conftest.py +90 -0
- axpilot-0.1.0a1/tests/system/test_browser.py +446 -0
- axpilot-0.1.0a1/tests/system/test_defaults.py +187 -0
- axpilot-0.1.0a1/tests/system/test_keychain.py +124 -0
- axpilot-0.1.0a1/tests/system/test_osascript.py +292 -0
- axpilot-0.1.0a1/tests/system/test_processes.py +217 -0
- axpilot-0.1.0a1/tests/system/test_runner.py +473 -0
- axpilot-0.1.0a1/tests/system/test_shell.py +81 -0
- axpilot-0.1.0a1/tests/system/test_shortcuts.py +163 -0
- axpilot-0.1.0a1/tests/system/test_spotlight.py +203 -0
- axpilot-0.1.0a1/tests/system/test_sysinfo.py +271 -0
- axpilot-0.1.0a1/tests/test_clientnames.py +33 -0
- axpilot-0.1.0a1/tests/test_config.py +150 -0
- axpilot-0.1.0a1/tests/test_doctor.py +591 -0
- axpilot-0.1.0a1/tests/test_models.py +36 -0
- axpilot-0.1.0a1/tests/test_release_script.py +322 -0
- axpilot-0.1.0a1/tests/test_runloop.py +224 -0
- axpilot-0.1.0a1/tests/test_tool_docs.py +53 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
*.lcov
|
|
51
|
+
.hypothesis/
|
|
52
|
+
.pytest_cache/
|
|
53
|
+
cover/
|
|
54
|
+
|
|
55
|
+
# Translations
|
|
56
|
+
*.mo
|
|
57
|
+
*.pot
|
|
58
|
+
|
|
59
|
+
# Django stuff:
|
|
60
|
+
*.log
|
|
61
|
+
local_settings.py
|
|
62
|
+
db.sqlite3
|
|
63
|
+
db.sqlite3-journal
|
|
64
|
+
|
|
65
|
+
# Flask stuff:
|
|
66
|
+
instance/
|
|
67
|
+
.webassets-cache
|
|
68
|
+
|
|
69
|
+
# Scrapy stuff:
|
|
70
|
+
.scrapy
|
|
71
|
+
|
|
72
|
+
# Sphinx documentation
|
|
73
|
+
docs/_build/
|
|
74
|
+
|
|
75
|
+
# PyBuilder
|
|
76
|
+
.pybuilder/
|
|
77
|
+
target/
|
|
78
|
+
|
|
79
|
+
# Jupyter Notebook
|
|
80
|
+
.ipynb_checkpoints
|
|
81
|
+
|
|
82
|
+
# IPython
|
|
83
|
+
profile_default/
|
|
84
|
+
ipython_config.py
|
|
85
|
+
|
|
86
|
+
# pyenv
|
|
87
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
88
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
89
|
+
# .python-version
|
|
90
|
+
|
|
91
|
+
# pipenv
|
|
92
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
93
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
94
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
95
|
+
# install all needed dependencies.
|
|
96
|
+
# Pipfile.lock
|
|
97
|
+
|
|
98
|
+
# uv
|
|
99
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
100
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
101
|
+
# commonly ignored for libraries.
|
|
102
|
+
# uv.lock
|
|
103
|
+
|
|
104
|
+
# poetry
|
|
105
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
106
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
107
|
+
# commonly ignored for libraries.
|
|
108
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
109
|
+
# poetry.lock
|
|
110
|
+
# poetry.toml
|
|
111
|
+
|
|
112
|
+
# pdm
|
|
113
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
114
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
115
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
116
|
+
# pdm.lock
|
|
117
|
+
# pdm.toml
|
|
118
|
+
.pdm-python
|
|
119
|
+
.pdm-build/
|
|
120
|
+
|
|
121
|
+
# pixi
|
|
122
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
123
|
+
# pixi.lock
|
|
124
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
125
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
126
|
+
.pixi/*
|
|
127
|
+
!.pixi/config.toml
|
|
128
|
+
|
|
129
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
130
|
+
__pypackages__/
|
|
131
|
+
|
|
132
|
+
# Celery stuff
|
|
133
|
+
celerybeat-schedule*
|
|
134
|
+
celerybeat.pid
|
|
135
|
+
|
|
136
|
+
# Redis
|
|
137
|
+
*.rdb
|
|
138
|
+
*.aof
|
|
139
|
+
*.pid
|
|
140
|
+
|
|
141
|
+
# RabbitMQ
|
|
142
|
+
mnesia/
|
|
143
|
+
rabbitmq/
|
|
144
|
+
rabbitmq-data/
|
|
145
|
+
|
|
146
|
+
# ActiveMQ
|
|
147
|
+
activemq-data/
|
|
148
|
+
|
|
149
|
+
# SageMath parsed files
|
|
150
|
+
*.sage.py
|
|
151
|
+
|
|
152
|
+
# Environments
|
|
153
|
+
.env
|
|
154
|
+
.envrc
|
|
155
|
+
.venv
|
|
156
|
+
env/
|
|
157
|
+
venv/
|
|
158
|
+
ENV/
|
|
159
|
+
env.bak/
|
|
160
|
+
venv.bak/
|
|
161
|
+
|
|
162
|
+
# Spyder project settings
|
|
163
|
+
.spyderproject
|
|
164
|
+
.spyproject
|
|
165
|
+
|
|
166
|
+
# Rope project settings
|
|
167
|
+
.ropeproject
|
|
168
|
+
|
|
169
|
+
# mkdocs/Zensical documentation
|
|
170
|
+
/site
|
|
171
|
+
|
|
172
|
+
# mypy
|
|
173
|
+
.mypy_cache/
|
|
174
|
+
.dmypy.json
|
|
175
|
+
dmypy.json
|
|
176
|
+
|
|
177
|
+
# Pyre type checker
|
|
178
|
+
.pyre/
|
|
179
|
+
|
|
180
|
+
# pytype static type analyzer
|
|
181
|
+
.pytype/
|
|
182
|
+
|
|
183
|
+
# Cython debug symbols
|
|
184
|
+
cython_debug/
|
|
185
|
+
|
|
186
|
+
# PyCharm
|
|
187
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
188
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
189
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
190
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
191
|
+
# .idea/
|
|
192
|
+
|
|
193
|
+
# Abstra
|
|
194
|
+
# Abstra is an AI-powered process automation framework.
|
|
195
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
196
|
+
# Learn more at https://abstra.io/docs
|
|
197
|
+
.abstra/
|
|
198
|
+
|
|
199
|
+
# Visual Studio Code
|
|
200
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore that
|
|
201
|
+
# can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
202
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer, you
|
|
203
|
+
# could uncomment the following to ignore the entire vscode folder
|
|
204
|
+
# .vscode/
|
|
205
|
+
# Temporary file for partial code execution
|
|
206
|
+
tempCodeRunnerFile.py
|
|
207
|
+
|
|
208
|
+
# Ruff stuff:
|
|
209
|
+
.ruff_cache/
|
|
210
|
+
|
|
211
|
+
# PyPI configuration file
|
|
212
|
+
.pypirc
|
|
213
|
+
|
|
214
|
+
# Marimo
|
|
215
|
+
marimo/_static/
|
|
216
|
+
marimo/_lsp/
|
|
217
|
+
__marimo__/
|
|
218
|
+
|
|
219
|
+
# Streamlit
|
|
220
|
+
.streamlit/secrets.toml
|
|
221
|
+
|
|
222
|
+
# --- macOS / AXPilot ---
|
|
223
|
+
.DS_Store
|
|
224
|
+
*.xcuserstate
|
|
225
|
+
xcuserdata/
|
|
226
|
+
DerivedData/
|
|
227
|
+
launcher/build/
|
|
228
|
+
spikes/**/results/*
|
|
229
|
+
!spikes/**/results/.gitkeep
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to AXPilot are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
|
|
6
|
+
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Tool names, parameters,
|
|
7
|
+
output schemas and error codes are public API: breaking changes to them are called out under
|
|
8
|
+
**Changed** or **Removed** with a migration note. The launcher (`AXPilot.app`) has its own version
|
|
9
|
+
line; a new launcher version requires a one-time permission re-grant, which is always flagged here.
|
|
10
|
+
|
|
11
|
+
## [Unreleased]
|
|
12
|
+
|
|
13
|
+
## [0.1.0a1] - 2026-10-21
|
|
14
|
+
|
|
15
|
+
The first alpha, for early testers: AXPilot on PyPI for macOS 14 or later. It is verified on
|
|
16
|
+
macOS 26 on Apple silicon; macOS 14 and 15 and Intel Macs are not tested yet. Expect breaking
|
|
17
|
+
changes until 1.0. The wheel embeds launcher 1.0.0 (`launcher-v1`, pinned in `launcher/CDHASH.md`):
|
|
18
|
+
the `AXPilot.app` you grant Accessibility and Screen Recording to once.
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- Locators for automation scripts. `locate` turns an element ref into a *locator*: a small JSON
|
|
23
|
+
object that names the element by its AXIdentifier, role and name, its containers or its
|
|
24
|
+
position, and still works in later sessions (refs only last for one). It returns a few
|
|
25
|
+
candidates, best first, each checked against a fresh capture of the window so that it names only
|
|
26
|
+
that element, graded `high` (an identifier), `medium` (role and name, which change with the app's
|
|
27
|
+
language) or `low` (a position), with warnings such as a missing identifier or a toolbar that can
|
|
28
|
+
overflow; it can also write the locator as an AXPilot SDK snippet. `locate(locator=…)` checks a
|
|
29
|
+
locator against the live window, and `locate(refs=[…])` locates every element of a screen in one
|
|
30
|
+
call, with one script for all of them (the steps of a flow: the agent locates each screen before
|
|
31
|
+
leaving it, since a closed screen's elements can't be checked; a secure field's text comes from
|
|
32
|
+
an environment variable). Agents call it only when asked for locators, a script or a test.
|
|
33
|
+
`find(locator=…)` looks one up with exact matching (also with
|
|
34
|
+
`scroll=true`) and reports `count` and `unique`; in the SDK, `find(locator=…).click()` raises the
|
|
35
|
+
new error codes `ELEMENT_NOT_FOUND` and `LOCATOR_AMBIGUOUS` instead of guessing. See
|
|
36
|
+
[Locators](docs/locators.md).
|
|
37
|
+
- Dropdowns in every kind of app: `select_option` opens the control, waits for its menu or list,
|
|
38
|
+
picks the option by title or index, checks that the control took it, and closes the menu again
|
|
39
|
+
if anything fails (including the kill switch). It covers pop-up buttons (also when their menu
|
|
40
|
+
belongs to the application), menu buttons such as Notes "Format" and Finder "Action" (refused
|
|
41
|
+
before), combo boxes (Java and Qt ones whose list opens in a window of its own), web `<select>`
|
|
42
|
+
elements, and custom web and Electron pickers (React Select, MUI, Slack, VS Code), which get
|
|
43
|
+
real mouse clicks; a web combo box that shows nothing on a click gets the Down arrow, and one
|
|
44
|
+
that does not list the option is typed into to filter it (the text is put back on failure).
|
|
45
|
+
`set_value` and `fill_form` choose pop-up options the same way. Snapshots taken while a menu is
|
|
46
|
+
open list its items, so opening a menu with `perform_action` and clicking an item also works.
|
|
47
|
+
- The first time a tool finds Accessibility missing (or a screenshot finds Screen Recording
|
|
48
|
+
missing), AXPilot shows macOS's own permission prompt, which also lists AXPilot in System
|
|
49
|
+
Settings, ready to be switched on. Before, a new user had to add AXPilot.app there by hand.
|
|
50
|
+
- `axpilot doctor` in launcher mode no longer judges Accessibility and Screen Recording by the app
|
|
51
|
+
it runs in (a terminal without them showed a failure although AXPilot.app worked); it says it
|
|
52
|
+
did not check AXPilot.app and shows the terminal's grants as information for direct mode.
|
|
53
|
+
- `axpilot stdio` completes the MCP handshake even when it cannot reach the AXPilot host
|
|
54
|
+
(AXPilot.app not installed, the host does not start, or it refused this client): it prints the
|
|
55
|
+
error on stderr, lists the usual tools and returns the error with its hint ("Run `axpilot setup`
|
|
56
|
+
once") from every tool call, so MCP clients show the reason instead of "server failed to start".
|
|
57
|
+
- A CI job builds the Swift launcher (`launcher/build.sh`) on macOS and runs its contract tests
|
|
58
|
+
against the built bundle on every change; nothing is published.
|
|
59
|
+
- An eval suite (`python -m axpilot.evals`): 43 tasks on the simulated desktop (input, controls,
|
|
60
|
+
dropdowns, menus, windows, long lists, OCR, web pages, an Electron and a Java app, and safety
|
|
61
|
+
requests that must not succeed), judged by state through read-only tools. A scripted agent replays each task's reference
|
|
62
|
+
solution in CI; model-backed agents plug in as `module:factory` and get JSON and Markdown reports.
|
|
63
|
+
- The kill switch and the on-screen indicator (macOS, real engine; not yet run on a Mac): ⌃⌥⌘.
|
|
64
|
+
(`[safety] kill_switch`) stops the input action in progress and pauses AXPilot, and pressing it
|
|
65
|
+
again resumes; a frame around the screen and a status pill show while AXPilot acts
|
|
66
|
+
(`[safety] indicator`), orange while paused. The hotkey is a Carbon hotkey (no permission
|
|
67
|
+
needed); the UI is best effort, so the server runs on without it if AppKit fails.
|
|
68
|
+
- The HTTP bearer token lives in the macOS login keychain (`[server] token_store`, `auto` by
|
|
69
|
+
default). A token from the old file moves there, so configured clients keep working; a locked
|
|
70
|
+
or unavailable keychain falls back to the private file with a warning. The token is written
|
|
71
|
+
through `security`'s standard input, never in a command line.
|
|
72
|
+
- Confirmations through the MCP client in direct mode: a client that supports elicitation shows
|
|
73
|
+
AXPilot's question in its own window (`[safety] elicitation`, on by default; off with `--yes`).
|
|
74
|
+
On protocol 2026-07-28 the question ends the call with an `InputRequiredResult` and the
|
|
75
|
+
client's retry carries the answer, which counts once, for the same call and question, within
|
|
76
|
+
the confirmation timeout. While the question is open every acting tool waits with
|
|
77
|
+
`NEEDS_USER`. Clients without elicitation keep the dialog or the safe "no".
|
|
78
|
+
- Project plan ([docs/PLAN.md](docs/PLAN.md)) and architecture decision records for language,
|
|
79
|
+
architecture, minimum macOS, MCP surface, signing and distribution, privacy, and the name
|
|
80
|
+
([docs/adr/](docs/adr/README.md)).
|
|
81
|
+
- Package foundation: stable error codes with hints (`axpilot.errors`), platform-independent data
|
|
82
|
+
types (`axpilot.models`), configuration with TOML file, `AXPILOT_<SECTION>_<KEY>` environment
|
|
83
|
+
variables and CLI overrides (`axpilot.config`), and redirectable filesystem locations
|
|
84
|
+
(`axpilot.paths`).
|
|
85
|
+
- The `Engine` interface, the in-memory `FakeEngine` with a demo desktop fixture for tests and
|
|
86
|
+
`--engine fake`, and the PyObjC-based macOS engine.
|
|
87
|
+
- Perception: accessibility snapshots with refs, pruning, paging, diffs, fuzzy element search,
|
|
88
|
+
the compact text format, and snapshot and capture stores.
|
|
89
|
+
- Stable element refs: a ref is unique per session, never reused for another element, and kept
|
|
90
|
+
by its element across snapshots of a window, so refs held from earlier snapshots keep working
|
|
91
|
+
after actions re-snapshot the UI. A ref whose element is gone, or a list row that scrolled
|
|
92
|
+
away, gives `STALE_REF` instead of hitting another element. Diffs pair equal refs first.
|
|
93
|
+
- Navigation tools: `explore` (a map of an app: windows, menus with item counts, toolbar, tabs,
|
|
94
|
+
sidebar, scroll areas, dialogs, focus and its compatibility profile), `find` (fuzzy search that
|
|
95
|
+
can scroll a list or page until the element appears), `scroll` (by lines or pages, to the top or
|
|
96
|
+
bottom, or an element into view; reports `moved` and `at_end`) and `read` (the whole content of a
|
|
97
|
+
long list, table, text view or web page, joined page by page without repeats, with `complete`).
|
|
98
|
+
Scrolling measures the app's line height, applies the input policy and lock, and every loop is
|
|
99
|
+
bounded, returning partial results with a warning instead of failing.
|
|
100
|
+
- App and system tools: `app` (launch, activate, hide, unhide, quit, force-quit), `window` (focus,
|
|
101
|
+
move, resize, minimize, restore, zoom, full screen, close), `open` (URLs, files and folders; only
|
|
102
|
+
http(s), mailto, file and System Settings URLs unless scripting is enabled), `clipboard` (text,
|
|
103
|
+
images, files), `notify`, `spotlight_search`, `system_info`, `system_control` (volume, mute,
|
|
104
|
+
appearance) and `processes` (list; stopping one refuses system processes, AXPilot and protected
|
|
105
|
+
apps before asking the user). A `manage` policy kind applies the deny lists to app and window
|
|
106
|
+
management without the Terminal typing rule; protected apps are recognized by their bundle id,
|
|
107
|
+
even renamed.
|
|
108
|
+
- Scripting tools, off by default: `shell` (zsh with the user's PATH), `applescript` (AppleScript
|
|
109
|
+
and JXA), `shortcuts` (list and run) and `defaults` (read and write preferences). Every command,
|
|
110
|
+
script, shortcut run and preference change is shown to the user for approval, after the call is
|
|
111
|
+
validated; apps a script names and preference domains are checked against the deny lists.
|
|
112
|
+
- Browser tools, off by default: `browser_tabs` (list, switch, open, close in Safari and Chromium
|
|
113
|
+
browsers), `browser_read` (the page's text through accessibility, in reading order, paged) and
|
|
114
|
+
`browser_eval_js` (approved per script, showing the page and the code). URLs and scripts are
|
|
115
|
+
embedded as escaped AppleScript strings; tabs matching `deny_windows` are hidden.
|
|
116
|
+
- The `computer` tool and profile: screenshot-pixel computer use (clicks, drags, typing, keys with
|
|
117
|
+
xdotool-style names, scrolling, waiting, the cursor position) with the same policy hit-testing,
|
|
118
|
+
rate limit, input lock and kill switch as the other input tools.
|
|
119
|
+
- The automation SDK: `from axpilot import Desktop` (blocking, thread-safe) or `AsyncDesktop`, with
|
|
120
|
+
typed results and element handles (`mac.find("Share").click()`), on the simulated desktop
|
|
121
|
+
(`Desktop.fake()`), in-process (`Desktop.direct()`) or through AXPilot.app
|
|
122
|
+
(`Desktop.connect()`). Scripts use the same tools, policy, confirmations, audit log and error
|
|
123
|
+
codes as agents.
|
|
124
|
+
- Examples: five automation scripts that run against the simulated desktop, and agent examples
|
|
125
|
+
for thirteen frameworks (OpenAI Agents SDK, LangGraph, CrewAI, Google ADK, Pydantic AI,
|
|
126
|
+
LlamaIndex, smolagents, Microsoft Agent Framework, Claude Agent SDK, Agno, Strands Agents, Vercel AI
|
|
127
|
+
SDK, Mastra).
|
|
128
|
+
- `select_option` (dropdowns, radio and tab groups, segmented controls, list rows by title or
|
|
129
|
+
index) and `handle_dialog` (read a sheet or dialog; accept, cancel or press a button;
|
|
130
|
+
buttons that delete or discard ask first, before `text` is typed into the dialog, so a "no"
|
|
131
|
+
changes nothing; in open and save panels, `path` goes to a folder or file with Go to the folder
|
|
132
|
+
first).
|
|
133
|
+
- Menu bar extras: `select_menu` with `extras: true` lists and chooses status items (Wi‑Fi,
|
|
134
|
+
Battery, an app's icon; Control Center by default); a one-title path clicks the item. Menu
|
|
135
|
+
titles match across hyphen variants ("wi-fi" finds "Wi‑Fi").
|
|
136
|
+
- Date pickers: `set_value` takes ISO 8601 dates and times (`"2026-10-20"`, `"2026-10-20 14:30"`,
|
|
137
|
+
`"14:30"` for a time field), sends them as dates and checks what the picker shows; snapshots
|
|
138
|
+
show `AXDateTimeArea` pickers as `date` and time fields as `time`, in local time.
|
|
139
|
+
- Table column headers show how the table is sorted (`value` "ascending"/"descending"); color wells
|
|
140
|
+
get a clear `ELEMENT_NOT_ACTIONABLE` that points to the Colors panel; the Agent Skill covers
|
|
141
|
+
editing table cells and toolbar items hidden behind `»`.
|
|
142
|
+
- Portable input schemas that OpenAI, Gemini and Anthropic function calling all accept (no `null`
|
|
143
|
+
unions or `$ref`s, `additionalProperties: false`, every parameter described), and an optional
|
|
144
|
+
tool-name prefix (`[tools] prefix = "mac_"`).
|
|
145
|
+
- The tool reference ([docs/tools.md](docs/tools.md)) is generated from the tool registry
|
|
146
|
+
(`scripts/gen_tool_docs.py`), and golden files pin `tools/list` for every profile and naming.
|
|
147
|
+
- The `windows-mcp` tool naming (`[tools] naming` or `--naming windows-mcp`): Windows-MCP's tool
|
|
148
|
+
names and parameter shapes (`Click(loc=[x, y])`, `Type(text, label=12)`, `Shortcut`, `App`,
|
|
149
|
+
`MultiSelect`, `Shell` for PowerShell, `Defaults` for Registry, …) on top of AXPilot's tools, so
|
|
150
|
+
Windows-MCP prompts and agents carry over to macOS.
|
|
151
|
+
- The AXPilot host and the stdio bridge: MCP clients run `axpilot stdio`, which starts
|
|
152
|
+
`AXPilot.app` if needed and connects to the host's private Unix socket (`0600` in a `0700`
|
|
153
|
+
folder, same-user only). The host asks once per client app whether it may connect, remembers
|
|
154
|
+
the answer, gives each client its own profile and naming, and limits concurrent clients.
|
|
155
|
+
`axpilot stdio --direct` and `--engine fake` run the server in-process instead.
|
|
156
|
+
- Streamable HTTP (`axpilot http`): loopback only by default, a bearer token stored privately,
|
|
157
|
+
`Host` and `Origin` checks and no CORS; other addresses need `--allow-remote` and TLS.
|
|
158
|
+
- The `axpilot` command: `stdio`, `http`, `host`, `setup`, `update`, `uninstall`, `doctor`,
|
|
159
|
+
`connect`/`disconnect`, `config`, `skill install`, `tools`, `call`, `debug dump-tree` and
|
|
160
|
+
`version`, with documented exit codes, `--json` output, one-line errors and tracebacks only with
|
|
161
|
+
`--debug`. The Agent Skill ships inside the package.
|
|
162
|
+
- Input helpers: key-combo parsing (`cmd+shift+t`, `⌘⇧T`, `Command-Shift-T`) and screenshot-to-screen
|
|
163
|
+
coordinate mapping.
|
|
164
|
+
- Policy layer: profiles and toolsets, app and window deny-lists, the Terminal rule, secure-field
|
|
165
|
+
protection, confirmations, rate limiting, an audit log with argument redaction, and input
|
|
166
|
+
serialization with yield-to-user and pause.
|
|
167
|
+
- Command-line integrations: a subprocess runner with timeouts, AppleScript/JXA, shell, Spotlight,
|
|
168
|
+
Shortcuts, `defaults`, processes, system information and browser tab scripting.
|
|
169
|
+
- The frozen launcher source (`launcher/`), its build script and tests, and harnesses for
|
|
170
|
+
spikes S1–S6.
|
|
171
|
+
- Documentation site skeleton, contributor guide, security policy, code of conduct, AGENTS.md,
|
|
172
|
+
issue and pull request templates, CI workflow, Dependabot and pre-commit configuration, the
|
|
173
|
+
Agent Skill (`skills/axpilot/SKILL.md`), MCP Registry metadata and the installer script
|
|
174
|
+
(`packaging/`).
|
|
175
|
+
|
|
176
|
+
### Fixed
|
|
177
|
+
|
|
178
|
+
- The pairing dialog, `status`, the pairing file and logs named Claude Code `claude` (the bundle
|
|
179
|
+
it runs in inside the Claude app), and command-line clients by their program (`codex`,
|
|
180
|
+
`gemini`). Known clients now show their readable name ("Claude Code", "Codex CLI", "Gemini
|
|
181
|
+
CLI"…); other names are unchanged, and pairing decisions stay keyed as before, so nobody is
|
|
182
|
+
asked again (#21).
|
|
183
|
+
- `set_value` and `fill_form` refused a date field in a web page (`<input type="date">`):
|
|
184
|
+
browsers ignore an accessibility value there. AXPilot now focuses each part (month, day, year,
|
|
185
|
+
in the order the page shows them, whatever the language) and types it, then reads the parts
|
|
186
|
+
back. Only a date is typed; a value with a time is refused with a hint (#26).
|
|
187
|
+
- `select_option` and `set_value` on TextEdit's font-size box (macOS 26) found no options: its list
|
|
188
|
+
holds text-field rows, which AXPilot did not count as options. They are read now, so the size is
|
|
189
|
+
picked from the list.
|
|
190
|
+
- When a combo box's list opened but could not be read, AXPilot clicked the box's arrow next; on
|
|
191
|
+
macOS 26 the list can cover the box, so that click chose whatever option lay there (9 pt instead
|
|
192
|
+
of 24). AXPilot no longer clicks a combo box that reports its list open, and says so.
|
|
193
|
+
- `set_value` with a size TextEdit's font-size box does not list (15) failed with "cannot take
|
|
194
|
+
keyboard focus": on macOS 26 that box refuses focus through accessibility. AXPilot now clicks its
|
|
195
|
+
text instead, then presses Return.
|
|
196
|
+
- After a pick from TextEdit's font-size list, `select_option` warned that the list "may still be
|
|
197
|
+
open" and pressed Escape, which opened TextEdit's word-completion popup: macOS 26 keeps the closed
|
|
198
|
+
list's elements valid. The box's own expanded state now tells whether its list is open.
|
|
199
|
+
- Web date fields still failed in Safari and Chrome (macOS 26): a part's digits went in as one key
|
|
200
|
+
event, and the browsers keep only its first character, so "03" set the month to 0 and "2026"
|
|
201
|
+
the year to 2. Each digit is now its own keystroke.
|
|
202
|
+
- In Chrome, a web date field that took the date was then reported as failed: the parts read back
|
|
203
|
+
as numbers (2026.0), which AXPilot compared as 20260. They are read as numbers now.
|
|
204
|
+
- `explore` listed the files of Finder's list view as sidebar sections: every outline's rows
|
|
205
|
+
counted. Only an outline named like a sidebar, or a narrow one along a window edge, is a sidebar
|
|
206
|
+
now; a wide one is the window's content and stays under scroll areas (#19).
|
|
207
|
+
- AXPilot could switch on the full accessibility tree (`AXManualAccessibility`) of an Electron or
|
|
208
|
+
Chromium app the agent never targeted: after an action whose app quit, the report of whatever
|
|
209
|
+
app came forward (often the MCP client itself) did so, and a call without `app` could read an app
|
|
210
|
+
that came forward after the policy check. Reports of an untargeted app now read it as it is, and
|
|
211
|
+
a call without `app` stays on the frontmost app the policy checked (#23).
|
|
212
|
+
- Clipboard reads and writes (the `clipboard` tool, and saving and restoring the clipboard around
|
|
213
|
+
a paste) ran on a worker thread, where macOS complains about apps fulfilling copied data
|
|
214
|
+
synchronously. They now run on the main thread, waiting at most 0.5 s for it, then as before on
|
|
215
|
+
the worker; work left waiting there is cancelled, so a late restore can never undo a newer copy
|
|
216
|
+
(#25).
|
|
217
|
+
- When AXPilot.app crashed or was force-quit, the host it started kept running and held the
|
|
218
|
+
socket, with nothing left to restart it. A host started by AXPilot.app now notices within a
|
|
219
|
+
second that its launcher is gone and stops cleanly (#29).
|
|
220
|
+
- `set_value` and `select_option` reported success on a native combo box such as TextEdit's font
|
|
221
|
+
size, but the text kept its size: setting a combo box's text only changes what it shows, and the
|
|
222
|
+
app acts on a pick from its list or on Return. Both tools now pick the value from the box's own
|
|
223
|
+
list (opened with its arrow), even when the box already shows it; `set_value` with text that is
|
|
224
|
+
not an option types it and presses Return, except in a dialog, where Return would press the
|
|
225
|
+
default button and a warning says so instead. `set_value` also works on Java and Qt combo boxes,
|
|
226
|
+
whose text cannot be set (#33).
|
|
227
|
+
|
|
228
|
+
[Unreleased]: https://github.com/vansh3503/Mac-Mcp/compare/v0.1.0a1...HEAD
|
|
229
|
+
[0.1.0a1]: https://github.com/vansh3503/Mac-Mcp/releases/tag/v0.1.0a1
|
axpilot-0.1.0a1/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|