⏳ This skill is pending AI review.
Scores will appear once the review pipeline completes.
chrome-mac-agent-skill
Controls and inspects currently active Google Chrome tabs on macOS via native AppleScript without restarting Chrome, launching separate browser profiles, or losing active user logins and cookies. Use when an AI Agent needs to interact with the user's live browser sessions.
Choose how to use this skill
You do not need every option. Choose the path your AI client supports. The stable page stays the same; versioned files are immutable.
1. Native installer
This listing has no registered native installer command. Use the complete package or source fallback below, depending on what your client supports.
Do not guess an installer command or replace an existing version without reviewing the diff.
2. Complete package recommended
Download the ZIP when available. It includes SKILL.md plus the references, security notes and version metadata.
No complete ProSkills package is published for this listing yet.3. Prompt-only
Copy the prompt above when the agent can read the stable page or when you want to adopt the workflow without installing a skill.
Need only the instruction file?
Download SKILL.md only if your client requires a single file. The complete ZIP is safer for a full installation because it preserves the references and release context.
No path installs or executes anything by itself. Your agent still needs access to the project files. Before updating, compare the installed version and review the diff.
// RATINGS
Not yet listed on ClawHub or SkillsMP
// README
_____ __ _ ________
/ _ \____/ |_(_)_ _____ __\______ \_______ ____ _____ ____
/ /_\ \_ __ __\ |\__ \/ || | \_ __ \/ _ \/ \_/ __ \
/ | \ | | | | | / __ \_ | ` \ | \( <_> ) Y Y \ ___/
\____|__ /__| |__|__|_|(____ / /_______ /__| \____/|__|_| /\___ >
\/ \/ \/ \/ \/
chrome-mac-agent-skill
Agent-Native Skill to control active Google Chrome tabs on macOS without restarting or losing user logins.
⚡ The Problem
When AI coding assistants and autonomous agents (like Claude Code, Cursor, Windsurf, or custom LLM frameworks) need to interact with web pages, they typically rely on Playwright, Puppeteer, or isolated browser wrappers.
This introduces severe workflow friction:
- Lost User Logins: They launch a blank, isolated browser session with no cookies. Every protected page requires re-logging in, solving 2FA, or scanning QR codes.
- Forced Process Killing: Attaching to a running Chrome normally forces you to close all your open windows and restart Chrome with
--remote-debugging-port=9222. - Heavy Dependency Footprint: Multi-gigabyte browser installations and complex driver setups just to check a web page.
💡 The Solution: chrome-mac-agent-skill
This skill connects your AI Agent directly to your currently open Google Chrome windows on macOS via native AppleScript:
- 🚀 Zero Restarts: Never close your current work tabs.
- 🔑 Preserves All Active Sessions: Keeps your Google accounts, enterprise SSO portals, GitHub, and social logins intact.
- 🪶 Zero External Dependencies: Pure Markdown instruction set leveraging macOS built-in
osascript. Nonpm install, nopip install. - 🛡 Native Sheet & Dialog Handling: Built-in recipes to bypass
beforeunloadblockers and automatically dismiss native macOS dialogs. - ⚡ Deep SPA & Complex Rich-Text Support: Built-in recipes for virtual list incremental scrolling, client-side route sync, Draft.js/Lexical rich-text state handling, and AppleScript defensive IIFE serialization.
- 📦 Modular Progressive Disclosure: Split into scenario-specific reference files to conserve AI context tokens.
📊 Feature Comparison
| Capability | Playwright / Puppeteer | Remote Debugging (CDP) | OS "Computer Use" (Vision + Mouse) | chrome-mac-agent-skill 🚀 |
|---|---|---|---|---|
| Keeps Active Logins & Cookies | ❌ No (Isolated) | ⚠️ Only if started with flag | ✅ Yes (Shares screen) | ✅ Yes (100% Live) |
| Silent Background Execution | ⚠️ Headless only | ⚠️ If port opened | ❌ No (Steals mouse & focus) | ✅ Yes (Zero mouse hijack) |
| Action Speed | ~1 - 3s | ~500ms | ❌ Slow (5 - 10s per click) | ⚡ Blazing Fast (<50ms) |
| Token & Cost Footprint | Low (HTML) | Low (HTML) | ❌ High (Thousands of Vision Tokens) | 💎 Optimal (Zero Image Tokens) |
| System Permissions Required | None | None | ❌ High (Screen Recording & Accessibility) | 🔒 Minimal (Chrome Menu Toggle Only) |
| Precision | High | High | ⚠️ Prone to Retina coordinate drift | 🎯 100% Deterministic (DOM Level) |
| Requires Browser Restart | ❌ Yes | ❌ Yes (Must restart Chrome) | ✅ No | ✅ No (Instant Attach) |
🥊 Why not OS-level "Computer Use" (Screenshots + Mouse Clicks)?
While modern multimodal models (like Claude 3.5 / 3.7 Computer Use) can physically see the screen and click coordinates, using "Computer Use" for routine browser automation is often like using a sledgehammer to crack a nut:
- Mouse Hijacking vs. True Background Silence:
- Computer Use: Forces Chrome to stay frontmost. The agent moves your physical cursor around the screen, rendering your computer unusable while the task is executing.
chrome-mac-agent-skill: 100% background silent. You can write code, watch videos, or minimize Chrome—the agent interacts behind the scenes without touching your mouse or stealing focus.
- Speed & Latency:
- Computer Use: Every single click requires: Capture Screenshot -> Upload Image -> Vision Model Reasoning -> Coordinate Math -> Move Cursor -> Click -> Wait -> Verify Screenshot (~5 to 10 seconds per step).
chrome-mac-agent-skill: Directly targets DOM nodes via native IPC in under 50 milliseconds.
- Token & Dollar Savings:
- Computer Use: Streams full-resolution 2K/4K screenshots every turn, consuming thousands of vision tokens per interaction.
chrome-mac-agent-skill: Zero visual token overhead. Executes pure, surgical JavaScript expressions.
- Least-Privilege Security:
- Computer Use: Demands high-risk macOS system permissions (Screen Recording to see everything on your display and Accessibility to control global input).
chrome-mac-agent-skill: Never needs macOS Screen Recording permissions. Operates strictly inside Google Chrome via native Apple Events.
🚀 How to Add to Your AI Agent
Option 1: Drop-in Folder (Antigravity, Cursor, Windsurf)
Clone or copy this repository into your project's .agents/skills/ or .skills/ directory:
mkdir -p .agents/skills
git clone https://github.com/aicode915/chrome-mac-agent-skill.git .agents/skills/active-chrome-control
Option 2: Claude Code
Copy SKILL.md and the references/ directory into your project's .claude/skills/chrome-mac-agent-skill/.
🧭 Repository Structure
chrome-mac-agent-skill/
├── SKILL.md # Entrypoint: Quick cheatsheet, prerequisites, and on-demand router
├── README.md # Human documentation (English)
├── README_CN.md # Human documentation (Chinese)
├── LICENSE # MIT License
└── references/ # Focused scenario playbooks (loaded by Agent on demand)
├── tab-management.md # Tab querying, filtering, switching, creating, and closing
├── page-interaction.md # Body text extraction, JS execution, reactive form inputs, Shadow DOM
├── dialog-handling.md # Dismissing native macOS sheets and stripping beforeunload blockers
└── background-alive.md # Tab focus-loss spoofing, anti-pause hooks, and video inspection
🛠 Manual CLI Quickstart
You can test these commands directly in your macOS terminal:
List All Active Chrome Tabs:
osascript -e 'tell application "Google Chrome" to repeat with w in windows
repeat with t in tabs of w
log (id of t as text) & " | " & title of t & " | " & URL of t
end repeat
end repeat'
Read Current Page Content:
osascript -e 'tell application "Google Chrome" to repeat with w in windows
repeat with t in tabs of w
if URL of t contains "github.com" then
return execute t javascript "document.body.innerText.substring(0, 1000)"
end if
end repeat
end repeat'
⚠️ Prerequisite (One-Time Setup)
To allow AppleScript to run JavaScript in Google Chrome:
- Open Google Chrome.
- In the macOS menu bar, navigate to: View (查看) -> Developer (开发者).
- Check Allow JavaScript from Apple Events (允许 Apple 事件中的 JavaScript).
📄 License
MIT © 2026 chrome-mac-agent-skill contributors.
// HOW IT'S BUILT
// FILES
10 files shipped with this skill. Inline text is the catalog copy. The upstream link is the source repository.
SKILL.md5.9 KB6a3b9238ece1upstream ↗
--- name: chrome-mac-agent-skill description: "Controls and inspects currently active Google Chrome tabs on macOS via native AppleScript without restarting Chrome, launching separate browser profiles, or losing active user logins and cookies. Use when an AI Agent needs to interact with the user's live browser sessions." --- # Chrome Mac Agent Skill Control and inspect the user's **currently active Google Chrome tabs on macOS** directly. Unlike Playwright or Puppeteer which spawn isolated, cookie-less browser instances, this skill communicates with the running Chrome process via native macOS AppleScript, **preserving all active logins, enterprise SSO sessions, cookies, and local state with zero restarts**. --- ## ⚡ Prerequisites & Self-Healing Google Chrome on macOS requires a one-time permission toggle: > **Chrome Menu Bar** -> **View (查看)** -> **Developer (开发者)** -> check **Allow JavaScript from Apple Events (允许 Apple 事件中的 JavaScript)**. ### Fast Permission Health Check Run this single command to verify access: ```bash osascript -e 'tell application "Google Chrome" to execute front window'\''s active tab javascript "1+1"' 2>&1 ``` * If it returns `2`, permissions are active. * If it returns an error mentioning `Allow JavaScript from Apple Events` (Error -1753 or code 12), guide the user: > *"Please enable 'Allow JavaScript from Apple Events' in Chrome: View > Developer > Allow JavaScript from Apple Events."* --- ## 🧭 Progressive Reference Routing (On-Demand Loading) To save context tokens, this skill is split into focused scenario modules. **Read the corresponding reference file only when your task requires it**: | Scenario | When to Read | Reference File | | :--- | :--- | :--- | | **Tab Management** | Need to find tabs, switch tabs, open new URLs, or close tabs | [`references/tab-management.md`](./references/tab-management.md) | | **DOM & Elements** | Need to extract page text/HTML, fill forms, or click buttons | [`references/page-interaction.md`](./references/page-interaction.md) | | **Dialogs & Alerts** | Dealing with "Leave site?" / "Reload site?" sheets or dialogs | [`references/dialog-handling.md`](./references/dialog-handling.md) | | **Background Keep-Alive** | Page pauses when switching tabs or monitors focus loss | [`references/background-alive.md`](./references/background-alive.md) | | **SPAs & Complex Web** | Virtual lists, Draft.js rich text, client-side routing, or AppleScript missing-value traps | [`references/spa-and-complex-web.md`](./references/spa-and-complex-web.md) | --- ## 🚀 Quick Execution Cheatsheet (High-Frequency One-Liners) ### 1. List Open Tabs (Titles, URLs & Tab IDs) ```bash osascript -e 'tell application "Google Chrome" set out to "" repeat with w in windows repeat with t in tabs of w set out to out & (id of t as text) & " | " & (title of t) & " | " & (URL of t) & linefeed end repeat end repeat return out end tell' ``` ### 2. Extract Visible Text from Matching Tab ```bash osascript -e 'tell application "Google Chrome" repeat with w in windows repeat with t in tabs of w if URL of t contains "TARGET_DOMAIN" then return execute t javascript "document.body.innerText.substring(0, 3000)" end if end repeat end repeat return "TAB_NOT_FOUND" end tell' ``` ### 3. Execute Arbitrary JavaScript on Matching Tab For complex multi-line JavaScript, always use **Heredoc (`<< 'EOF'`)** to eliminate string escaping bugs: ```bash osascript << 'EOF' tell application "Google Chrome" repeat with w in windows repeat with t in tabs of w if URL of t contains "TARGET_DOMAIN" then return execute t javascript "document.title + ' | ' + location.href" end if end repeat end repeat return "TAB_NOT_FOUND" end tell EOF ``` ### 4. Click Button/Link by Visible Text (Shadow DOM Penetrating) ```bash osascript << 'EOF' tell application "Google Chrome" repeat with w in windows repeat with t in tabs of w if URL of t contains "TARGET_DOMAIN" then return execute t javascript "(function() { function deepFind(root) { if (!root) return null; const els = root.querySelectorAll('button, a, input[type=\"button\"], input[type=\"submit\"], [role=\"button\"], label'); for (const el of els) { if (el.innerText && el.innerText.trim().includes('BUTTON_TEXT') && el.offsetParent !== null) return el; } for (const el of root.querySelectorAll('*')) { if (el.shadowRoot) { const found = deepFind(el.shadowRoot); if (found) return found; } } return null; } const target = deepFind(document); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'center' }); target.click(); return 'CLICKED'; } return 'NOT_FOUND'; })()" end if end repeat end repeat return "TAB_NOT_FOUND" end tell EOF ``` --- ## 🛡 Security & Best Practices 1. **Target by URL Substring or Title**: Avoid hardcoding window indexes; always query by `URL of t contains ...` or `title of t contains ...`. 2. **Prevent Navigation Blockers**: When reloading or leaving pages with active forms, proactively inject `window.onbeforeunload = null;` to prevent native browser blocking dialogs (see [`references/dialog-handling.md`](./references/dialog-handling.md)). 3. **No External Dependencies**: Never install pip/npm packages for browser automation if native AppleScript suffices. Keep workflows zero-config and lightweight.README.md8.0 KB6b8ff9e5a73aupstream ↗
<div align="center"> ``` _____ __ _ ________ / _ \____/ |_(_)_ _____ __\______ \_______ ____ _____ ____ / /_\ \_ __ __\ |\__ \/ || | \_ __ \/ _ \/ \_/ __ \ / | \ | | | | | / __ \_ | ` \ | \( <_> ) Y Y \ ___/ \____|__ /__| |__|__|_|(____ / /_______ /__| \____/|__|_| /\___ > \/ \/ \/ \/ \/ ``` # chrome-mac-agent-skill **Agent-Native Skill to control active Google Chrome tabs on macOS without restarting or losing user logins.** [](https://opensource.org/licenses/MIT) [](https://apple.com/macos) [](https://github.com/aicode915/chrome-mac-agent-skill) [](https://github.com/aicode915/chrome-mac-agent-skill) [English](./README.md) • [简体中文](./README_CN.md) </div> --- ## ⚡ The Problem When AI coding assistants and autonomous agents (like Claude Code, Cursor, Windsurf, or custom LLM frameworks) need to interact with web pages, they typically rely on **Playwright**, **Puppeteer**, or isolated browser wrappers. This introduces severe workflow friction: 1. **Lost User Logins**: They launch a blank, isolated browser session with no cookies. Every protected page requires re-logging in, solving 2FA, or scanning QR codes. 2. **Forced Process Killing**: Attaching to a running Chrome normally forces you to close all your open windows and restart Chrome with `--remote-debugging-port=9222`. 3. **Heavy Dependency Footprint**: Multi-gigabyte browser installations and complex driver setups just to check a web page. --- ## 💡 The Solution: `chrome-mac-agent-skill` This skill connects your AI Agent directly to your **currently open Google Chrome windows on macOS** via native AppleScript: - 🚀 **Zero Restarts**: Never close your current work tabs. - 🔑 **Preserves All Active Sessions**: Keeps your Google accounts, enterprise SSO portals, GitHub, and social logins intact. - 🪶 **Zero External Dependencies**: Pure Markdown instruction set leveraging macOS built-in `osascript`. No `npm install`, no `pip install`. - 🛡 **Native Sheet & Dialog Handling**: Built-in recipes to bypass `beforeunload` blockers and automatically dismiss native macOS dialogs. - ⚡ **Deep SPA & Complex Rich-Text Support**: Built-in recipes for virtual list incremental scrolling, client-side route sync, Draft.js/Lexical rich-text state handling, and AppleScript defensive IIFE serialization. - 📦 **Modular Progressive Disclosure**: Split into scenario-specific reference files to conserve AI context tokens. --- ## 📊 Feature Comparison | Capability | Playwright / Puppeteer | Remote Debugging (CDP) | OS "Computer Use" (Vision + Mouse) | `chrome-mac-agent-skill` 🚀 | | :--- | :---: | :---: | :---: | :---: | | **Keeps Active Logins & Cookies** | ❌ No (Isolated) | ⚠️ Only if started with flag | ✅ Yes (Shares screen) | **✅ Yes (100% Live)** | | **Silent Background Execution** | ⚠️ Headless only | ⚠️ If port opened | ❌ **No (Steals mouse & focus)** | **✅ Yes (Zero mouse hijack)** | | **Action Speed** | ~1 - 3s | ~500ms | ❌ **Slow (5 - 10s per click)** | **⚡ Blazing Fast (<50ms)** | | **Token & Cost Footprint** | Low (HTML) | Low (HTML) | ❌ **High (Thousands of Vision Tokens)** | **💎 Optimal (Zero Image Tokens)** | | **System Permissions Required** | None | None | ❌ **High (Screen Recording & Accessibility)** | **🔒 Minimal (Chrome Menu Toggle Only)** | | **Precision** | High | High | ⚠️ **Prone to Retina coordinate drift** | **🎯 100% Deterministic (DOM Level)** | | **Requires Browser Restart** | ❌ Yes | ❌ Yes (Must restart Chrome) | ✅ No | **✅ No (Instant Attach)** | --- ## 🥊 Why not OS-level "Computer Use" (Screenshots + Mouse Clicks)? While modern multimodal models (like Claude 3.5 / 3.7 Computer Use) can physically see the screen and click coordinates, using "Computer Use" for routine browser automation is often like using a sledgehammer to crack a nut: 1. **Mouse Hijacking vs. True Background Silence**: * *Computer Use*: Forces Chrome to stay frontmost. The agent moves your physical cursor around the screen, rendering your computer unusable while the task is executing. * *`chrome-mac-agent-skill`*: **100% background silent**. You can write code, watch videos, or minimize Chrome—the agent interacts behind the scenes without touching your mouse or stealing focus. 2. **Speed & Latency**: * *Computer Use*: Every single click requires: *Capture Screenshot -> Upload Image -> Vision Model Reasoning -> Coordinate Math -> Move Cursor -> Click -> Wait -> Verify Screenshot* (~5 to 10 seconds per step). * *`chrome-mac-agent-skill`*: Directly targets DOM nodes via native IPC in **under 50 milliseconds**. 3. **Token & Dollar Savings**: * *Computer Use*: Streams full-resolution 2K/4K screenshots every turn, consuming thousands of vision tokens per interaction. * *`chrome-mac-agent-skill`*: **Zero visual token overhead**. Executes pure, surgical JavaScript expressions. 4. **Least-Privilege Security**: * *Computer Use*: Demands high-risk macOS system permissions (**Screen Recording** to see everything on your display and **Accessibility** to control global input). * *`chrome-mac-agent-skill`*: **Never needs macOS Screen Recording permissions**. Operates strictly inside Google Chrome via native Apple Events. --- ## 🚀 How to Add to Your AI Agent ### Option 1: Drop-in Folder (Antigravity, Cursor, Windsurf) Clone or copy this repository into your project's `.agents/skills/` or `.skills/` directory: ```bash mkdir -p .agents/skills git clone https://github.com/aicode915/chrome-mac-agent-skill.git .agents/skills/active-chrome-control ``` ### Option 2: Claude Code Copy `SKILL.md` and the `references/` directory into your project's `.claude/skills/chrome-mac-agent-skill/`. --- ## 🧭 Repository Structure ```text chrome-mac-agent-skill/ ├── SKILL.md # Entrypoint: Quick cheatsheet, prerequisites, and on-demand router ├── README.md # Human documentation (English) ├── README_CN.md # Human documentation (Chinese) ├── LICENSE # MIT License └── references/ # Focused scenario playbooks (loaded by Agent on demand) ├── tab-management.md # Tab querying, filtering, switching, creating, and closing ├── page-interaction.md # Body text extraction, JS execution, reactive form inputs, Shadow DOM ├── dialog-handling.md # Dismissing native macOS sheets and stripping beforeunload blockers └── background-alive.md # Tab focus-loss spoofing, anti-pause hooks, and video inspection ``` --- ## 🛠 Manual CLI Quickstart You can test these commands directly in your macOS terminal: ### List All Active Chrome Tabs: ```bash osascript -e 'tell application "Google Chrome" to repeat with w in windows repeat with t in tabs of w log (id of t as text) & " | " & title of t & " | " & URL of t end repeat end repeat' ``` ### Read Current Page Content: ```bash osascript -e 'tell application "Google Chrome" to repeat with w in windows repeat with t in tabs of w if URL of t contains "github.com" then return execute t javascript "document.body.innerText.substring(0, 1000)" end if end repeat end repeat' ``` --- ## ⚠️ Prerequisite (One-Time Setup) To allow AppleScript to run JavaScript in Google Chrome: 1. Open Google Chrome. 2. In the macOS menu bar, navigate to: **View (查看)** -> **Developer (开发者)**. 3. Check **Allow JavaScript from Apple Events (允许 Apple 事件中的 JavaScript)**. --- ## 📄 License [MIT](./LICENSE) © 2026 chrome-mac-agent-skill contributors.references/background-alive.md4.0 KB5edf77a3d43eupstream ↗
# Reference: Background Keep-Alive & Anti-Pause Hooks Many web applications (such as corporate training portals, exam engines, or video dashboards) pause execution or flag automated tests when their browser tab loses active focus (`blur`) or when users switch tabs (`visibilitychange`). This reference provides techniques to keep active tabs running in the background and prevent pause events. --- ## 1. Universal Anti-Pause & Focus Freeze Hook Inject this payload into the target tab immediately after opening or navigation: ```bash osascript << 'EOF' tell application "Google Chrome" repeat with w in windows repeat with t in tabs of w if URL of t contains "TARGET_DOMAIN" then return execute t javascript "(function() { try { // 1. Block focus-loss and tab-switch events window.addEventListener('blur', function(e) { e.stopImmediatePropagation(); }, true); window.addEventListener('mouseleave', function(e) { e.stopImmediatePropagation(); }, true); document.addEventListener('visibilitychange', function(e) { e.stopImmediatePropagation(); }, true); // 2. Freeze visibility state to always active Object.defineProperty(document, 'hidden', { value: false, writable: false }); Object.defineProperty(document, 'visibilityState', { value: 'visible', writable: false }); return 'ANTI_PAUSE_HOOKS_ACTIVE'; } catch(err) { return 'ERROR: ' + err.message; } })()" end if end repeat end repeat return "TAB_NOT_FOUND" end tell EOF ``` --- ## 2. Inspect HTML5 Video Playback State Inspect video progress without needing to activate the tab: ```bash osascript << 'EOF' tell application "Google Chrome" repeat with w in windows repeat with t in tabs of w if URL of t contains "TARGET_DOMAIN" then return execute t javascript "(function() { const v = document.querySelector('video'); if (!v) return 'NO_VIDEO_FOUND'; return JSON.stringify({ paused: v.paused, currentTime: Math.floor(v.currentTime), duration: Math.floor(v.duration), progress: v.duration ? ((v.currentTime / v.duration) * 100).toFixed(1) + '%' : '0%' }); })()" end if end repeat end repeat return "TAB_NOT_FOUND" end tell EOF ``` --- ## 3. Human-like Sequential Actions with Jitter When interacting with platforms sensitive to automated batch operations, execute sequential steps with natural delays rather than synchronous loops: ```bash osascript << 'EOF' tell application "Google Chrome" repeat with w in windows repeat with t in tabs of w if URL of t contains "TARGET_DOMAIN" then return execute t javascript "(async function() { const items = Array.from(document.querySelectorAll('.clickable-option, .list-item')); for (let i = 0; i < Math.min(items.length, 5); i++) { const el = items[i]; el.scrollIntoView({ behavior: 'smooth', block: 'center' }); // Randomized human delay: 800ms - 2200ms const delay = Math.floor(Math.random() * 1400) + 800; await new Promise(r => setTimeout(r, delay)); el.dispatchEvent(new MouseEvent('mousedown', { bubbles: true })); el.dispatchEvent(new MouseEvent('mouseup', { bubbles: true })); el.click(); } return 'COMPLETED_NATURALLY'; })()" end if end repeat end repeat return "TAB_NOT_FOUND" end tell EOF ```references/dialog-handling.md3.5 KBd22fc1c457b5upstream ↗
# Reference: Native Dialog Handling & BeforeUnload Bypass This reference guides how to handle and prevent macOS system-level sheets and browser dialogs (e.g., *"Reload site? Changes you made may not be saved"* with `[Cancel]` and `[Reload]` buttons). --- ## 1. Why Native Dialogs Block Automation When a tab has active form fields, unsaved drafts, or dirty state (such as Twitter/X tweet compositing or form editors), reloading or navigating away triggers the browser's native `beforeunload` event. Because this alert is a **native macOS sheet** rather than an HTML DOM element, standard web queries (`document.querySelector`) cannot detect or interact with it. --- ## 2. Tier 1: Proactive Prevention (Recommended • 0 Permissions Required) The cleanest and most reliable strategy is to **strip beforeunload listeners before initiating reloads or navigation**: ```bash osascript << 'EOF' tell application "Google Chrome" repeat with w in windows repeat with t in tabs of w if URL of t contains "TARGET_DOMAIN" then execute t javascript "(function() { window.onbeforeunload = null; window.addEventListener('beforeunload', function(e) { e.stopImmediatePropagation(); delete e['returnValue']; }, true); })()" reload t return "RELOADED_WITHOUT_DIALOG" end if end repeat end repeat return "TAB_NOT_FOUND" end tell EOF ``` --- ## 3. Tier 2: Reactive Native Sheet Dismissal (macOS System Events) If a confirmation sheet has **already appeared on screen**, use macOS `System Events` to automatically click the confirm button: ```bash osascript << 'EOF' try tell application "System Events" tell process "Google Chrome" repeat with w in windows if exists (sheet 1 of w) then try -- Match Chinese ("重新加载" / "离开") and English ("Reload" / "Leave") click (first button of sheet 1 of w whose name is "重新加载" or name is "Reload" or name is "离开" or name is "Leave") return "DISMISSED_NATIVE_SHEET" on error -- Fallback: press Return (default highlighted action button) keystroke return return "DISMISSED_VIA_ENTER" end try end if end repeat return "NO_SHEET_DETECTED" end tell end tell on error errMsg return "ACCESSIBILITY_PERMISSION_NOTE: " & errMsg end try EOF ``` > [!NOTE] > If `System Events` outputs error `-25211` ("osascript is not allowed assistive access"), macOS Accessibility permission has not been granted to Terminal. Use **Tier 1 (Proactive Prevention)** instead, as it requires zero extra macOS system permissions. --- ## 4. One-Click Safe Reload Snippet Combine both strategies into a unified safe reload operation: ```bash osascript << 'EOF' tell application "Google Chrome" repeat with w in windows repeat with t in tabs of w if URL of t contains "TARGET_DOMAIN" then -- 1. Strip beforeunload handlers execute t javascript "window.onbeforeunload = null;" -- 2. Trigger reload reload t return "SAFE_RELOAD_SUCCESS" end if end repeat end repeat return "TAB_NOT_FOUND" end tell EOF ```references/page-interaction.md5.9 KB86a039251e20upstream ↗
# Reference: Page Interaction & DOM Manipulation This reference provides JavaScript payloads designed to be injected via AppleScript (`execute t javascript ...`) to reliably read page state, interact with elements, fill reactive forms, and traverse Shadow DOM trees. --- ## 1. Reading Page Content ### A. Extract Clean Visible Body Text (with length limit) ```bash osascript << 'EOF' tell application "Google Chrome" repeat with w in windows repeat with t in tabs of w if URL of t contains "TARGET_DOMAIN" then return execute t javascript "(function() { return document.body.innerText.substring(0, 4000); })()" end if end repeat end repeat return "TAB_NOT_FOUND" end tell EOF ``` ### B. Extract Structured Data or Links ```bash osascript << 'EOF' tell application "Google Chrome" repeat with w in windows repeat with t in tabs of w if URL of t contains "TARGET_DOMAIN" then return execute t javascript "(function() { const links = Array.from(document.querySelectorAll('a[href]')) .map(a => ({ text: a.innerText.trim(), href: a.href })) .filter(l => l.text.length > 0); return JSON.stringify(links.slice(0, 20)); })()" end if end repeat end repeat return "TAB_NOT_FOUND" end tell EOF ``` --- ## 2. Interactive Clicking & Shadow DOM Penetration Standard `document.querySelector` fails when elements live inside Web Components or Shadow Roots. Use this recursive traversal helper: ```bash osascript << 'EOF' tell application "Google Chrome" repeat with w in windows repeat with t in tabs of w if URL of t contains "TARGET_DOMAIN" then return execute t javascript "(function() { function deepFind(root, targetText) { if (!root) return null; const candidates = root.querySelectorAll('button, a, input[type=\"button\"], input[type=\"submit\"], [role=\"button\"], label, span'); for (const el of candidates) { if (el.innerText && el.innerText.trim().includes(targetText) && el.offsetParent !== null) { return el; } } for (const el of root.querySelectorAll('*')) { if (el.shadowRoot) { const found = deepFind(el.shadowRoot, targetText); if (found) return found; } } return null; } const target = deepFind(document, 'Submit'); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'center' }); // Dispatch mouse sequence for high-compatibility frameworks target.dispatchEvent(new MouseEvent('mousedown', { bubbles: true })); target.dispatchEvent(new MouseEvent('mouseup', { bubbles: true })); target.click(); return 'CLICKED'; } return 'ELEMENT_NOT_FOUND'; })()" end if end repeat end repeat return "TAB_NOT_FOUND" end tell EOF ``` --- ## 3. Reactive Form Filling (React, Vue, Angular) Simply setting `input.value = "..."` frequently fails to update framework state (e.g., Vue `v-model` or React synthetic event bindings). Always dispatch synthetic input and change events: ```bash osascript << 'EOF' tell application "Google Chrome" repeat with w in windows repeat with t in tabs of w if URL of t contains "TARGET_DOMAIN" then return execute t javascript "(function() { const input = document.querySelector('input[name=\"search\"], #username, [placeholder*=\"Search\"]'); if (!input) return 'INPUT_NOT_FOUND'; input.focus(); input.value = 'My Query'; input.dispatchEvent(new Event('input', { bubbles: true })); input.dispatchEvent(new Event('change', { bubbles: true })); return 'INPUT_FILLED'; })()" end if end repeat end repeat return "TAB_NOT_FOUND" end tell EOF ``` --- ## 4. Extracting Captcha Image Data Extracts Base64 image data strings so multimodal agents can visually solve human verification challenges: ```bash osascript << 'EOF' tell application "Google Chrome" repeat with w in windows repeat with t in tabs of w if URL of t contains "TARGET_DOMAIN" then return execute t javascript "(function() { const img = document.querySelector('.captcha-image, img[src*=\"captcha\"], img[src*=\"code\"], img[src^=\"data:image\"]'); if (!img) return 'NO_CAPTCHA_IMAGE'; // If image is already data URI, return directly if (img.src.startsWith('data:image')) return img.src; // Otherwise draw to offscreen canvas to obtain Base64 try { const canvas = document.createElement('canvas'); canvas.width = img.naturalWidth || img.width; canvas.height = img.naturalHeight || img.height; const ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0); return canvas.toDataURL('image/png'); } catch(e) { return img.src; } })()" end if end repeat end repeat return "TAB_NOT_FOUND" end tell EOF ```references/spa-and-complex-web.md6.4 KBd9b3630a4a8fupstream ↗
# Reference: Modern SPAs & Complex Web Applications This reference provides battle-tested patterns for handling modern Single Page Applications (React, Vue, Next.js), complex rich-text frameworks (Draft.js, Lexical, ProseMirror), virtualized lists, client-side routing, and AppleScript IPC return value constraints. --- ## 1. AppleScript Safe IIFE & JSON Serialization ### Problem: The `missing value` Trap AppleScript's `execute tab javascript ...` bridge only supports primitive types (`string`, `integer`, `boolean`). If your JavaScript returns `undefined`, `null`, a DOM Node (`HTMLDivElement`), a function, or throws an unhandled error, AppleScript silently returns `missing value` or throws an error. ### Production Solution: Safe Defensive IIFE Wrapper Always wrap injected scripts in a self-contained IIFE with `try...catch` and explicit `JSON.stringify`: ```bash osascript << 'EOF' tell application "Google Chrome" repeat with w in windows repeat with t in tabs of w if URL of t contains "TARGET_DOMAIN" then return execute t javascript "(() => { try { const items = Array.from(document.querySelectorAll('.target-item')) .map(el => el.innerText.trim()) .filter(Boolean); return JSON.stringify(items.slice(0, 50)); } catch (e) { return 'ERROR: ' + e.message; } })()" end if end repeat end repeat return "TAB_NOT_FOUND" end tell EOF ``` --- ## 2. Virtualized Lists & Long Feeds (Twitter, Slack, Gmail, Feishu) ### Problem: DOM Destruction in Virtual Windows Modern web apps use virtualization (`react-window`, `react-virtualized`, `[data-testid="cellInnerDiv"]`, `role="feed"`). DOM nodes outside the current viewport are recycled or unmounted. Traditional `document.querySelectorAll()` returns only what fits on screen. ### Production Solution: Incremental Scroll & Collect Dispatch smooth scroll increments with micro-delays to allow the virtualizer to mount upcoming nodes: ```bash osascript << 'EOF' tell application "Google Chrome" repeat with w in windows repeat with t in tabs of w if URL of t contains "TARGET_DOMAIN" then return execute t javascript "(() => { return (async () => { const collected = new Set(); for (let step = 0; step < 5; step++) { const cells = document.querySelectorAll('[data-testid=\"cellInnerDiv\"], [role=\"row\"], article'); cells.forEach(c => { const txt = c.innerText ? c.innerText.trim() : ''; if (txt.length > 0) collected.add(txt); }); window.scrollBy({ top: 400, behavior: 'smooth' }); await new Promise(r => setTimeout(r, 600)); } return JSON.stringify(Array.from(collected).slice(0, 30)); })(); })()" end if end repeat end repeat return "TAB_NOT_FOUND" end tell EOF ``` --- ## 3. SPA Client-Side Route Synchronization (`history.pushState`) ### Problem: Asynchronous Navigation Without Page Reload When clicking links or buttons in modern SPAs, navigation occurs via `history.pushState()`. Reading `URL of t` immediately after `.click()` often returns the *old* URL because the transition hasn't completed in the browser process. ### Production Solution: Polling with Timeout ```applescript tell application "Google Chrome" -- 1. Trigger the SPA client-side navigation execute targetTab javascript "document.querySelector('a.route-link').click()" -- 2. Wait for route transition (poll up to 5 seconds) set hasNavigated to false repeat 10 times set curUrl to URL of targetTab if curUrl contains "expected-subpath" then set hasNavigated to true exit repeat end if delay 0.5 end repeat end tell ``` --- ## 4. Complex Rich-Text Editors (Draft.js, Lexical, ProseMirror) ### Problem: Immutable React State Disconnect Setting `.innerText`, `.innerHTML`, or `.value` on a `[contenteditable="true"]` element (used in Twitter/X, Slack, Notion, Jira) does **not** update the underlying framework's immutable state. The "Submit" or "Tweet" button remains disabled (`disabled: true`). ### Solution A: Web Intent Routing (Recommended for Social/Sharing Platforms) For platforms that support Web Intents (Twitter/X, Reddit, Mastodon, LinkedIn), bypass the UI editor entirely. Open a new tab with the intent URL: ```applescript tell application "Google Chrome" tell front window -- Text and status ID are pre-parsed into React state upon page load make new tab with properties {URL:"https://x.com/intent/tweet?in_reply_to=123456789&text=Hello%20World"} end tell end tell ``` Once loaded, the submit button is natively active. A simple `.click()` completes the action. ### Solution B: Synthetic InputEvent Dispatch For apps without Web Intents, focus the element and use `execCommand('insertText')` combined with synthetic `InputEvent` dispatching: ```javascript (() => { const editor = document.querySelector('[contenteditable="true"]'); if (!editor) return 'EDITOR_NOT_FOUND'; editor.focus(); document.execCommand('selectAll', false, null); document.execCommand('insertText', false, 'Your text content here'); editor.dispatchEvent(new Event('input', { bubbles: true })); return 'INSERTED'; })() ``` --- ## 5. Platform Notification Feed Disambiguation ### Problem: Algorithmic Recommendations Mixed with Direct Interactions Platforms like X, LinkedIn, and Weibo mix algorithmic suggestions (e.g. sparkle ✨ "Highlight for you" or "Recommended topic") directly into primary notification feeds (`/notifications`). An AI Agent must not confuse these with actionable user replies or mentions. ### Production Guidelines: 1. **Target Specific Sub-Routes**: Navigate directly to `/notifications/mentions` or `/notifications/unread` instead of the broad `/notifications` feed. 2. **Inspect Badge/Icon Semantics**: In JavaScript, check the SVG icon's `aria-label` or path data to distinguish direct interactions (replies, mentions, quotes) from algorithmic highlights before taking action.references/tab-management.md3.0 KB7800e0cc1f15upstream ↗
# Reference: Tab Management Operations This reference provides production-ready AppleScript snippets for discovering, targeting, creating, activating, and closing Google Chrome tabs on macOS. --- ## 1. List and Filter Tabs ### A. List All Open Tabs (with Window & Tab Index) ```bash osascript -e 'tell application "Google Chrome" set out to "" set wIndex to 1 repeat with w in windows set tIndex to 1 repeat with t in tabs of w set out to out & (id of t as text) & " | Window " & wIndex & " Tab " & tIndex & " | " & (title of t) & " | " & (URL of t) & linefeed set tIndex to tIndex + 1 end repeat set wIndex to wIndex + 1 end repeat return out end tell' ``` ### B. Find Tab by URL Substring or Title ```bash osascript << 'EOF' tell application "Google Chrome" repeat with w in windows repeat with t in tabs of w if (URL of t contains "github.com") or (title of t contains "Pull Requests") then return (id of t as text) & " | " & (title of t) & " | " & (URL of t) end if end repeat end repeat return "NOT_FOUND" end tell EOF ``` --- ## 2. Navigate and Open Tabs ### A. Navigate Existing Tab to a New URL ```bash osascript << 'EOF' tell application "Google Chrome" repeat with w in windows repeat with t in tabs of w if URL of t contains "TARGET_DOMAIN" then set URL of t to "https://app.example.com/dashboard" return "NAVIGATED" end if end repeat end repeat return "NOT_FOUND" end tell EOF ``` ### B. Open a New Tab in the Frontmost Window ```bash osascript -e 'tell application "Google Chrome" tell front window make new tab with properties {URL:"https://app.example.com"} end tell return "TAB_OPENED" end tell' ``` ### C. Open a New Background Tab (Without Stealing Focus) ```bash osascript -e 'tell application "Google Chrome" tell front window set newTab to make new tab with properties {URL:"https://app.example.com"} end tell return "BACKGROUND_TAB_OPENED" end tell' ``` --- ## 3. Focus and Activation ### Bring Tab and Chrome Window to Front ```bash osascript << 'EOF' tell application "Google Chrome" activate repeat with w in windows repeat with i from 1 to count of tabs of w set t to tab i of w if URL of t contains "TARGET_DOMAIN" then set active tab index of w to i set index of w to 1 return "ACTIVATED" end if end repeat end repeat return "NOT_FOUND" end tell EOF ``` --- ## 4. Close Tabs ### Close Tab Matching Specific URL or Title ```bash osascript << 'EOF' tell application "Google Chrome" repeat with w in windows repeat with t in tabs of w if URL of t contains "TARGET_DOMAIN_TO_CLOSE" then close t return "CLOSED" end if end repeat end repeat return "NOT_FOUND" end tell EOF ```.gitignore16 B9fa88ac4d377upstream ↗
.DS_Store *.logLICENSE1.0 KB2f77a74d0a79upstream ↗
MIT License Copyright (c) 2026 aicode915 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.README_CN.md7.9 KB6daafa7a23deupstream ↗
<div align="center"> ``` _____ __ _ ________ / _ \____/ |_(_)_ _____ __\______ \_______ ____ _____ ____ / /_\ \_ __ __\ |\__ \/ || | \_ __ \/ _ \/ \_/ __ \ / | \ | | | | | / __ \_ | ` \ | \( <_> ) Y Y \ ___/ \____|__ /__| |__|__|_|(____ / /_______ /__| \____/|__|_| /\___ > \/ \/ \/ \/ \/ ``` # chrome-mac-agent-skill **专为 AI Agent 打造的 macOS Google Chrome 原生会话控制技能包。免重启 Chrome,保留全部用户登录态。** [](https://opensource.org/licenses/MIT) [](https://apple.com/macos) [](https://github.com/aicode915/chrome-mac-agent-skill) [](https://github.com/aicode915/chrome-mac-agent-skill) [English](./README.md) • [简体中文](./README_CN.md) </div> --- ## ⚡ 痛点背景 当 AI 编程助手或智能体(如 Claude Code、Cursor、Windsurf、Antigravity)需要帮我们操作浏览器网页时,主流方案通常依赖 **Playwright** 或 **Puppeteer**。 这会带来极其痛苦的工作流割裂: 1. **丢失用户登录态**:它们默认启动一个全新的空白无痕浏览器,没有 Cookie。每次打开内部系统、邮箱或后台,都必须重新扫码、输密码或找手机短信 2FA。 2. **强迫重启浏览器**:如果想连接日常使用的 Chrome,通常必须杀掉所有窗口,带 `--remote-debugging-port` 参数重启。开发者日常几十个未保存的标签页直接丢失。 3. **环境庞大繁重**:为了看个网页,需要下载动辄数百兆的 Chromium 和繁杂的 Node/Python 驱动依赖。 --- ## 💡 解决方案:`chrome-mac-agent-skill` 本技能包直接利用 macOS 原生系统级 AppleScript 与后台正在运行的真实 Chrome 进程通信: - 🚀 **零重启、即插即用**:完全不需要关闭当前打开的工作标签页。 - 🔑 **无缝继承所有登录态**:Google 账号、企业 SSO 门户、GitHub、内网管理后台等所有 Cookie 完好无损。 - 🪶 **纯 Markdown 零依赖**:无需安装任何 `pip` 或 `npm` 依赖包,利用 macOS 内置的 `osascript` 毫秒级执行。 - 🛡 **原生系统弹窗与离开拦截破解**:内置自动剥离 `beforeunload` 锁,并支持自动点击 macOS 系统级确认弹窗(“重新加载此网站?”)。 - ⚡ **现代 SPA 与复杂富文本深度适配**:内置虚拟长列表滚动采集、客户端路由无刷新同步、Draft.js/Lexical 复杂富文本状态同步及 AppleScript 安全防吞没机制。 - 📦 **模块化渐进式加载(Progressive Disclosure)**:主干仅保留核心指令,深度疑难场景按需读取,极致节省大模型 Context Token。 --- ## 📊 与现有方案对比 | 功能特性 | Playwright / Puppeteer | 远程调试端口 (CDP) | 系统级 Computer Use (截屏+鼠标) | `chrome-mac-agent-skill` 🚀 | | :--- | :---: | :---: | :---: | :---: | | **保留用户已登录会话** | ❌ 否 (空白隔离环境) | ⚠️ 仅当启动时开启了端口 | ✅ 是 (直接看屏幕) | **✅ 是 (100% 完美保留)** | | **后台完全静默执行** | ⚠️ 仅限无头模式 | ⚠️ 需配置端口 | ❌ **否 (强行霸占鼠标与屏幕)** | **✅ 是 (零鼠标劫持/无感后台运行)** | | **动作执行响应速度** | ~1 - 3 秒 | ~500 毫秒 | ❌ **慢 (每次点击 5~10 秒)** | **⚡ 极致迅速 (<50 毫秒)** | | **Token 与资金消耗** | 极低 | 极低 | ❌ **极贵 (每次消耗数千视觉 Token)** | **💎 极致省钱 (零视觉 Token 浪费)** | | **系统权限要求** | 无特殊要求 | 无特殊要求 | ❌ **极高 (需屏幕录制 + 辅助功能权限)** | **🔒 极小 (仅需勾选 Chrome 菜单一次)** | | **点击精准度** | 极高 | 极高 | ⚠️ **受屏幕缩放/Retina 漂移影响易点偏** | **🎯 100% 绝对精准 (DOM 级别命中)** | | **需要关闭/重启 Chrome** | ❌ 需要 | ❌ 需要关闭已有 Chrome | ✅ 不需要 | **✅ 绝对不需要 (即连即用)** | --- ## 🥊 为什么不直接使用系统级 "Computer Use"(截屏 + 物理鼠标点击)? 虽然当前多模态大模型(如 Claude 3.5 / 3.7 Computer Use)具备直接“看屏幕像素并模拟鼠标点击”的能力,但在日常的浏览器操作中,Computer Use 往往是“高射炮打蚊子”: 1. **鼠标劫持 vs 真正的后台静默**: * *Computer Use 模式*:必须强行把 Chrome 窗口置顶在最前台,AI 会控制你的物理鼠标在屏幕上乱晃。在它操作期间,**你无法使用这台电脑**(你一动鼠标它就会点错位置)。 * *`chrome-mac-agent-skill`*:**100% 后台静默**。无论 Chrome 是最小化还是被其他窗口遮挡,AI 都能在后台标签页直接读写数据。你完全可以一边让 AI 发帖/查资料,一边看视频或敲代码,互不干扰! 2. **执行速度与延迟**: * *Computer Use 模式*:每一个点击动作都需要经历完整的循环:*截屏 -> 上传大图 -> 多模态视觉模型理解 -> 计算像素坐标 -> 移动鼠标 -> 点击 -> 等待 -> 再截屏验证*(单次操作耗时 **5~10 秒**)。 * *`chrome-mac-agent-skill`*:通过 macOS 原生 AppleScript IPC 直接定位 DOM 节点,响应时间在 **50 毫秒以内**。 3. **Token 与账单成本**: * *Computer Use 模式*:每一轮交互都需要传输 2K/4K 全屏高清截图,跑完一个任务会消耗大量 Vision Tokens。 * *`chrome-mac-agent-skill`*:**零视觉 Token 开销**,只传输精炼的文本指令,成本降低 95% 以上。 4. **最小权限与安全隐私**: * *Computer Use 模式*:必须向 AI 授予 macOS 极高风险的系统级权限:**「屏幕录制 (Screen Recording)」**(允许窥视你屏幕上的全部软件与隐私)和**「辅助功能 (Accessibility)」**(允许全局接管鼠标键盘)。 * *`chrome-mac-agent-skill`*:**完全不需要 macOS 屏幕录制权限**,操作严格被隔离在 Google Chrome 内部,安全感拉满。 --- ## 🚀 如何导入到你的 AI Agent ### 方式 1:直接放入工作区(Antigravity, Cursor, Windsurf) 将本仓库克隆或复制到项目的技能目录下: ```bash mkdir -p .agents/skills git clone https://github.com/aicode915/chrome-mac-agent-skill.git .agents/skills/active-chrome-control ``` ### 方式 2:Claude Code 将 `SKILL.md` 和 `references/` 复制到项目的 `.claude/skills/chrome-mac-agent-skill/`。 --- ## 🧭 仓库架构 ```text chrome-mac-agent-skill/ ├── SKILL.md # 核心入口:快速指令速查、前置检查与按需路由索引 ├── README.md # 英文说明文档 ├── README_CN.md # 中文说明文档 ├── LICENSE # MIT 开源协议 └── references/ # 专项深度指南(Agent 按需读取) ├── tab-management.md # 标签页发现、精准匹配、新建、切换与关闭 ├── page-interaction.md # 正文提取、JS 求值、穿透 Shadow DOM 点击、响应式表单 ├── dialog-handling.md # 系统原生弹窗点击与 beforeunload 静默解除 └── background-alive.md # 页面防切屏、防失焦挂起与后台保活注入 ``` --- ## ⚠️ 前置要求(仅需开启一次) 为允许 AppleScript 在 Chrome 中执行 JavaScript: 1. 打开 Google Chrome; 2. 在 macOS 顶部菜单栏选择:**查看 (View)** -> **开发者 (Developer)**; 3. 勾选 **允许 Apple 事件中的 JavaScript (Allow JavaScript from Apple Events)**。 --- ## 📄 开源许可证 [MIT](./LICENSE) © 2026 chrome-mac-agent-skill contributors.
Plain-text copy, no login: /skill-bundles/aicode915-chrome-mac-agent-skill.md