Skip to content
Automation
Skill

/ha-mac-control

Hope Agent native macOS desktop control — the standard `mac_control` status / diagnostics / apps / dock / spaces / snapshot / visual / windows / menu / clipboard / dialog loop, target-first action rules, no-blind-coordinate policy, and recovery for stale AX/window/menu/dialog

From plugin
hope-agent
1.6k30 skills
Install
$ npx -y skills add shiwenwen/hope-agent --skill ha-mac-control --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/ha-mac-control

Context preview

The summary Claude sees to decide when to auto-load this skill.

Hope Agent native macOS desktop control — the standard `mac_control` status / diagnostics / apps / dock / spaces / snapshot / visual / windows / menu / clipboard / dialog loop, target-first action rules, no-blind-coordinate policy, and recovery for stale AX/window/menu/dialog

SKILL.md

ha-mac-control.SKILL.md
name: ha-mac-control
description: "Hope Agent native macOS desktop control — the standard `mac_control` status / diagnostics / apps / dock / spaces / snapshot / visual / windows / menu / clipboard / dialog loop, target-first action rules, no-blind-coordinate policy, and recovery for stale AX/window/menu/dialog state. Load whenever using `mac_control`, or when the user asks to control local Mac apps, Dock, Spaces, click/type/menu/window/dialog/clipboard, automate Finder/TextEdit/System Settings, visually locate UI, or says 控制 Mac, macOS 自动化, 点按钮, 打开应用, Dock, Space, 关闭窗口, 菜单点击, 视觉定位."
version: 1.0.0
author: Hope Agent
license: MIT
allowed-tools: [mac_control, ask_user_question]
status: active

Hope Agent Mac Control

`mac_control` operates the user's macOS desktop from the authorized Hope Agent app process. macOS UI state is volatile: apps steal focus, AX IDs expire, sheets attach to windows, and multiple windows often share similar titles. Use a fresh observation before every meaningful action.

Standard Loop

Use this loop unless the user explicitly asks for a single read-only query:

1. mac_control(action="status")
2. mac_control(action="apps", op="frontmost" | "search" | "installed")
3. observe: snapshot / visual.observe / elements.find / windows.list / dock.list / spaces.list / menu.list / menu.popover / dialog.inspect
4. act: apps.activate/launch, dock.launch, spaces.switch, windows.*, act.*, menu.click, dialog.*
5. verify: wait, snapshot, windows.list, or dialog.inspect

For a concrete app workflow:

apps.launch bundleId=...
apps.frontmost                         # verify focus if the next step depends on menus/input
snapshot, elements.find, or windows.list # get fresh window/element ids
act/menu/windows/clipboard/dialog      # one action burst
wait or snapshot                       # verify the expected change

Targeting Rules

  • Prefer `bundleId` over `appName` for mutations. Use `apps.search` / `apps.installed` when the app name is uncertain, then retry with `bundleId`.
  • `appNameMatch` defaults to `exact`. Use `contains` only for read-only discovery or when the user clearly gave a partial name.
  • Prefer `windowId` from the latest `windows.list` or `snapshot` for window mutations.
  • `target.windowTitleMatch` defaults to `exact`. Use `contains` only after listing windows and confirming a partial title is intentional.
  • Prefer `elementId` from the latest `snapshot` / `visual.observe` / `elements.find` for precise clicks and set-value actions, and pass the matching `target.snapshotId` with it. `snapshotId + elementId` lets the runtime verify the original AX fingerprint and re-resolve stale `el_N` ids instead of blindly trusting a new traversal.
  • Use `elements.find` when a full snapshot is too noisy or when an action target is ambiguous. It is read-only and returns scored candidates with reasons; retry mutations with `target.elementId` from the chosen candidate plus the result `snapshotId`.
  • If two windows, dialogs, text fields, or buttons match, do not guess. Use a more specific target or ask the user.
  • Element mutations reject equally ranked AX candidates instead of choosing the first match. When this happens, take a fresh `snapshot` and retry with `elementId`, `target.windowTitle`, `target.role`, or more specific `target.text`.

Actions

Apps

  • Use `apps.frontmost` to know what macOS will receive menu and keyboard actions.
  • Use `apps.activate bundleId=...` before operating an app that is not frontmost.
  • Use `apps.search` or `apps.installed` when launch/activate by name fails.
  • `apps.quit` is destructive. Verify the target app and prefer `bundleId`.

Dock and Spaces

  • Use `dock.list` before `dock.launch`; prefer `dockItemId` or `bundleId` over a loose app name.
  • Use `dock.menu` to open a Dock item's context menu and inspect `menuItems`; use `dock.select_menu` with `menuItem` when possible, or `menuIndex` only when titles are unavailable. If both are present, `menuItem` is treated as the intended target.
  • `dock.hide` and `dock.show` change the user's Dock autohide setting and restart Dock, so be explicit before approval.
  • Use `spaces.list` before `spaces.switch` when targeting a numbered Space. `spaceIndex` is 1-based.
  • `spaces.switch direction="left"|"right"` / `spaceIndex` / `spaceId` pass exactly one selector. Direction and adjacent targets use Mission Control Control+Left/Right first; non-adjacent exact targets may fall back to Control+number or SkyLight/CGS. Verify with `spaces.list` or a fresh screenshot after switching.
  • `spaces.move_window` moves one explicit window to `spaceIndex` / `spaceId` through SkyLight/CGS. Resolve the window first with `windows.list windowScope="all"` and prefer `windowId`; if post-move verification warns, use `spaces.list` or a fresh screenshot to confirm.

Windows

  • Use `windows.list` before `windows.close`, `move`, `resize`, or `minimize` unless the user supplied an exact `windowId`.
  • `windowScope` defaults to `frontmost`. Use `windows.list windowScope="all"` to discover background app windows before activating or focusing them.
  • Prefer all-scope ids like `win_<pid>_<index>` for cross-app window mutations; they are safer than generic titles.
  • For `windows.close`, avoid generic titles like `Untitled` / `未命名` when multiple similar windows exist. Use `windowId`.
  • Hope Agent's own window cannot be mutated through the Accessibility worker; if the target is Hope Agent itself, explain the limitation.

Screenshots

  • Use `snapshot includeScreenshot=true` when visual context matters.
  • Default screenshots capture the primary display. Use `displayId` from `snapshot.displays` when the user points at a specific monitor.
  • For a focused-window image, use `snapshot includeScreenshot=true screenshotTarget="window"`. Pass `windowId` from the latest snapshot/list when several windows are possible.
  • Window screenshot matching uses the current AX window state; if it fails, take a fresh snapshot a
Read more
Ships withhope-agent

🦭 会记忆、能持续推进目标、会动态编排多 Agent 的跨端桌面 AI 助手,也可服务化常驻 NAS / 云端 | A cross-device desktop AI agent with memory, autonomous goals, dynamic workflows, and headless deployment

Get the whole plugin
Stats
1,603
Stars
153
Forks
Active
Maintenance
Rust
Language
MIT
License
2d ago
Last commit
6mo ago
Created

Repo: shiwenwen/hope-agent

Other skills on hope-agent.