[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6KTAM9SRZ28ZW2BM7HM9DYV":3,"skill-same:01M6KTAM9SRZ28ZW2BM7HM9DYV":171},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":25,"publishedAt":46,"linkOnly":47,"markdownContent":48,"markdownBody":49,"frontMatter":50,"refName":55,"commitSha":56,"skillDirectory":57,"forksCount":13,"repositoryHtmlUrl":58,"repositoryHomepageUrl":6,"ownerHtmlUrl":59,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":60,"install":61,"resources":74},"01M6KTAM9SRZ28ZW2BM7HM9DYV","ck:chrome-devtools",null,"Browser automation, debugging, and performance analysis using Puppeteer CLI scripts. Use for automating browsers, taking screenshots, analyzing performance, monitoring network traffic, web scraping, form automation, and JavaScript debugging.","devmotminh\u002Fplayscored","devmotminh","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F133726659?v=4","01M6KSRTWXJ4EW9RPFDYZQ0MYH","01M6KSRV19QN8MN1MNQHNE46JS",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002FSKILL.md",[17,22],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":23,"categoryName":24,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发",[26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],"chrome devtools","ck","ck:chrome devtools","devtools","chrome","debugging","browser","puppeteer","performance","monitoring","screenshots","analyzing","network","analysis","scraping","browser automation","scripts","URL","traffic","cli","2026-11-10 10:12:30",false,"---\nname: ck:chrome-devtools\ndescription: Browser automation, debugging, and performance analysis using Puppeteer CLI scripts. Use for automating browsers, taking screenshots, analyzing performance, monitoring network traffic, web scraping, form automation, and JavaScript debugging.\nargument-hint: \"[url or task]\"\nlicense: Apache-2.0\nmetadata:\n  author: claudekit\n  version: \"1.1.0\"\n---\n\n# Chrome DevTools Agent Skill\n\nBrowser automation via Puppeteer scripts with persistent sessions. All scripts output JSON.\n\n## Skill Location\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\n\n```bash\n# Detect skill location\nSKILL_DIR=\"\"\nif [ -d \".opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\" ]; then\n  SKILL_DIR=\".opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\"\nelif [ -d \"$HOME\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\" ]; then\n  SKILL_DIR=\"$HOME\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\"\nfi\ncd \"$SKILL_DIR\"\n```\n\n## Choosing Your Approach\n\n| Scenario | Approach |\n|----------|----------|\n| **Source-available sites** | Read source code first, write selectors directly |\n| **Unknown layouts** | Use `aria-snapshot.js` for semantic discovery |\n| **Visual inspection** | Take screenshots to verify rendering |\n| **Debug issues** | Collect console logs, analyze with session storage |\n| **Accessibility audit** | Use ARIA snapshot for semantic structure analysis |\n\n## Automation Browsing Running Mode\n\n- Detect current OS and launch browser as headless only when running on Linux, WSL, or CI environments.\n- For macOS\u002FWindows, browser always runs in headed mode for better debugging.\n- Run multiple scripts\u002Fsessions in parallel to simulate real user interactions.\n- Run multiple scripts\u002Fsessions in parallel to simulate different device types (mobile, tablet, desktop).\n- Skills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\n\n## ARIA Snapshot (Element Discovery)\n\nWhen page structure is unknown, use `aria-snapshot.js` to get a YAML-formatted accessibility tree with semantic roles, accessible names, states, and stable element references.\n\n### Get ARIA Snapshot\n\n```bash\n# Generate ARIA snapshot and output to stdout\nnode aria-snapshot.js --url https:\u002F\u002Fexample.com\n\n# Save to file in snapshots directory\nnode aria-snapshot.js --url https:\u002F\u002Fexample.com --output .\u002F.opencode\u002Fchrome-devtools\u002Fsnapshots\u002Fpage.yaml\n```\n\n### Example YAML Output\n\n```yaml\n- banner:\n  - link \"Hacker News\" [ref=e1]\n    \u002Furl: https:\u002F\u002Fnews.ycombinator.com\n  - navigation:\n    - link \"new\" [ref=e2]\n    - link \"past\" [ref=e3]\n    - link \"comments\" [ref=e4]\n- main:\n  - list:\n    - listitem:\n      - link \"Show HN: My new project\" [ref=e8]\n      - text: \"128 points by user 3 hours ago\"\n- contentinfo:\n  - textbox [ref=e10]\n    \u002Fplaceholder: \"Search\"\n```\n\n### Interpreting ARIA Notation\n\n| Notation | Meaning |\n|----------|---------|\n| `[ref=eN]` | Stable identifier for interactive elements |\n| `[checked]` | Checkbox\u002Fradio is selected |\n| `[disabled]` | Element is inactive |\n| `[expanded]` | Accordion\u002Fdropdown is open |\n| `[level=N]` | Heading hierarchy (1-6) |\n| `\u002Furl:` | Link destination |\n| `\u002Fplaceholder:` | Input placeholder text |\n| `\u002Fvalue:` | Current input value |\n\n### Interact by Ref\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\nUse `select-ref.js` to interact with elements by their ref:\n\n```bash\n# Click element with ref e5\nnode select-ref.js --ref e5 --action click\n\n# Fill input with ref e10\nnode select-ref.js --ref e10 --action fill --value \"search query\"\n\n# Get text content\nnode select-ref.js --ref e8 --action text\n\n# Screenshot specific element\nnode select-ref.js --ref e1 --action screenshot --output .\u002Flogo.png\n\n# Focus element\nnode select-ref.js --ref e10 --action focus\n\n# Hover over element\nnode select-ref.js --ref e5 --action hover\n```\n\n### Store Snapshots\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\nStore snapshots for analysis in `\u003Cproject>\u002F.opencode\u002Fchrome-devtools\u002Fsnapshots\u002F`:\n\n```bash\n# Create snapshots directory\nmkdir -p .opencode\u002Fchrome-devtools\u002Fsnapshots\n\n# Capture and store with timestamp\nSESSION=\"$(date +%Y%m%d-%H%M%S)\"\nnode aria-snapshot.js --url https:\u002F\u002Fexample.com --output .opencode\u002Fchrome-devtools\u002Fsnapshots\u002F$SESSION.yaml\n```\n\n### Workflow: Unknown Page Structure\n\n1. **Get snapshot** to discover elements:\n   ```bash\n   node aria-snapshot.js --url https:\u002F\u002Fexample.com\n   ```\n\n2. **Identify target** from YAML output (e.g., `[ref=e5]` for a button)\n\n3. **Interact by ref**:\n   ```bash\n   node select-ref.js --ref e5 --action click\n   ```\n\n4. **Verify result** with screenshot or new snapshot:\n   ```bash\n   node screenshot.js --output .\u002Fresult.png\n   ```\n\n## Local HTML Files\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\n**IMPORTANT**: Never browse local HTML files via `file:\u002F\u002F` protocol. Always serve via local server:\n**Why**: `file:\u002F\u002F` protocol blocks many browser features (CORS, ES modules, fetch API, service workers). Local server ensures proper HTTP behavior.\n\n```bash\n# Option 1: npx serve (recommended)\nnpx serve .\u002Fdist -p 3000 &\nnode navigate.js --url http:\u002F\u002Flocalhost:3000\n\n# Option 2: Python http.server\npython -m http.server 3000 --directory .\u002Fdist &\nnode navigate.js --url http:\u002F\u002Flocalhost:3000\n```\n\n**Note**: when port 3000 is busy, find an available port with `lsof -i :3000` and use a different one.\n\n## Quick Start\n\n```bash\n# Install dependencies\ncd .opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\nnpm install  # Installs puppeteer, sharp, debug, yargs\n\n# Test (browser stays running for session reuse)\nnode navigate.js --url https:\u002F\u002Fexample.com\n# Output: {\"success\": true, \"url\": \"...\", \"title\": \"...\"}\n```\n\n**Linux\u002FWSL only**: Run `.\u002Finstall-deps.sh` first for Chrome system libraries.\n\n## Session Persistence\n\nBrowser state persists across script executions via WebSocket endpoint file (`.browser-session.json`).\n\n**Default behavior**: Scripts disconnect but keep browser running for session reuse.\n\n```bash\n# First script: launches browser, navigates, disconnects (browser stays running)\nnode navigate.js --url https:\u002F\u002Fexample.com\u002Flogin\n\n# Subsequent scripts: connect to existing browser, reuse page state\nnode fill.js --selector \"#email\" --value \"user@example.com\"\nnode fill.js --selector \"#password\" --value \"secret\"\nnode click.js --selector \"button[type=submit]\"\n\n# Close browser when done\nnode navigate.js --url about:blank --close true\n```\n\n**Session management**:\n- `--close true`: Close browser and clear session\n- Default (no flag): Keep browser running for next script\n\n## Available Scripts\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\nAll in `.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002F`:\n\n| Script | Purpose |\n|--------|---------|\n| `navigate.js` | Navigate to URLs |\n| `screenshot.js` | Capture screenshots (auto-compress >5MB via Sharp) |\n| `click.js` | Click elements |\n| `fill.js` | Fill form fields |\n| `evaluate.js` | Execute JS in page context |\n| `snapshot.js` | Extract interactive elements (JSON format) |\n| `aria-snapshot.js` | Get ARIA accessibility tree (YAML format with refs) |\n| `select-ref.js` | Interact with elements by ref from ARIA snapshot |\n| `console.js` | Monitor console messages\u002Ferrors |\n| `network.js` | Track HTTP requests\u002Fresponses |\n| `performance.js` | Measure Core Web Vitals |\n\n## Workflow Loop\n\n1. **Execute** focused script for single task\n2. **Observe** JSON output\n3. **Assess** completion status\n4. **Decide** next action\n5. **Repeat** until done\n\n## Writing Custom Test Scripts\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\nFor complex automation, write scripts to `\u003Cproject>\u002F.opencode\u002Fchrome-devtools\u002Ftmp\u002F`:\n\n```bash\n# Create tmp directory for test scripts\nmkdir -p $SKILL_DIR\u002F.opencode\u002Fchrome-devtools\u002Ftmp\n\n# Write a test script\ncat > $SKILL_DIR\u002F.opencode\u002Fchrome-devtools\u002Ftmp\u002Flogin-test.js \u003C\u003C 'EOF'\nimport { getBrowser, getPage, disconnectBrowser, outputJSON } from '..\u002Fscripts\u002Flib\u002Fbrowser.js';\n\nasync function loginTest() {\n  const browser = await getBrowser();\n  const page = await getPage(browser);\n\n  await page.goto('https:\u002F\u002Fexample.com\u002Flogin');\n  await page.type('#email', 'user@example.com');\n  await page.type('#password', 'secret');\n  await page.click('button[type=submit]');\n  await page.waitForNavigation();\n\n  outputJSON({\n    success: true,\n    url: page.url(),\n    title: await page.title()\n  });\n\n  await disconnectBrowser();\n}\n\nloginTest();\nEOF\n\n# Run the test\nnode $SKILL_DIR\u002F.opencode\u002Fchrome-devtools\u002Ftmp\u002Flogin-test.js\n```\n\n**Key principles for custom scripts**:\n- Single-purpose: one script, one task\n- Always call `disconnectBrowser()` at the end (keeps browser running)\n- Use `closeBrowser()` only when ending session completely\n- Output JSON for easy parsing\n- Plain JavaScript only in `page.evaluate()` callbacks\n\n## Screenshots\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\nStore screenshots for analysis in `\u003Cproject>\u002F.opencode\u002Fchrome-devtools\u002Fscreenshots\u002F`:\n\n```bash\n# Basic screenshot\nnode screenshot.js --url https:\u002F\u002Fexample.com --output .\u002F.opencode\u002Fchrome-devtools\u002Fscreenshots\u002Fpage.png\n\n# Full page\nnode screenshot.js --url https:\u002F\u002Fexample.com --output .\u002F.opencode\u002Fchrome-devtools\u002Fscreenshots\u002Fpage.png --full-page true\n\n# Specific element\nnode screenshot.js --url https:\u002F\u002Fexample.com --selector \".main-content\" --output .\u002F.opencode\u002Fchrome-devtools\u002Fscreenshots\u002Felement.png\n```\n\n### Auto-Compression (Sharp)\n\nScreenshots >5MB auto-compress using Sharp (4-5x faster than ImageMagick):\n\n```bash\n# Default: compress if >5MB\nnode screenshot.js --url https:\u002F\u002Fexample.com --output .\u002F.opencode\u002Fchrome-devtools\u002Fscreenshots\u002Fpage.png\n\n# Custom threshold (3MB)\nnode screenshot.js --url https:\u002F\u002Fexample.com --output .\u002F.opencode\u002Fchrome-devtools\u002Fscreenshots\u002Fpage.png --max-size 3\n\n# Disable compression\nnode screenshot.js --url https:\u002F\u002Fexample.com --output .\u002F.opencode\u002Fchrome-devtools\u002Fscreenshots\u002Fpage.png --no-compress\n```\n\nStore screenshots for analysis in `\u003Cproject>\u002F.opencode\u002Fchrome-devtools\u002Fscreenshots\u002F`.\n\n## Console Log Collection & Analysis\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\n\n### Capture Logs\n\n```bash\n# Capture all logs for 10 seconds\nnode console.js --url https:\u002F\u002Fexample.com --duration 10000\n\n# Filter by type\nnode console.js --url https:\u002F\u002Fexample.com --types error,warn --duration 5000\n```\n\n### Session Storage Pattern\n\nStore logs for analysis in `\u003Cproject>\u002F.opencode\u002Fchrome-devtools\u002Flogs\u002F\u003Csession>\u002F`:\n\n```bash\n# Create session directory\nSESSION=\"$(date +%Y%m%d-%H%M%S)\"\nmkdir -p .opencode\u002Fchrome-devtools\u002Flogs\u002F$SESSION\n\n# Capture and store\nnode console.js --url https:\u002F\u002Fexample.com --duration 10000 > .opencode\u002Fchrome-devtools\u002Flogs\u002F$SESSION\u002Fconsole.json\nnode network.js --url https:\u002F\u002Fexample.com > .opencode\u002Fchrome-devtools\u002Flogs\u002F$SESSION\u002Fnetwork.json\n\n# View errors\njq '.messages[] | select(.type==\"error\")' .opencode\u002Fchrome-devtools\u002Flogs\u002F$SESSION\u002Fconsole.json\n```\n\n### Root Cause Analysis\n\n```bash\n# 1. Check for JavaScript errors\nnode console.js --url https:\u002F\u002Fexample.com --types error,pageerror --duration 5000 | jq '.messages'\n\n# 2. Correlate with network failures\nnode network.js --url https:\u002F\u002Fexample.com | jq '.requests[] | select(.response.status >= 400)'\n\n# 3. Check specific error stack traces\nnode console.js --url https:\u002F\u002Fexample.com --types error --duration 5000 | jq '.messages[].stack'\n```\n\n## Finding Elements\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\nUse `snapshot.js` to discover selectors before interacting:\n\n```bash\n# Get all interactive elements\nnode snapshot.js --url https:\u002F\u002Fexample.com | jq '.elements[] | {tagName, text, selector}'\n\n# Find buttons\nnode snapshot.js --url https:\u002F\u002Fexample.com | jq '.elements[] | select(.tagName==\"button\")'\n\n# Find by text content\nnode snapshot.js --url https:\u002F\u002Fexample.com | jq '.elements[] | select(.text | contains(\"Submit\"))'\n```\n\n## Error Recovery\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\nIf script fails:\n\n```bash\n# 1. Capture current state (without navigating to preserve state)\nnode screenshot.js --output .\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscreenshots\u002Fdebug.png\n\n# 2. Get console errors\nnode console.js --url about:blank --types error --duration 1000\n\n# 3. Discover correct selector\nnode snapshot.js | jq '.elements[] | select(.text | contains(\"Submit\"))'\n\n# 4. Try XPath if CSS fails\nnode click.js --selector \"\u002F\u002Fbutton[contains(text(),'Submit')]\"\n```\n\n## Common Patterns\n\n### Web Scraping\n```bash\nnode evaluate.js --url https:\u002F\u002Fexample.com --script \"\n  Array.from(document.querySelectorAll('.item')).map(el => ({\n    title: el.querySelector('h2')?.textContent,\n    link: el.querySelector('a')?.href\n  }))\n\" | jq '.result'\n```\n\n### Form Automation\n```bash\nnode navigate.js --url https:\u002F\u002Fexample.com\u002Fform\nnode fill.js --selector \"#search\" --value \"query\"\nnode click.js --selector \"button[type=submit]\"\n```\n\n### Performance Testing\n```bash\nnode performance.js --url https:\u002F\u002Fexample.com | jq '.vitals'\n```\n\n## Script Options\n\nAll scripts support:\n- `--headless false` - Show browser window\n- `--close true` - Close browser completely (default: stay running)\n- `--timeout 30000` - Set timeout (ms)\n- `--wait-until networkidle2` - Wait strategy\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\n\n## Troubleshooting\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\n\n| Error | Solution |\n|-------|----------|\n| `Cannot find package 'puppeteer'` | Run `npm install` in scripts directory |\n| `libnss3.so` missing (Linux) | Run `.\u002Finstall-deps.sh` |\n| Element not found | Use `snapshot.js` to find correct selector |\n| Script hangs | Use `--timeout 60000` or `--wait-until load` |\n| Screenshot >5MB | Auto-compressed; use `--max-size 3` for lower |\n| Session stale | Delete `.browser-session.json` and retry |\n\n### Screenshot Analysis: Missing Images\n\nIf images don't appear in screenshots, they may be waiting for animation triggers:\n\n1. **Scroll-triggered animations**: Scroll element into view first\n   ```bash\n   node evaluate.js --script \"document.querySelector('.lazy-image').scrollIntoView()\"\n   # Wait for animation\n   node evaluate.js --script \"await new Promise(r => setTimeout(r, 1000))\"\n   node screenshot.js --output .\u002Fresult.png\n   ```\n\n2. **Sequential animation queue**: Wait longer and retry\n   ```bash\n   # First attempt\n   node screenshot.js --url http:\u002F\u002Flocalhost:3000 --output .\u002Fattempt1.png\n\n   # Wait for animations to complete\n   node evaluate.js --script \"await new Promise(r => setTimeout(r, 2000))\"\n\n   # Retry screenshot\n   node screenshot.js --output .\u002Fattempt2.png\n   ```\n\n3. **Intersection Observer animations**: Trigger by scrolling through page\n   ```bash\n   node evaluate.js --script \"window.scrollTo(0, document.body.scrollHeight)\"\n   node evaluate.js --script \"await new Promise(r => setTimeout(r, 1500))\"\n   node evaluate.js --script \"window.scrollTo(0, 0)\"\n   node screenshot.js --output .\u002Ffull-loaded.png --full-page true\n   ```\n\n## Reference Documentation\n\n- `.\u002Freferences\u002Fcdp-domains.md` - Chrome DevTools Protocol domains\n- `.\u002Freferences\u002Fpuppeteer-reference.md` - Puppeteer API patterns\n- `.\u002Freferences\u002Fperformance-guide.md` - Core Web Vitals optimization\n- `.\u002Fscripts\u002FREADME.md` - Detailed script options\n","# Chrome DevTools Agent Skill\n\nBrowser automation via Puppeteer scripts with persistent sessions. All scripts output JSON.\n\n## Skill Location\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\n\n```bash\n# Detect skill location\nSKILL_DIR=\"\"\nif [ -d \".opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\" ]; then\n  SKILL_DIR=\".opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\"\nelif [ -d \"$HOME\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\" ]; then\n  SKILL_DIR=\"$HOME\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\"\nfi\ncd \"$SKILL_DIR\"\n```\n\n## Choosing Your Approach\n\n| Scenario | Approach |\n|----------|----------|\n| **Source-available sites** | Read source code first, write selectors directly |\n| **Unknown layouts** | Use `aria-snapshot.js` for semantic discovery |\n| **Visual inspection** | Take screenshots to verify rendering |\n| **Debug issues** | Collect console logs, analyze with session storage |\n| **Accessibility audit** | Use ARIA snapshot for semantic structure analysis |\n\n## Automation Browsing Running Mode\n\n- Detect current OS and launch browser as headless only when running on Linux, WSL, or CI environments.\n- For macOS\u002FWindows, browser always runs in headed mode for better debugging.\n- Run multiple scripts\u002Fsessions in parallel to simulate real user interactions.\n- Run multiple scripts\u002Fsessions in parallel to simulate different device types (mobile, tablet, desktop).\n- Skills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\n\n## ARIA Snapshot (Element Discovery)\n\nWhen page structure is unknown, use `aria-snapshot.js` to get a YAML-formatted accessibility tree with semantic roles, accessible names, states, and stable element references.\n\n### Get ARIA Snapshot\n\n```bash\n# Generate ARIA snapshot and output to stdout\nnode aria-snapshot.js --url https:\u002F\u002Fexample.com\n\n# Save to file in snapshots directory\nnode aria-snapshot.js --url https:\u002F\u002Fexample.com --output .\u002F.opencode\u002Fchrome-devtools\u002Fsnapshots\u002Fpage.yaml\n```\n\n### Example YAML Output\n\n```yaml\n- banner:\n  - link \"Hacker News\" [ref=e1]\n    \u002Furl: https:\u002F\u002Fnews.ycombinator.com\n  - navigation:\n    - link \"new\" [ref=e2]\n    - link \"past\" [ref=e3]\n    - link \"comments\" [ref=e4]\n- main:\n  - list:\n    - listitem:\n      - link \"Show HN: My new project\" [ref=e8]\n      - text: \"128 points by user 3 hours ago\"\n- contentinfo:\n  - textbox [ref=e10]\n    \u002Fplaceholder: \"Search\"\n```\n\n### Interpreting ARIA Notation\n\n| Notation | Meaning |\n|----------|---------|\n| `[ref=eN]` | Stable identifier for interactive elements |\n| `[checked]` | Checkbox\u002Fradio is selected |\n| `[disabled]` | Element is inactive |\n| `[expanded]` | Accordion\u002Fdropdown is open |\n| `[level=N]` | Heading hierarchy (1-6) |\n| `\u002Furl:` | Link destination |\n| `\u002Fplaceholder:` | Input placeholder text |\n| `\u002Fvalue:` | Current input value |\n\n### Interact by Ref\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\nUse `select-ref.js` to interact with elements by their ref:\n\n```bash\n# Click element with ref e5\nnode select-ref.js --ref e5 --action click\n\n# Fill input with ref e10\nnode select-ref.js --ref e10 --action fill --value \"search query\"\n\n# Get text content\nnode select-ref.js --ref e8 --action text\n\n# Screenshot specific element\nnode select-ref.js --ref e1 --action screenshot --output .\u002Flogo.png\n\n# Focus element\nnode select-ref.js --ref e10 --action focus\n\n# Hover over element\nnode select-ref.js --ref e5 --action hover\n```\n\n### Store Snapshots\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\nStore snapshots for analysis in `\u003Cproject>\u002F.opencode\u002Fchrome-devtools\u002Fsnapshots\u002F`:\n\n```bash\n# Create snapshots directory\nmkdir -p .opencode\u002Fchrome-devtools\u002Fsnapshots\n\n# Capture and store with timestamp\nSESSION=\"$(date +%Y%m%d-%H%M%S)\"\nnode aria-snapshot.js --url https:\u002F\u002Fexample.com --output .opencode\u002Fchrome-devtools\u002Fsnapshots\u002F$SESSION.yaml\n```\n\n### Workflow: Unknown Page Structure\n\n1. **Get snapshot** to discover elements:\n   ```bash\n   node aria-snapshot.js --url https:\u002F\u002Fexample.com\n   ```\n\n2. **Identify target** from YAML output (e.g., `[ref=e5]` for a button)\n\n3. **Interact by ref**:\n   ```bash\n   node select-ref.js --ref e5 --action click\n   ```\n\n4. **Verify result** with screenshot or new snapshot:\n   ```bash\n   node screenshot.js --output .\u002Fresult.png\n   ```\n\n## Local HTML Files\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\n**IMPORTANT**: Never browse local HTML files via `file:\u002F\u002F` protocol. Always serve via local server:\n**Why**: `file:\u002F\u002F` protocol blocks many browser features (CORS, ES modules, fetch API, service workers). Local server ensures proper HTTP behavior.\n\n```bash\n# Option 1: npx serve (recommended)\nnpx serve .\u002Fdist -p 3000 &\nnode navigate.js --url http:\u002F\u002Flocalhost:3000\n\n# Option 2: Python http.server\npython -m http.server 3000 --directory .\u002Fdist &\nnode navigate.js --url http:\u002F\u002Flocalhost:3000\n```\n\n**Note**: when port 3000 is busy, find an available port with `lsof -i :3000` and use a different one.\n\n## Quick Start\n\n```bash\n# Install dependencies\ncd .opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\nnpm install  # Installs puppeteer, sharp, debug, yargs\n\n# Test (browser stays running for session reuse)\nnode navigate.js --url https:\u002F\u002Fexample.com\n# Output: {\"success\": true, \"url\": \"...\", \"title\": \"...\"}\n```\n\n**Linux\u002FWSL only**: Run `.\u002Finstall-deps.sh` first for Chrome system libraries.\n\n## Session Persistence\n\nBrowser state persists across script executions via WebSocket endpoint file (`.browser-session.json`).\n\n**Default behavior**: Scripts disconnect but keep browser running for session reuse.\n\n```bash\n# First script: launches browser, navigates, disconnects (browser stays running)\nnode navigate.js --url https:\u002F\u002Fexample.com\u002Flogin\n\n# Subsequent scripts: connect to existing browser, reuse page state\nnode fill.js --selector \"#email\" --value \"user@example.com\"\nnode fill.js --selector \"#password\" --value \"secret\"\nnode click.js --selector \"button[type=submit]\"\n\n# Close browser when done\nnode navigate.js --url about:blank --close true\n```\n\n**Session management**:\n- `--close true`: Close browser and clear session\n- Default (no flag): Keep browser running for next script\n\n## Available Scripts\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\nAll in `.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002F`:\n\n| Script | Purpose |\n|--------|---------|\n| `navigate.js` | Navigate to URLs |\n| `screenshot.js` | Capture screenshots (auto-compress >5MB via Sharp) |\n| `click.js` | Click elements |\n| `fill.js` | Fill form fields |\n| `evaluate.js` | Execute JS in page context |\n| `snapshot.js` | Extract interactive elements (JSON format) |\n| `aria-snapshot.js` | Get ARIA accessibility tree (YAML format with refs) |\n| `select-ref.js` | Interact with elements by ref from ARIA snapshot |\n| `console.js` | Monitor console messages\u002Ferrors |\n| `network.js` | Track HTTP requests\u002Fresponses |\n| `performance.js` | Measure Core Web Vitals |\n\n## Workflow Loop\n\n1. **Execute** focused script for single task\n2. **Observe** JSON output\n3. **Assess** completion status\n4. **Decide** next action\n5. **Repeat** until done\n\n## Writing Custom Test Scripts\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\nFor complex automation, write scripts to `\u003Cproject>\u002F.opencode\u002Fchrome-devtools\u002Ftmp\u002F`:\n\n```bash\n# Create tmp directory for test scripts\nmkdir -p $SKILL_DIR\u002F.opencode\u002Fchrome-devtools\u002Ftmp\n\n# Write a test script\ncat > $SKILL_DIR\u002F.opencode\u002Fchrome-devtools\u002Ftmp\u002Flogin-test.js \u003C\u003C 'EOF'\nimport { getBrowser, getPage, disconnectBrowser, outputJSON } from '..\u002Fscripts\u002Flib\u002Fbrowser.js';\n\nasync function loginTest() {\n  const browser = await getBrowser();\n  const page = await getPage(browser);\n\n  await page.goto('https:\u002F\u002Fexample.com\u002Flogin');\n  await page.type('#email', 'user@example.com');\n  await page.type('#password', 'secret');\n  await page.click('button[type=submit]');\n  await page.waitForNavigation();\n\n  outputJSON({\n    success: true,\n    url: page.url(),\n    title: await page.title()\n  });\n\n  await disconnectBrowser();\n}\n\nloginTest();\nEOF\n\n# Run the test\nnode $SKILL_DIR\u002F.opencode\u002Fchrome-devtools\u002Ftmp\u002Flogin-test.js\n```\n\n**Key principles for custom scripts**:\n- Single-purpose: one script, one task\n- Always call `disconnectBrowser()` at the end (keeps browser running)\n- Use `closeBrowser()` only when ending session completely\n- Output JSON for easy parsing\n- Plain JavaScript only in `page.evaluate()` callbacks\n\n## Screenshots\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\nStore screenshots for analysis in `\u003Cproject>\u002F.opencode\u002Fchrome-devtools\u002Fscreenshots\u002F`:\n\n```bash\n# Basic screenshot\nnode screenshot.js --url https:\u002F\u002Fexample.com --output .\u002F.opencode\u002Fchrome-devtools\u002Fscreenshots\u002Fpage.png\n\n# Full page\nnode screenshot.js --url https:\u002F\u002Fexample.com --output .\u002F.opencode\u002Fchrome-devtools\u002Fscreenshots\u002Fpage.png --full-page true\n\n# Specific element\nnode screenshot.js --url https:\u002F\u002Fexample.com --selector \".main-content\" --output .\u002F.opencode\u002Fchrome-devtools\u002Fscreenshots\u002Felement.png\n```\n\n### Auto-Compression (Sharp)\n\nScreenshots >5MB auto-compress using Sharp (4-5x faster than ImageMagick):\n\n```bash\n# Default: compress if >5MB\nnode screenshot.js --url https:\u002F\u002Fexample.com --output .\u002F.opencode\u002Fchrome-devtools\u002Fscreenshots\u002Fpage.png\n\n# Custom threshold (3MB)\nnode screenshot.js --url https:\u002F\u002Fexample.com --output .\u002F.opencode\u002Fchrome-devtools\u002Fscreenshots\u002Fpage.png --max-size 3\n\n# Disable compression\nnode screenshot.js --url https:\u002F\u002Fexample.com --output .\u002F.opencode\u002Fchrome-devtools\u002Fscreenshots\u002Fpage.png --no-compress\n```\n\nStore screenshots for analysis in `\u003Cproject>\u002F.opencode\u002Fchrome-devtools\u002Fscreenshots\u002F`.\n\n## Console Log Collection & Analysis\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\n\n### Capture Logs\n\n```bash\n# Capture all logs for 10 seconds\nnode console.js --url https:\u002F\u002Fexample.com --duration 10000\n\n# Filter by type\nnode console.js --url https:\u002F\u002Fexample.com --types error,warn --duration 5000\n```\n\n### Session Storage Pattern\n\nStore logs for analysis in `\u003Cproject>\u002F.opencode\u002Fchrome-devtools\u002Flogs\u002F\u003Csession>\u002F`:\n\n```bash\n# Create session directory\nSESSION=\"$(date +%Y%m%d-%H%M%S)\"\nmkdir -p .opencode\u002Fchrome-devtools\u002Flogs\u002F$SESSION\n\n# Capture and store\nnode console.js --url https:\u002F\u002Fexample.com --duration 10000 > .opencode\u002Fchrome-devtools\u002Flogs\u002F$SESSION\u002Fconsole.json\nnode network.js --url https:\u002F\u002Fexample.com > .opencode\u002Fchrome-devtools\u002Flogs\u002F$SESSION\u002Fnetwork.json\n\n# View errors\njq '.messages[] | select(.type==\"error\")' .opencode\u002Fchrome-devtools\u002Flogs\u002F$SESSION\u002Fconsole.json\n```\n\n### Root Cause Analysis\n\n```bash\n# 1. Check for JavaScript errors\nnode console.js --url https:\u002F\u002Fexample.com --types error,pageerror --duration 5000 | jq '.messages'\n\n# 2. Correlate with network failures\nnode network.js --url https:\u002F\u002Fexample.com | jq '.requests[] | select(.response.status >= 400)'\n\n# 3. Check specific error stack traces\nnode console.js --url https:\u002F\u002Fexample.com --types error --duration 5000 | jq '.messages[].stack'\n```\n\n## Finding Elements\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\nUse `snapshot.js` to discover selectors before interacting:\n\n```bash\n# Get all interactive elements\nnode snapshot.js --url https:\u002F\u002Fexample.com | jq '.elements[] | {tagName, text, selector}'\n\n# Find buttons\nnode snapshot.js --url https:\u002F\u002Fexample.com | jq '.elements[] | select(.tagName==\"button\")'\n\n# Find by text content\nnode snapshot.js --url https:\u002F\u002Fexample.com | jq '.elements[] | select(.text | contains(\"Submit\"))'\n```\n\n## Error Recovery\n\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\nIf script fails:\n\n```bash\n# 1. Capture current state (without navigating to preserve state)\nnode screenshot.js --output .\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscreenshots\u002Fdebug.png\n\n# 2. Get console errors\nnode console.js --url about:blank --types error --duration 1000\n\n# 3. Discover correct selector\nnode snapshot.js | jq '.elements[] | select(.text | contains(\"Submit\"))'\n\n# 4. Try XPath if CSS fails\nnode click.js --selector \"\u002F\u002Fbutton[contains(text(),'Submit')]\"\n```\n\n## Common Patterns\n\n### Web Scraping\n```bash\nnode evaluate.js --url https:\u002F\u002Fexample.com --script \"\n  Array.from(document.querySelectorAll('.item')).map(el => ({\n    title: el.querySelector('h2')?.textContent,\n    link: el.querySelector('a')?.href\n  }))\n\" | jq '.result'\n```\n\n### Form Automation\n```bash\nnode navigate.js --url https:\u002F\u002Fexample.com\u002Fform\nnode fill.js --selector \"#search\" --value \"query\"\nnode click.js --selector \"button[type=submit]\"\n```\n\n### Performance Testing\n```bash\nnode performance.js --url https:\u002F\u002Fexample.com | jq '.vitals'\n```\n\n## Script Options\n\nAll scripts support:\n- `--headless false` - Show browser window\n- `--close true` - Close browser completely (default: stay running)\n- `--timeout 30000` - Set timeout (ms)\n- `--wait-until networkidle2` - Wait strategy\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\n\n## Troubleshooting\nSkills can exist in **project-scope** or **user-scope**. Priority: project-scope > user-scope.\n\n| Error | Solution |\n|-------|----------|\n| `Cannot find package 'puppeteer'` | Run `npm install` in scripts directory |\n| `libnss3.so` missing (Linux) | Run `.\u002Finstall-deps.sh` |\n| Element not found | Use `snapshot.js` to find correct selector |\n| Script hangs | Use `--timeout 60000` or `--wait-until load` |\n| Screenshot >5MB | Auto-compressed; use `--max-size 3` for lower |\n| Session stale | Delete `.browser-session.json` and retry |\n\n### Screenshot Analysis: Missing Images\n\nIf images don't appear in screenshots, they may be waiting for animation triggers:\n\n1. **Scroll-triggered animations**: Scroll element into view first\n   ```bash\n   node evaluate.js --script \"document.querySelector('.lazy-image').scrollIntoView()\"\n   # Wait for animation\n   node evaluate.js --script \"await new Promise(r => setTimeout(r, 1000))\"\n   node screenshot.js --output .\u002Fresult.png\n   ```\n\n2. **Sequential animation queue**: Wait longer and retry\n   ```bash\n   # First attempt\n   node screenshot.js --url http:\u002F\u002Flocalhost:3000 --output .\u002Fattempt1.png\n\n   # Wait for animations to complete\n   node evaluate.js --script \"await new Promise(r => setTimeout(r, 2000))\"\n\n   # Retry screenshot\n   node screenshot.js --output .\u002Fattempt2.png\n   ```\n\n3. **Intersection Observer animations**: Trigger by scrolling through page\n   ```bash\n   node evaluate.js --script \"window.scrollTo(0, document.body.scrollHeight)\"\n   node evaluate.js --script \"await new Promise(r => setTimeout(r, 1500))\"\n   node evaluate.js --script \"window.scrollTo(0, 0)\"\n   node screenshot.js --output .\u002Ffull-loaded.png --full-page true\n   ```\n\n## Reference Documentation\n\n- `.\u002Freferences\u002Fcdp-domains.md` - Chrome DevTools Protocol domains\n- `.\u002Freferences\u002Fpuppeteer-reference.md` - Puppeteer API patterns\n- `.\u002Freferences\u002Fperformance-guide.md` - Core Web Vitals optimization\n- `.\u002Fscripts\u002FREADME.md` - Detailed script options\n",{"name":5,"license":14,"metadata":51,"description":7,"argument-hint":54},{"author":52,"version":53},"claudekit","1.1.0","[url or task]","main","fa3098ef56c24a44b365d9f1727c4c86b98dfd20",".opencode\u002Fskills\u002Fchrome-devtools","https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored","https:\u002F\u002Fgithub.com\u002Fdevmotminh","2026-05-04 12:54:25",{"source":8,"skillName":5,"commands":62,"prompt":72,"zipAvailable":73},[63,66,69],{"tool":64,"command":65},"npx","npx skills add devmotminh\u002Fplayscored --skill \"ck:chrome-devtools\"",{"tool":67,"command":68},"bunx","bunx skills add devmotminh\u002Fplayscored --skill \"ck:chrome-devtools\"",{"tool":70,"command":71},"pnpm","pnpm dlx skills add devmotminh\u002Fplayscored --skill \"ck:chrome-devtools\"","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002FSKILL.md",true,[75,81,85,89,95,99,103,107,111,115,119,123,127,131,135,139,143,147,151,155,159,163,167],{"path":76,"resourceType":77,"resourceTypeDesc":78,"sizeBytes":79,"sourceHtmlUrl":80},"references\u002Fcdp-domains.md","REFERENCE","参考文档",17812,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Freferences\u002Fcdp-domains.md",{"path":82,"resourceType":77,"resourceTypeDesc":78,"sizeBytes":83,"sourceHtmlUrl":84},"references\u002Fperformance-guide.md",21550,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Freferences\u002Fperformance-guide.md",{"path":86,"resourceType":77,"resourceTypeDesc":78,"sizeBytes":87,"sourceHtmlUrl":88},"references\u002Fpuppeteer-reference.md",19065,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Freferences\u002Fpuppeteer-reference.md",{"path":90,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":93,"sourceHtmlUrl":94},"scripts\u002F__tests__\u002Fselector.test.js","SCRIPT","脚本",6525,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002F__tests__\u002Fselector.test.js",{"path":96,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":97,"sourceHtmlUrl":98},"scripts\u002F.gitignore",12,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002F.gitignore",{"path":100,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":101,"sourceHtmlUrl":102},"scripts\u002Faria-snapshot.js",10309,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002Faria-snapshot.js",{"path":104,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":105,"sourceHtmlUrl":106},"scripts\u002Fclick.js",2425,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002Fclick.js",{"path":108,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":109,"sourceHtmlUrl":110},"scripts\u002Fconsole.js",1932,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002Fconsole.js",{"path":112,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":113,"sourceHtmlUrl":114},"scripts\u002Fevaluate.js",1274,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002Fevaluate.js",{"path":116,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":117,"sourceHtmlUrl":118},"scripts\u002Ffill.js",2090,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002Ffill.js",{"path":120,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":121,"sourceHtmlUrl":122},"scripts\u002Finject-auth.js",7421,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002Finject-auth.js",{"path":124,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":125,"sourceHtmlUrl":126},"scripts\u002Finstall-deps.sh",4371,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002Finstall-deps.sh",{"path":128,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":129,"sourceHtmlUrl":130},"scripts\u002Finstall.sh",2137,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002Finstall.sh",{"path":132,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":133,"sourceHtmlUrl":134},"scripts\u002Flib\u002Fbrowser.js",8043,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002Flib\u002Fbrowser.js",{"path":136,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":137,"sourceHtmlUrl":138},"scripts\u002Flib\u002Fselector.js",5422,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002Flib\u002Fselector.js",{"path":140,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":141,"sourceHtmlUrl":142},"scripts\u002Fnavigate.js",1355,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002Fnavigate.js",{"path":144,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":145,"sourceHtmlUrl":146},"scripts\u002Fnetwork.js",2913,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002Fnetwork.js",{"path":148,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":149,"sourceHtmlUrl":150},"scripts\u002Fpackage.json",345,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002Fpackage.json",{"path":152,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":153,"sourceHtmlUrl":154},"scripts\u002Fperformance.js",4061,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002Fperformance.js",{"path":156,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":157,"sourceHtmlUrl":158},"scripts\u002FREADME.md",7726,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002FREADME.md",{"path":160,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":161,"sourceHtmlUrl":162},"scripts\u002Fscreenshot.js",6379,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002Fscreenshot.js",{"path":164,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":165,"sourceHtmlUrl":166},"scripts\u002Fselect-ref.js",3910,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002Fselect-ref.js",{"path":168,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":169,"sourceHtmlUrl":170},"scripts\u002Fsnapshot.js",3704,"https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fchrome-devtools\u002Fscripts\u002Fsnapshot.js",[172,208,233,257,283,308],{"skillNo":173,"name":174,"nameZh":6,"description":175,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":176,"licenseFileUrl":6,"sourceHtmlUrl":177,"categories":178,"keywords":187,"publishedAt":46},"01M6KTQ1G3XCP03TVWRW3ZC12B","ckm:youtube-thumbnail-design","Design YouTube thumbnails with 17 styles, niche-specific guides, and CTR optimization. Generate complete thumbnails with text using Gemini Nano Banana Pro (4K text rendering). Actions: design, create, generate thumbnail. Niches: tech, gaming, education, cooking, fitness, business. Styles: facecam, before-after, listicle, diagram, whiteboard, bold-text, mystery, dark-dramatic. Features: AI generation with text baked in, brand identity, reference face, arrows, Google Font support.","MIT","https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fyoutube-thumbnail-design\u002FSKILL.md",[179,182],{"categoryNo":180,"categoryName":181,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":183,"categoryName":184,"taxonomyType":185,"taxonomyTypeDesc":186},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",[188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207],"design","youtube","thumbnail","ckm","ckm:youtube thumbnail design","ckm:youtube","diagram","create","generate","nano banana pro","actions","text","thumbnails","before-after","banana","ctr","niches","niche","guides","whiteboard",{"skillNo":209,"name":210,"nameZh":6,"description":211,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":176,"licenseFileUrl":6,"sourceHtmlUrl":212,"categories":213,"keywords":214,"publishedAt":46},"01M6KTPMRWPGHSCT8AAPDHKSZ1","ck:web-frameworks","Build modern full-stack web applications with Next.js (App Router, Server Components, RSC, PPR, SSR, SSG, ISR), Turborepo (monorepo management, task pipelines, remote caching, parallel execution), and RemixIcon (3100+ SVG icons in outlined\u002Ffilled styles). Use when creating React applications, implementing server-side rendering, setting up monorepos with multiple packages, optimizing build performance and caching strategies, adding icon libraries, managing shared dependencies, or working with TypeScript full-stack projects.","https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fweb-frameworks\u002FSKILL.md",[],[215,216,217,218,27,34,219,220,221,222,223,224,225,226,227,228,229,230,231,232],"web","web frameworks","frameworks","ck:web frameworks","components","react","libraries","projects","monorepo","router","up","caching","strategies","shared","app","remote","Server Components","implementing",{"skillNo":234,"name":235,"nameZh":6,"description":236,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":176,"licenseFileUrl":6,"sourceHtmlUrl":237,"categories":238,"keywords":241,"publishedAt":46},"01M6KTNK7R4AD3ZDHE4WXCSTQ1","ck:ui-styling","Create beautiful, accessible user interfaces with shadcn\u002Fui components (built on Radix UI + Tailwind), Tailwind CSS utility-first styling, and canvas-based visual designs. Use when building user interfaces, implementing design systems, creating responsive layouts, adding accessible components (dialogs, dropdowns, forms, tables), customizing themes and colors, implementing dark mode, generating visual designs and posters, or establishing consistent styling patterns across applications.","https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fui-styling\u002FSKILL.md",[239,240],{"categoryNo":180,"categoryName":181,"taxonomyType":20,"taxonomyTypeDesc":21},{"categoryNo":183,"categoryName":184,"taxonomyType":185,"taxonomyTypeDesc":186},[242,243,244,245,27,188,246,247,219,248,195,249,250,251,252,253,254,255,256,232],"ui styling","ui","styling","ck:ui styling","css","canvas","component","design systems","Tailwind","forms","across","layout","themes","utility","mode",{"skillNo":258,"name":259,"nameZh":6,"description":260,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":176,"licenseFileUrl":6,"sourceHtmlUrl":261,"categories":262,"keywords":266,"publishedAt":46},"01M6KTND8TD6D7C273Q99VVQNQ","ck:threejs","Build 3D web apps with Three.js (WebGL\u002FWebGPU). 556 searchable examples, 60 API classes, 20 use cases. Actions: create 3D scene, load model, add animation, implement physics, build VR\u002FXR. Topics: GLTF loader, PBR materials, particle effects, shadows, post-processing, compute shaders, TSL. Integrations: WebGPU, physics engines, spatial audio.","https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fthreejs\u002FSKILL.md",[263],{"categoryNo":264,"categoryName":265,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000010","后端与接口",[267,259,27,268,195,269,198,270,271,272,273,274,275,276,277,278,279,280,281,282],"threejs","webgpu","shaders","api","Animation","3D","Audio","model","integrations","physics","apps","add","processing","post-processing","vr","effects",{"skillNo":284,"name":285,"nameZh":6,"description":286,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":176,"licenseFileUrl":6,"sourceHtmlUrl":287,"categories":288,"keywords":289,"publishedAt":46},"01M6KTM3HB7WWZRW64HH35G6TN","ck:sequential-thinking","Apply structured, reflective problem-solving for complex tasks requiring multi-step analysis, revision capability, and hypothesis verification. Use for complex problem decomposition, adaptive planning, analysis needing course correction, problems with unclear scope, multi-step solutions, and hypothesis-driven work.","https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fsequential-thinking\u002FSKILL.md",[],[290,291,292,27,293,294,295,39,296,297,298,299,300,301,302,303,304,305,306,307],"sequential thinking","thinking","ck:sequential thinking","tasks","planning","verification","analyze","work","use","problem-solving","scope","problem","multi","with","course","for","adaptive","apply",{"skillNo":309,"name":310,"nameZh":6,"description":311,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":176,"licenseFileUrl":6,"sourceHtmlUrl":312,"categories":313,"keywords":314,"publishedAt":46},"01M6KTJ0QCSSY0ZGEKP99W3HKQ","ck:payment-integration","Integrate payments with SePay (VietQR), Polar (SaaS subscriptions), Stripe (global payments). Use for checkout, webhooks, QR codes, subscriptions, currency conversion, multi-provider order management, commission systems.","https:\u002F\u002Fgithub.com\u002Fdevmotminh\u002Fplayscored\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fpayment-integration\u002FSKILL.md",[],[315,316,317,318,27,319,320,298,321,322,323,324,325,326,327,302,303,328,305,329],"integration","payment integration","payment","ck:payment integration","payments","saas","conversion","provider","subscriptions","task","currency","checkout","codes","qr","order management"]