| name | macos-agent-ops |
|---|---|
| description | Use Homebrew-installed macos-agent to run repeatable app automation checks and routine tasks on macOS. |
Prereqs:
- macOS host with Accessibility and Automation permissions granted for Terminal and target apps.
- Homebrew-installed
macos-agentavailable onPATH. cliclick,osascript, andim-selectavailable onPATH.ABC/USinput source enabled in macOS Input Sources.- For full AX surface (
ax attr/action/session/watch), Hammerspoon runtime should be healthy (hs+hs.ipc).
Inputs:
- Command entrypoint:
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh. - Optional env vars:
MACOS_AGENT_OPS_INPUT_SOURCE_ID(preferred; example:abc) for deterministic input source target.MACOS_AGENT_REAL_E2E_INPUT_SOURCE(legacy fallback) ifMACOS_AGENT_OPS_INPUT_SOURCE_IDis unset.MACOS_AGENT_OPS_SKIP_INPUT_SOURCE_SWITCH=1to bypass automatic input source switch.CODEX_MACOS_AGENT_AX_BACKEND=auto|hammerspoon|applescriptto control AX backend preference.
Outputs:
- macos-agent JSON/text command output.
- Artifacts generated by macos-agent under
$AGENT_HOME/out/(screenshots, traces, debug bundles, step ledgers).
Exit codes:
0: success1: runtime failure or missing runtime dependency2: usage error
Failure modes:
wait app-activetimeouts because focus was stolen (Control Center/Spotlight/notifications).window.activatefailure when app relaunch/update state is stuck; wrapper now uses--reopen-on-fail.- missing
im-selectcausesinput-sourcefailure before keyboard-input actions. not authorized/ Apple Events denial from TCC permissions.- AX target mismatch (selector too broad / stale node id) during
axoperations. - AX gate failures (
--gate-*) when app/window/selector readiness conditions are not met. - AX postcondition failures (
--postcondition-*) when state does not change as expected after mutation. observe screenshot --if-changed-baselinepath missing or unreadable.- trace directory validation failures when using
--trace/--trace-dirand path is not writable.
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh
- Resolve Homebrew
macos-agentbinary path:
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh where- Ensure deterministic input source (default target:
abc):
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh input-source
# or explicit source id
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh input-source --id com.apple.keylayout.ABC- Run readiness checks (
preflight+ AX list smoke check):
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh doctor
# optional target for AX smoke
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh doctor --ax-app Arc
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh doctor --ax-bundle-id com.google.Chrome- Inspect unified permission state directly (
screen_recording/accessibility/automation/ready):
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh run -- \
--format json preflight --include-probes- Run quick app foreground check with reopen recovery:
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh app-check --app Finder
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh app-check --app Arc --timeout-ms 15000
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh app-check --bundle-id com.google.Chrome- Run AX-only health check (AX tree probe):
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh ax-check --app Arc --role AXWindow
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh ax-check --app Arc --role AXTextField --title-contains Search- Use AX wait primitives before mutation to stabilize dynamic UI:
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh run -- \
--format json wait ax-present --app Arc --role AXButton --title-contains "Compose" \
--match-strategy contains --timeout-ms 2500 --poll-ms 80
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh run -- \
--format json wait ax-unique --app Arc --role AXTextField --title-contains "Search" \
--selector-explain --timeout-ms 2500 --poll-ms 80- Run robust mutating AX actions with gating + postconditions:
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh run -- \
--format json ax click --app Arc --role AXButton --title-contains "Play" \
--match-strategy contains --selector-explain --reselect-before-click \
--fallback-order ax-press,ax-confirm,frame-center,coordinate \
--gate-app-active --gate-window-present --gate-ax-unique \
--postcondition-focused true --postcondition-timeout-ms 2000 \
--allow-coordinate-fallback$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh run -- \
--format json ax type --app Arc --role AXTextField --title-contains "Search" \
--text "lofi" --clear-first --submit --paste \
--gate-app-active --gate-window-present --gate-ax-present \
--postcondition-attribute AXValue --postcondition-attribute-value "lofi" \
--postcondition-timeout-ms 2000 --allow-keyboard-fallback- Use selector-frame screenshots for visual proof of target alignment:
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh run -- \
--format json observe screenshot --active-window \
--role AXButton --title-contains "Play" --selector-padding 12 \
--path "$AGENT_HOME/out/macos-agent-selector-$(date +%Y%m%d-%H%M%S).png"- Use diff-aware screenshots to avoid noisy artifacts when nothing changed:
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh run -- \
--format json observe screenshot --active-window \
--path "$AGENT_HOME/out/macos-agent-state.png" \
--if-changed --if-changed-threshold 2- Use one-shot debug bundle for triage artifacts:
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh run -- \
--format json debug bundle --active-window \
--output-dir "$AGENT_HOME/out/macos-agent-debug-$(date +%Y%m%d-%H%M%S)"- Run routine scripted scenarios:
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh scenario --file /path/to/scenario.json- Pass through raw macos-agent commands with JSON errors + trace when needed:
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh run -- \
--format json --error-format json --trace \
input click --x 200 --y 160- During runtime failure triage, the agent SHOULD capture an active-window screenshot before retry/remediation.
- For
wait app-activeandwindow.activatefailures, screenshot capture SHOULD be first-line diagnostics. - Screenshot artifacts MUST be written under
$AGENT_HOME/out/and SHOULD use timestamped filenames. - The agent SHOULD include screenshot path + failing command + error message in the final diagnostic summary.
Recommended command (via the skill entrypoint):
$AGENT_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh run -- \
--format json observe screenshot --active-window \
--path "$AGENT_HOME/out/macos-agent-failure-$(date +%Y%m%d-%H%M%S).png"-
error: input source mismatch after switch attempt ...- Run
.../macos-agent-ops.sh input-source --id abcand verifycurrentiscom.apple.keylayout.ABCor...US. - Ensure
im-selectis installed:brew install im-select. - If you intentionally need non-ABC IME, set
MACOS_AGENT_OPS_SKIP_INPUT_SOURCE_SWITCH=1.
- Run
-
error: timed out waiting for app-active ...- Keep hands off keyboard/mouse while checks are running.
- Close Control Center/Spotlight overlays and reduce notification interruptions.
- Increase timeout (
--timeout-ms 12000or higher) for slow app transitions.
-
error: ax.list ... timed outduringwait ax-present/wait ax-unique- Run
app-checkfirst, then retry AX waits after app focus is stable. - Increase AX wait timeout/poll (
--timeout-ms,--poll-ms) and narrow selectors. - Keep backend on
autounless you need to force Hammerspoon behavior (CODEX_MACOS_AGENT_AX_BACKEND).
- Run
-
window activate failed ...- Wrapper already uses
--reopen-on-fail; rerun once to allow quit/relaunch recovery. - For flaky apps (e.g., Spotify updater), kill stale relauncher and retry.
- Wrapper already uses
-
not authorized/ Apple Events failures- Re-run
doctorand fix Accessibility/Automation in System Settings.
- Re-run
-
selector returned zero AX matchesor ambiguous matches- Narrow selectors and use
--match-strategy exact|prefix|suffix|regexwhencontainsis too broad. - Use
--selector-explainandwait ax-uniquebeforeax click/ax type. - Prefer
--reselect-before-clickin dynamic pages where node ids churn.
- Narrow selectors and use
-
gate failure (
--gate-*) before mutation- Add/adjust readiness gates based on context (
--gate-app-active,--gate-window-present,--gate-ax-present,--gate-ax-unique). - Increase gate timeout/poll for slower app transitions (
--gate-timeout-ms,--gate-poll-ms).
- Add/adjust readiness gates based on context (
-
postcondition failure (
--postcondition-*) after mutation- Verify you are asserting the correct target/attribute (
AXValue, focus state, etc.). - Increase postcondition timeout on animation-heavy apps (
--postcondition-timeout-ms).
- Verify you are asserting the correct target/attribute (
-
error: --if-changed-baseline path does not exist ...- Verify baseline path exists before running capture.
- If baseline is optional, remove
--if-changed-baselineand let current output file be baseline.
-
trace directory is not writable (
trace.writeerrors)- Use a writable custom path with
--trace-dir. - Prefer
$AGENT_HOME/out/...for reproducible artifacts.
- Use a writable custom path with
-
Homebrew macos-agent missing
- Install and link with Homebrew:
brew install macos-agent.
- Install and link with Homebrew:
- Prefer canonical flags in examples:
--window-title-contains(instead of legacy--window-name)input type --submit(instead of legacy--enter)
- Keep
--error-format jsonenabled in automation loops when you need machine-parseable failures. - Use
debug bundlefirst when a run fails and root cause is unclear. - Parse preflight JSON permissions (
screen_recording/accessibility/automation/ready) before mutating runs.
skills/tools/macos-agent-ops/references/e2e-ref-01-preflight-focus.mdskills/tools/macos-agent-ops/references/e2e-ref-02-finder-routine.mdskills/tools/macos-agent-ops/references/e2e-ref-03-matrix-routine.md