macos-agent ops
Contract
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:
$AGENTS_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
$AGENTS_HOME/out/(screenshots, traces, debug bundles, step ledgers).
Exit codes:
- •
0: success - •
1: runtime failure or missing runtime dependency - •
2: 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.
Scripts (only entrypoints)
- •
$AGENTS_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh
Workflow
- •Resolve Homebrew
macos-agentbinary path:
bash
$AGENTS_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh where
- •Ensure deterministic input source (default target:
abc):
bash
$AGENTS_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh input-source # or explicit source id $AGENTS_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):
bash
$AGENTS_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh doctor # optional target for AX smoke $AGENTS_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh doctor --ax-app Arc $AGENTS_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):
bash
$AGENTS_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:
bash
$AGENTS_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh app-check --app Finder $AGENTS_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh app-check --app Arc --timeout-ms 15000 $AGENTS_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):
bash
$AGENTS_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh ax-check --app Arc --role AXWindow $AGENTS_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:
bash
$AGENTS_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 $AGENTS_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:
bash
$AGENTS_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
bash
$AGENTS_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:
bash
$AGENTS_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 "$AGENTS_HOME/out/macos-agent-selector-$(date +%Y%m%d-%H%M%S).png"
- •Use diff-aware screenshots to avoid noisy artifacts when nothing changed:
bash
$AGENTS_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh run -- \ --format json observe screenshot --active-window \ --path "$AGENTS_HOME/out/macos-agent-state.png" \ --if-changed --if-changed-threshold 2
- •Use one-shot debug bundle for triage artifacts:
bash
$AGENTS_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh run -- \ --format json debug bundle --active-window \ --output-dir "$AGENTS_HOME/out/macos-agent-debug-$(date +%Y%m%d-%H%M%S)"
- •Run routine scripted scenarios:
bash
$AGENTS_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:
bash
$AGENTS_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh run -- \ --format json --error-format json --trace \ input click --x 200 --y 160
Screenshot-Based Triage Rules
- •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
$AGENTS_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):
bash
$AGENTS_HOME/skills/tools/macos-agent-ops/scripts/macos-agent-ops.sh run -- \ --format json observe screenshot --active-window \ --path "$AGENTS_HOME/out/macos-agent-failure-$(date +%Y%m%d-%H%M%S).png"
Common Errors And Prevention
- •
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
$AGENTS_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:
Practical Notes
- •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.
References
- •
skills/tools/macos-agent-ops/references/e2e-ref-01-preflight-focus.md - •
skills/tools/macos-agent-ops/references/e2e-ref-02-finder-routine.md - •
skills/tools/macos-agent-ops/references/e2e-ref-03-matrix-routine.md