一键导入
userscripts
Use when writing Tampermonkey/Violentmonkey/Greasemonkey userscripts, modifying website behavior or appearance, or working with .user.js files.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when writing Tampermonkey/Violentmonkey/Greasemonkey userscripts, modifying website behavior or appearance, or working with .user.js files.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when the user wants to create a new pull request, update an existing PR's body, open a draft PR, or preview a PR body locally before pushing.
Use when executing implementation plans with independent tasks in the current Pi session using fresh subagents and review loops
Create a new Pi task folder for a specific task or feature development. Use when the user wants to start a new task, plan a feature, or asks to create a task file.
You MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.
Use when you have a written implementation plan to execute with review checkpoints
Use when you have an approved design or requirements for a multi-step task, before touching code
| name | userscripts |
| description | Use when writing Tampermonkey/Violentmonkey/Greasemonkey userscripts, modifying website behavior or appearance, or working with .user.js files. |
Guide for writing Tampermonkey/Violentmonkey userscripts.
Ask one at a time:
https://example.com/*).user.js fileOption A: Fetch URL directly (try first for public sites)
Option B: User provides MHTML/HTML file
class=, data-, id=, -- (CSS variables)data-testid, data-*, semantic IDs over generated class namesOption C: User provides selectors
@run-at timing based on task type@grant level (start with none)// ==UserScript==
// @name Script Name
// @namespace your-namespace
// @version 0.0.1
// @description Brief description
// @icon https://www.google.com/s2/favicons?sz=64&domain=example.com
// @homepage https://github.com/username/repo
// @match https://example.com/*
// @exclude https://example.com/admin/*
// @author Author Name
// @run-at document-end
// @noframes
// @grant none
// ==/UserScript==
// ==UserScript==
// @name Site Name - Custom Styles
// @namespace your-namespace
// @version 0.0.1
// @description Override styles on example.com
// @icon https://www.google.com/s2/favicons?sz=64&domain=example.com
// @match https://example.com/*
// @author Your Name
// @run-at document-start
// @grant none
// ==/UserScript==
;(() => {
'use strict'
const style = document.createElement('style')
style.textContent = `
/* Hide element */
.annoying-banner {
display: none !important;
}
/* Override CSS variable */
:root {
--site-font: -apple-system, BlinkMacSystemFont, system-ui, sans-serif !important;
}
`
document.documentElement.appendChild(style)
})()
// ==UserScript==
// @name Site Name - DOM Tweaks
// @namespace your-namespace
// @version 0.0.1
// @description Modify DOM on example.com
// @icon https://www.google.com/s2/favicons?sz=64&domain=example.com
// @match https://example.com/*
// @author Your Name
// @run-at document-end
// @noframes
// @grant none
// ==/UserScript==
;(() => {
'use strict'
// Remove elements
document.querySelectorAll('.unwanted').forEach(el => el.remove())
// Modify elements
document.querySelectorAll('a.external').forEach(link => {
link.setAttribute('target', '_blank')
})
// Add keyboard shortcut
document.addEventListener('keydown', e => {
if (e.target.matches('input, textarea, [contenteditable]')) return
if (e.key === 'j' && !e.ctrlKey && !e.metaKey && !e.altKey) {
e.preventDefault()
// action here
}
})
})()
// ==UserScript==
// @name Site Name - Dynamic Handler
// @namespace your-namespace
// @version 0.0.1
// @description Handle dynamically loaded content on example.com
// @icon https://www.google.com/s2/favicons?sz=64&domain=example.com
// @match https://example.com/*
// @author Your Name
// @run-at document-end
// @noframes
// @grant none
// ==/UserScript==
;(() => {
'use strict'
const processElement = el => {
// modify element
}
// Process existing elements
document.querySelectorAll('.target').forEach(processElement)
// Watch for new elements
const observer = new MutationObserver(mutations => {
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (node.nodeType !== Node.ELEMENT_NODE) continue
if (node.matches('.target')) processElement(node)
node.querySelectorAll?.('.target').forEach(processElement)
}
}
})
observer.observe(document.body, { childList: true, subtree: true })
})()
| Value | Use Case |
|---|---|
document-start | CSS injection, intercept before render |
document-end | DOM manipulation (DOM ready, images loading) |
document-idle | Non-critical, after page fully loads |
| Value | When to Use |
|---|---|
none | Simple scripts, no sandbox, direct page access |
GM_addStyle | CSS injection helper function |
GM_getValue / GM_setValue | Persistent storage across sessions |
GM_xmlhttpRequest | Cross-origin requests (also needs @connect) |
GM_registerMenuCommand | Add items to extension popup menu |
GM_setClipboard | Copy to clipboard |
unsafeWindow | Access page's JavaScript context |
// @run-at document-start
// @grant none
const style = document.createElement('style')
style.textContent = `
.selector {
display: none !important;
}
`
document.documentElement.appendChild(style)
// @run-at document-start
const style = document.createElement('style')
style.textContent = `
:root {
--custom-property: value !important;
}
`
document.documentElement.appendChild(style)
// @run-at document-end
document.querySelectorAll('.selector').forEach(el => {
el.style.display = 'none'
})
// @run-at document-end
document.addEventListener('keydown', e => {
// Skip if typing in input/textarea
if (e.target.matches('input, textarea, [contenteditable]')) return
if (e.key === 'j' && !e.ctrlKey && !e.metaKey && !e.altKey) {
e.preventDefault()
// action here
}
})
// @run-at document-end
const observer = new MutationObserver(mutations => {
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (node.matches?.('.target-selector')) {
// handle new element
}
}
}
})
observer.observe(document.body, { childList: true, subtree: true })
// @grant GM_addStyle
GM_addStyle(`
.selector {
display: none !important;
}
`)
See @references/advanced-patterns.md for full implementations:
| Pattern | Use Case |
|---|---|
| Wait for element | Poll with requestAnimationFrame until element exists |
| isTyping helper | Skip shortcuts when user is in input/textarea |
| Scroll with offset | Smooth scroll accounting for fixed headers |
| Dark mode | CSS media query, meta tag, or CSS variables |
| URL parsing | Extract domain/path with new URL() |
| GM_addElement | Programmatic element creation |
| SPA navigation | Handle YouTube events, History API |
| Debug logging | Toggleable console output |
| Focus management | Track selection with keyboard nav |
| TreeWalker | Iterate text nodes for search/highlight |
| CSS Highlight API | Highlight without DOM modification |
| Canvas overlay | Draw scroll position markers |
Prefer (stable):
data-testid="value" - test IDs rarely changedata-* attributes - semantic, intentional#main-content, #sidebarbutton[role="tab"]Avoid (fragile):
.css-1a2b3c, .sc-abc123div > div > div > span:nth-child(3)document.querySelectorAll('.selector')document-idle or MutationObserver!important to override site styles@references/api-reference.md - All metadata headers, @match patterns, GM_* functions@references/advanced-patterns.md - SPA handling, dark mode, scroll markers, TreeWalker, etc.