zfinix/aster/macos-harness
- community
Checking that the SKILL.md file is still in the repository.
Control a whole Mac from one persistent Python session with screenshots, PID-targeted input, an animated virtual pointer, targeted Apple Accessibility, Apple Events, Browser Harness CDP, and filesystem access. Use for native, Electron, browser, dialog, file, or cross-app tasks without moving the physical cursor or forcing apps into the foreground.
Install
npx vskill@latest install zfinix/aster/macos-harnessSKILL.md
macOS Harness
Setup
The skill ships with aster; the CLI it drives does not. Install it once with uv tool install macos-harness, then run macos-harness doctor to check permissions without prompting (--request only with user approval).
Surface
The CLI entry points are doctor, apps, see <app>, state <app>, repl, skill, telemetry. The real harness is the Python session: stdin programs preload mac, browser, Path, and subprocess.
Verified bindings (checked against the installed CLI):
mac.see(app)-> dict withpath(screenshot file),app,bounds,
focus.target_is_frontmost. Captures without focusing the app.
mac.key/mac.type/mac.click/mac.drag/mac.scroll/
mac.move: PID-targeted input; the physical cursor stays untouched.
mac.axis an object:.dump(app)(dict:app,nodes,text,
windows, screenshot), .query, .get, .set, .perform, .actions, .at.
mac.script(applescript)for Apple Events;mac.windows(app),
mac.list_apps(), mac.snapshot(), mac.get_app_state(app) for discovery and state.
browser.connect(name)/browser.wait(name)for CDP into the user's
real logged-in browser. Chrome shows an Allow remote debugging? sheet on first connect; approve it once there.
- Plain
Pathandsubprocessfor everything else.
Minimize round trips
- Bundle deterministic, reversible steps into one program, then verify once.
Opening search, typing a query, and capturing the results is one burst, not three calls.
- Stop at a genuine decision boundary: ambiguous identity, new coordinates,
an irreversible action, or unexpected state. Inspect once, then run the next burst.
- Do not screenshot merely to confirm that a known shortcut opened a text
field before typing. Let the final screenshot verify the whole sequence.
- Poll exact AX or Apple Events state inside the same Python program when
possible; do not make the model repeatedly ask whether a transition finished.
- Use the cheapest strong end-state check: one screenshot for visible state
or one exact API/AX query for semantic state; both only when they prove different things.
Use the small surface
Think in six verbs: see, key, type, click, ax, script.
Use ordinary Python for local context and one-off logic. Do not add app-specific helpers when a short program can resolve the task.
Choose the lowest useful mode
- When identity depends on local context (
my,friend, or prior
activity), inspect that context and correlate stable fields; a loose text hit is not enough.
- Use
mac.script()for a known exact, focus-safe app command. - Otherwise use
mac.see(app)and vision. - Prefer a known keyboard route; use a verified coordinate for a visible,
low-risk target.
- Use targeted
mac.axonly when semantic identity or state matters. Do
not dump a full AX tree before trying the direct route.
After a failed verified burst, switch mode or stop. Never repair uncertainty with repeated keys, clicks, deletion loops, or bulk input.
Keep the invariants
- Input targets an already-running app PID and never requests activation or
raise.
- A background target becoming frontmost raises
FocusChangedError; never
manipulate focus to restore it.
mac.click()is raw PID-targeted input. It never guesses an AX action.- The animated pointer is click-through and never moves the physical cursor.
mac.move()moves only that pointer; it cannot produce native hover.- Inactive apps may reject raw clicks. After one verified failure, switch
mode.
- Never launch a closed app or use a custom URL scheme when focus is
forbidden.
- Screenshot coordinates come from the latest
mac.see()and preserve
window bounds and Retina scaling.
Secondary primitives are mac.move, drag, scroll, show_pointer, and hide_pointer. mac.ax.query() returns compact matches and bounds fallback traversal; lower max_nodes for especially large apps.
Browser and permissions
Use browser for DOM, tabs, network, downloads, and uploads. Do not substitute AX for CDP inside a web page. While Browser Harness connects, macOS Harness accepts Chrome's exact Allow remote debugging? sheet through system-wide AX. It never activates Chrome or emits a mouse event.
Run macos-harness doctor to inspect permissions without prompting. Run macos-harness doctor --request only with user approval. Accessibility, screen recording, and event posting are global; Apple Events Automation is per target.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingcrates/aster-skills/optional-skills/macos-harness/SKILL.md
Popularity
- 7-day trend score
- 5
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/zfinix/aster/macos-harness)