AGENT SKILL

app_open_clean

Open a macOS app AND dismiss any blocking welcome / "What's New" / setup-prompt sheet that appeared on launch. Returns the app name and whether a modal was dismissed. Use this INSTEAD of `shell open -a X` when first opening an app you haven't driven before — saves the agent from the common failure mode of typing into a welcome modal instead of the actual UI. Looks for these dismiss buttons in priority order across any sheet or window of the frontmost app: Continue · Get Started · Skip · Later · Not Now · Got It · Maybe Later · Done · Cancel Generic — works for first-launch Apple apps (Reminders, Mail, Calendar, Photos, Maps, Music) and third-party apps that follow the same modal pattern.

License 许可
Apache-2.0
所属仓库
LocalKinAI/kinclaw
最近更新
2026-11-01
Stars
★ 9
Forks
3

01 前言 Front Matter

args
[ "{{app}}" ]
name
app_open_clean
schema
{ "app": { "type": "string", "required": true, "description": "App name (e.g. \"Reminders\", \"Mail\", \"Calendar\") or bundle ID. Whatever `open -a` accepts." } }
command
[ "sh", "-c", "APP=\"$1\"\n[ -z \"$APP\" ] && { echo \"app name required\" >&2; exit 1; }\n\nopen -a \"$APP\"\n# Most welcome sheets appear within 1.5s of launch. Sleep more on\n# slow boots — better to be late than to dismiss-before-render.\nsleep 1.5\n\n# Walk the frontmost app's sheets + windows; click the first\n# matching dismiss button by priority. Errors silenced — if the\n# app has no modal, we just exit with no-op success.\nDISMISSED=$(osascript 2>/dev/null <<'APPLESCRIPT'\nset dismissBtns to {\"Continue\", \"Get Started\", \"Skip\", \"Later\", \"Not Now\", \"Got It\", \"Maybe Later\", \"Done\", \"Cancel\"}\nset didClick to \"\"\ntell application \"System Events\"\n try\n set frontProc to first application process whose frontmost is true\n tell frontProc\n repeat with w in windows\n -- Sheets (attached modal dialogs)\n try\n repeat with s in sheets of w\n repeat with btnName in dismissBtns\n if exists (button btnName of s) then\n click button btnName of s\n set didClick to btnName as string\n exit repeat\n end if\n end repeat\n if didClick is not \"\" then exit repeat\n end repeat\n end try\n if didClick is not \"\" then exit repeat\n -- Standalone window that looks like welcome (has Continue/Get Started)\n try\n repeat with btnName in {\"Continue\", \"Get Started\", \"Got It\"}\n if exists (button btnName of w) then\n click button btnName of w\n set didClick to btnName as string\n exit repeat\n end if\n end repeat\n end try\n if didClick is not \"\" then exit repeat\n end repeat\n end tell\n end try\nend tell\nreturn didClick\nAPPLESCRIPT\n)\n\n# Some welcome flows are multi-step. Run a second pass to catch\n# the next sheet (e.g. Reminders has \"What's New\" → may auto-open\n# iCloud sync prompt). Quick second pass, no sleep needed.\nif [ -n \"$DISMISSED\" ]; then\n sleep 0.4\n DISMISSED2=$(osascript 2>/dev/null <<'APPLESCRIPT'\nset dismissBtns to {\"Continue\", \"Get Started\", \"Skip\", \"Later\", \"Not Now\", \"Got It\", \"Maybe Later\", \"Done\", \"Cancel\"}\nset didClick to \"\"\ntell application \"System Events\"\n try\n set frontProc to first application process whose frontmost is true\n tell frontProc\n repeat with w in windows\n try\n repeat with s in sheets of w\n repeat with btnName in dismissBtns\n if exists (button btnName of s) then\n click button btnName of s\n set didClick to btnName as string\n exit repeat\n end if\n end repeat\n if didClick is not \"\" then exit repeat\n end repeat\n end try\n if didClick is not \"\" then exit repeat\n end repeat\n end tell\n end try\nend tell\nreturn didClick\nAPPLESCRIPT\n)\nfi\n\nif [ -n \"$DISMISSED\" ]; then\n printf 'opened: %s\\ndismissed: %s' \"$APP\" \"$DISMISSED\"\n [ -n \"$DISMISSED2\" ] && printf ' → %s' \"$DISMISSED2\"\n printf '\\n'\nelse\n printf 'opened: %s\\ndismissed: (no modal found)\\n' \"$APP\"\nfi\n", "_" ]
timeout
15
description
Open a macOS app AND dismiss any blocking welcome / "What's New" / setup-prompt sheet that appeared on launch. Returns the app name and whether a modal was dismissed. Use this INSTEAD of `shell open -a X` when first opening an app you haven't driven before — saves the agent from the common failure mode of typing into a welcome modal instead of the actual UI. Looks for these dismiss buttons in priority order across any sheet or window of the frontmost app: Continue · Get Started · Skip · Later · Not Now · Got It · Maybe Later · Done · Cancel Generic — works for first-launch Apple apps (Reminders, Mail, Calendar, Photos, Maps, Music) and third-party apps that follow the same modal pattern.

03 SKILL.md 正文

app_open_clean — open + dismiss welcome modal

A common failure pattern when an LLM agent first drives a Mac app: launch the app → start typing or clicking → realize too late that a "What's New" or "Welcome" sheet was sitting on top of the real UI the whole time. The keystrokes go nowhere or hit the wrong target. The app looks unresponsive but is actually working fine; the modal is invisible to the AX-walk because it's a separate sheet.

This skill handles both phases in a single tool call:

  1. open -a <app> — launches via Launch Services
  2. osascript walks the frontmost process's windows + sheets, clicks the highest-priority dismiss button it finds, repeats once for stacked welcome flows.

If the app has no modal (already dismissed, or never had one), the script exits clean and reports "no modal found" — completely safe to call on already-open apps.

When to use

  • You're driving a built-in macOS app you haven't touched in this session: Reminders, Mail, Calendar, Photos, Maps, Music, etc.
  • You just upgraded macOS — every app's "What's New" fires once.
  • A third-party app you've never opened on this machine (Bear, Slack, Notion, etc.).

When NOT to use

  • App is already running and you've already used it — shell open -a is enough, no modal will appear.
  • The "modal" you want to keep — e.g. you opened Mail to use the Add Account flow on purpose. (Use shell open -a Mail directly then.)

Examples

app_open_clean app=Reminders
  → opened: Reminders
    dismissed: Continue → Got It

app_open_clean app=Calculator
  → opened: Calculator
    dismissed: (no modal found)

Why a SKILL.md and not native

Pure shell + osascript. No Go state, no AX walking via kinax that this skill doesn't already get from the standard ui tool. Sticks to the "thin kernel + fat skill" thesis — apps come and go, modal shapes evolve, this is exactly what forge should be writing.

Override / extend

If your installed app has a different dismiss button label not in the priority list (e.g. "Begin", "OK, got it", "下一步"), edit this SKILL.md and add it to dismissBtns. Or forge a sibling skill named after the specific app.

04 同仓库更多 Skills

LocalKinAI
LocalKinAI/kinclaw

web

Universal web tool — fetches and interacts with web pages through real Chromium (Playwright). Renders JavaScript, follows redirects, handles cookies, bypasses many anti-scrape stubs that block plain `web_fetch`. Each call launches a fresh browser, executes the requested flow, closes. ~2-3s cold start; no persistent state. Use INSTEAD of `web_fetch` when: - Target is a JS-heavy SPA (prices via XHR, lazy content) - `web_fetch` returned an anti-scrape placeholder (Zhihu's "click here" stub, JD's chrome-only HTML) - You need to interact (click, fill input) before extracting Common patterns: fetch rendered text: url=X wait for content then read: url=X wait_for=".price" extract specific element: url=X selector=".product-list" click and read result: url=X click=".search-button" fill form, then read: url=X click="input[name=q]" type_text="kinclaw" fill + Enter (React forms): url=X click="input" type_text="hi" press_enter=true wait_for=".reply" screenshot the page: url=X screenshot=true (returns image:// marker) run JS and get result: url=X js="document.title" First-time setup (one-time per machine, ~500MB Chromium download): pip install playwright playwright install chromium

文档处理测试与质量
★ 9
LocalKinAI
LocalKinAI/kinclaw

weather

Current conditions plus a three-day forecast (today / tomorrow / day after) for a place, in metric, from wttr.in. No API key. Use this for any weather question — including "明天" and "后天" — before reaching for web search.

★ 9
LocalKinAI
LocalKinAI/kinclaw

tts

Synthesize speech from text and play it through the macOS speakers. Talks to a local LocalKin Service Audio Server (default :8001 / Kokoro). When `record` is running with audio=true, the spoken audio is captured into the recording — use this in place of `shell say` for high-quality multilingual narration in demo videos. Set the TTS_ENDPOINT env var to point at a different server.

图像与多媒体Skill与智能体开发
★ 9
LocalKinAI
LocalKinAI/kinclaw

translate

Translate text between languages using the system's translate command

★ 9
LocalKinAI
LocalKinAI/kinclaw

summarize

Summarize a file's contents into key bullet points

资料检索与研究
★ 9
LocalKinAI
LocalKinAI/kinclaw

stt

Transcribe an audio file (wav/mp3/mp4/m4a) into text via a local LocalKin Service Audio Server (default :8000 / SenseVoice). Pair with `record action=start mic=true` to turn a recorded mic track into text. Set STT_ENDPOINT env var to point at a different server.

图像与多媒体
★ 9