react-grab by supercent-io/skills-template
npx skills add https://github.com/supercent-io/skills-template --skill react-grab关键词 :
react-grab·grab·element context·copy component to ai指向浏览器中的任意 UI 元素,按下 Cmd/Ctrl+C,即可立即将其 React 组件名称、源文件路径和 HTML 标记复制到剪贴板 —— 随时供您的 AI 编码代理使用。
getElementContext、freeze)进行自动化或测试工具开发广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
bash scripts/install.sh(或 npx -y grab@latest init)以在您的项目中安装 react-grabbash scripts/add-agent.sh mcp 以启用 MCP 工具访问,用于编程式使用有关详细的 API 和特定框架的设置,请参阅 references/api.md。
# 1. 启动您的应用
npm run dev
# 2. 在浏览器中将鼠标悬停在一个按钮上
# 3. 按下 Cmd+C(Mac)或 Ctrl+C(Win/Linux)
# 剪贴板现在包含:
#
# in LoginForm at components/login-form.tsx:46:19
#
# <button class="btn-primary" type="submit">
# Log in
# </button>
# 4. 粘贴到 Claude Code 中 —— 它确切地知道组件位于何处
# 安装 react-grab MCP 服务器
npx -y grab@latest add mcp
# 您的 AI 代理现在可以调用 get_element_context MCP 工具
# 以在您在浏览器中选择元素后接收其上下文
import { registerPlugin } from "react-grab";
registerPlugin({
name: "open-in-figma",
actions: [{
id: "figma",
label: "Find in Figma",
shortcut: "F",
onAction: (ctx) => {
window.open(`figma://search?q=${ctx.componentName}`);
},
}],
});
# 一条命令 —— 自动检测您的框架并安装所有内容
npx -y grab@latest init
# 添加 MCP 服务器以支持编程式 AI 代理访问
npx -y grab@latest add mcp
# 添加到特定的 AI 代理
npx -y grab@latest add claude-code
安装后,在开发过程中将鼠标悬停在浏览器中的任意元素上并按下:
Cmd+CCtrl+C输出复制到剪贴板:
in LoginForm at components/login-form.tsx:46:19
<a class="ml-auto text-sm underline-offset-4 hover:underline">
Forgot your password?
</a>
直接粘贴到您的 AI 编码代理提示中 —— 无需搜索文件。
npx -y grab@latest init
自动检测您的框架(Next.js App Router / Pages Router / Vite / TanStack Start / Webpack)和包管理器(npm / yarn / pnpm / bun)。
Next.js App Router (app/layout.tsx):
import Script from 'next/script'
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
{process.env.NODE_ENV === "development" && (
<Script
src="//unpkg.com/react-grab/dist/index.global.js"
crossOrigin="anonymous"
strategy="beforeInteractive"
/>
)}
</body>
</html>
)
}
Next.js Pages Router (pages/_document.tsx):
import Script from 'next/script'
// Inside _document component:
{process.env.NODE_ENV === "development" && (
<Script
src="//unpkg.com/react-grab/dist/index.global.js"
crossOrigin="anonymous"
strategy="beforeInteractive"
/>
)}
Vite (index.html):
<script type="module">
if (import.meta.env.DEV) {
await import('//unpkg.com/react-grab/dist/index.global.js');
}
</script>
Webpack(入口文件):
if (process.env.NODE_ENV === 'development') {
import('react-grab');
}
包安装(用于编程式使用):
npm install react-grab
# or: pnpm add react-grab | yarn add react-grab | bun add react-grab
# 自动检测框架并安装
bash scripts/install.sh
# 为特定框架安装
bash scripts/install.sh --framework next-app
# 添加到特定的 AI 代理
bash scripts/add-agent.sh claude-code
bash scripts/add-agent.sh cursor
bash scripts/add-agent.sh mcp
在开发模式下:
输出格式:
in <ComponentName> at <file-path>:<line>:<col>
<element-html>
当 react-grab 激活时,一个可拖动的工具栏会出现在浏览器角落:
点击并拖动以选择多个元素,一次性捕获它们的所有上下文。每个元素的组件堆栈和 HTML 都会包含在剪贴板输出中。
import { getGlobalApi } from "react-grab";
const api = getGlobalApi();
// 激活覆盖层
api.activate(); // 显示覆盖层
api.deactivate(); // 隐藏覆盖层
api.toggle(); // 切换
// 将元素的上下文复制到剪贴板
await api.copyElement(document.querySelector('.my-button'));
// 获取源信息而不复制
const source = await api.getSource(element);
console.log(source.filePath); // "src/components/Button.tsx"
console.log(source.lineNumber); // 42
console.log(source.componentName); // "Button"
// 获取完整的堆栈上下文字符串
const stack = await api.getStackContext(element);
// "in Button (at Button.tsx:42:5)\n in Card (at Card.tsx:10:3)"
// 检查当前状态
const state = api.getState();
// { isActive, isDragging, isCopying, targetElement, ... }
不使用默认的覆盖层 UI —— 用于自动化、测试工具或自定义集成:
import { getElementContext, freeze, unfreeze, openFile } from "react-grab/primitives";
// or: import { getElementContext } from "react-grab/core";
const button = document.querySelector('.submit-btn');
// 冻结页面状态(暂停 React 更新、CSS 动画,保留 :hover/:focus 状态)
freeze();
// 获取元素的所有上下文
const context = await getElementContext(button);
console.log(context.componentName); // "SubmitButton"
console.log(context.selector); // "button.submit-btn"
console.log(context.stackString); // "in SubmitButton (at Button.tsx:12:5)"
console.log(context.htmlPreview); // "<button class=\"submit-btn\">Submit</button>"
console.log(context.styles); // 相关的计算后 CSS
unfreeze(); // 恢复正常的页面行为
// 在编辑器中打开源文件
await openFile("/src/components/Button.tsx", 12);
react-grab 附带一个 MCP 服务器(@react-grab/mcp),用于编程式 AI 代理访问:
# 添加 MCP 服务器
npx -y grab@latest add mcp
MCP 服务器公开了一个 get_element_context 工具,该工具返回浏览器覆盖层中最近选择的元素。您的 AI 代理调用此工具以接收您在浏览器中选择的上下文。
流程:
get_element_context MCP 工具将 react-grab 添加到您特定的 AI 编码代理:
npx -y grab@latest add claude-code # Claude Code
npx -y grab@latest add cursor # Cursor
npx -y grab@latest add copilot # GitHub Copilot
npx -y grab@latest add codex # OpenAI Codex
npx -y grab@latest add gemini # Google Gemini CLI
npx -y grab@latest add opencode # OpenCode
npx -y grab@latest add amp # Amp
npx -y grab@latest add droid # Droid
移除集成:
npx -y grab@latest remove cursor
通过自定义上下文菜单操作、工具栏按钮和生命周期钩子扩展 react-grab:
import { registerPlugin } from "react-grab";
registerPlugin({
name: "send-to-jira",
hooks: {
// 向剪贴板内容添加注释
transformCopyContent: async (content, elements) => {
return content + "\n// Sent from react-grab";
},
// 自定义文件打开行为
onOpenFile: (filePath, lineNumber) => {
// 如果已处理则返回 true;返回 false 以使用默认行为
return false;
},
},
actions: [
{
id: "jira-action",
label: "Create Jira Ticket",
shortcut: "J",
onAction: async (context) => {
await createJiraTicket({
filePath: context.filePath,
componentName: context.componentName,
html: context.element.outerHTML,
});
context.hideContextMenu();
},
},
{
id: "toolbar-inspect",
label: "Inspect",
target: "toolbar", // 放置在工具栏中而非上下文菜单
onAction: () => {
console.log("Inspect triggered");
},
},
],
theme: {
hue: 200, // 更改覆盖层颜色(0-360 HSL)
crosshair: { enabled: false }, // 禁用十字准线覆盖层
},
});
hooks: {
onActivate?: () => void
onDeactivate?: () => void
onElementHover?: (element: Element) => void
onElementSelect?: (element: Element) => boolean | void // 返回 true 以取消默认操作
onBeforeCopy?: (elements: Element[]) => void
transformCopyContent?: (content: string, elements: Element[]) => string | Promise<string>
onAfterCopy?: (elements: Element[], success: boolean) => void
onOpenFile?: (filePath: string, lineNumber?: number) => boolean | void
transformHtmlContent?: (html: string, elements: Element[]) => string | Promise<string>
transformAgentContext?: (ctx: AgentContext, elements: Element[]) => AgentContext
transformSnippet?: (snippet: string, element: Element) => string | Promise<string>
}
grab [command] [options]
Commands:
init Auto-detect project and install react-grab
add Connect react-grab to an AI coding agent (alias: install)
remove Disconnect from an AI coding agent
configure Configure options (activation key, context lines, etc.)
Options:
-y, --yes Skip confirmation prompts
-c, --cwd Working directory (default: process.cwd())
-v, --version Display version
-h, --help Display help
将选项传递给 init() 以进行编程式控制(当不使用 CDN 脚本时):
import { init } from "react-grab";
init({
enabled: true, // 完全启用/禁用
activationMode: "toggle", // "toggle" | "hold"
activationKey: "c", // 要按下的键(与 Cmd/Ctrl 组合)
maxContextLines: 10, // 限制 React 组件堆栈深度
freezeReactUpdates: true, // 激活时暂停 React 状态更新
getContent: async (elements) => { // 自定义剪贴板内容格式化器
const contexts = await generateSnippet(elements);
return contexts.join("\n---\n");
},
});
完全禁用(在脚本加载之前):
window.__REACT_GRAB_DISABLED__ = true;
NODE_ENV === "development" 或 import.meta.env.DEV 中。init 命令:npx -y grab@latest init 处理框架检测 —— 除非需要,否则不要手动添加脚本标签。grab add mcp 添加 MCP 服务器,以便代理可以在不依赖剪贴板的情况下拉取上下文。freeze()。| 问题 | 解决方案 |
|---|---|
| 覆盖层未出现 | 检查 NODE_ENV === "development" 包装;检查 window.__REACT_GRAB_DISABLED__ 是否未设置 |
组件名称显示为 null | 确保 react-grab 脚本在 React 渲染之前加载(在 Next.js 中使用 strategy="beforeInteractive") |
| 文件路径缺失 | 需要启用 React 源映射(仅开发模式;非压缩构建) |
| MCP 工具返回空 | 您需要先在浏览器中选择一个元素,然后再调用 get_element_context |
grab init 失败 | 检查 Node.js >=18 和包管理器(npm/pnpm/yarn/bun)是否已安装 |
install.sh(项目设置) · add-agent.sh(代理集成)每周安装量
343
代码仓库
GitHub 星标数
88
首次出现
2026年3月12日
安全审计
安装于
gemini-cli304
codex297
opencode288
github-copilot285
cursor285
kimi-cli284
Keyword :
react-grab·grab·element context·copy component to aiPoint at any UI element in your browser, press Cmd/Ctrl+C, and instantly copy its React component name, source file path, and HTML markup to clipboard — ready for your AI coding agent.
getElementContext, freeze) for automation or test toolingbash scripts/install.sh (or npx -y grab@latest init) to install react-grab in your projectbash scripts/add-agent.sh mcp to enable MCP tool access for programmatic useFor detailed API and framework-specific setup, see references/api.md.
# 1. Start your app
npm run dev
# 2. Hover over a button in the browser
# 3. Press Cmd+C (Mac) or Ctrl+C (Win/Linux)
# Clipboard now contains:
#
# in LoginForm at components/login-form.tsx:46:19
#
# <button class="btn-primary" type="submit">
# Log in
# </button>
# 4. Paste into Claude Code — it knows exactly where the component lives
# Install react-grab MCP server
npx -y grab@latest add mcp
# Your AI agent can now call the get_element_context MCP tool
# to receive element context after you select it in the browser
import { registerPlugin } from "react-grab";
registerPlugin({
name: "open-in-figma",
actions: [{
id: "figma",
label: "Find in Figma",
shortcut: "F",
onAction: (ctx) => {
window.open(`figma://search?q=${ctx.componentName}`);
},
}],
});
# One command — auto-detects your framework and installs everything
npx -y grab@latest init
# Add MCP server for programmatic AI agent access
npx -y grab@latest add mcp
# Add to a specific AI agent
npx -y grab@latest add claude-code
After installation, hover over any element in your browser during development and press:
Cmd+CCtrl+COutput copied to clipboard:
in LoginForm at components/login-form.tsx:46:19
<a class="ml-auto text-sm underline-offset-4 hover:underline">
Forgot your password?
</a>
Paste directly into your AI coding agent prompt — no file searching needed.
npx -y grab@latest init
Detects your framework (Next.js App Router / Pages Router / Vite / TanStack Start / Webpack) and package manager (npm / yarn / pnpm / bun) automatically.
Next.js App Router (app/layout.tsx):
import Script from 'next/script'
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
{process.env.NODE_ENV === "development" && (
<Script
src="//unpkg.com/react-grab/dist/index.global.js"
crossOrigin="anonymous"
strategy="beforeInteractive"
/>
)}
</body>
</html>
)
}
Next.js Pages Router (pages/_document.tsx):
import Script from 'next/script'
// Inside _document component:
{process.env.NODE_ENV === "development" && (
<Script
src="//unpkg.com/react-grab/dist/index.global.js"
crossOrigin="anonymous"
strategy="beforeInteractive"
/>
)}
Vite (index.html):
<script type="module">
if (import.meta.env.DEV) {
await import('//unpkg.com/react-grab/dist/index.global.js');
}
</script>
Webpack (entry file):
if (process.env.NODE_ENV === 'development') {
import('react-grab');
}
Package install (for programmatic use):
npm install react-grab
# or: pnpm add react-grab | yarn add react-grab | bun add react-grab
# Auto-detect framework and install
bash scripts/install.sh
# Install for a specific framework
bash scripts/install.sh --framework next-app
# Add to a specific AI agent
bash scripts/add-agent.sh claude-code
bash scripts/add-agent.sh cursor
bash scripts/add-agent.sh mcp
In development mode:
Output format:
in <ComponentName> at <file-path>:<line>:<col>
<element-html>
A draggable toolbar appears in the corner of your browser when react-grab is active:
Click and drag across multiple elements to capture all their contexts at once. Each element's component stack and HTML is included in the clipboard output.
import { getGlobalApi } from "react-grab";
const api = getGlobalApi();
// Activate the overlay
api.activate(); // show overlay
api.deactivate(); // hide overlay
api.toggle(); // toggle
// Copy an element's context to clipboard
await api.copyElement(document.querySelector('.my-button'));
// Get source info without copying
const source = await api.getSource(element);
console.log(source.filePath); // "src/components/Button.tsx"
console.log(source.lineNumber); // 42
console.log(source.componentName); // "Button"
// Get the full stack context string
const stack = await api.getStackContext(element);
// "in Button (at Button.tsx:42:5)\n in Card (at Card.tsx:10:3)"
// Check current state
const state = api.getState();
// { isActive, isDragging, isCopying, targetElement, ... }
Use without the default overlay UI — for automation, test tooling, or custom integrations:
import { getElementContext, freeze, unfreeze, openFile } from "react-grab/primitives";
// or: import { getElementContext } from "react-grab/core";
const button = document.querySelector('.submit-btn');
// Freeze page state (pause React updates, CSS animations, preserve :hover/:focus)
freeze();
// Get all context for an element
const context = await getElementContext(button);
console.log(context.componentName); // "SubmitButton"
console.log(context.selector); // "button.submit-btn"
console.log(context.stackString); // "in SubmitButton (at Button.tsx:12:5)"
console.log(context.htmlPreview); // "<button class=\"submit-btn\">Submit</button>"
console.log(context.styles); // Relevant computed CSS
unfreeze(); // Restore normal page behavior
// Open the source file in editor
await openFile("/src/components/Button.tsx", 12);
react-grab ships an MCP server (@react-grab/mcp) for programmatic AI agent access:
# Add MCP server
npx -y grab@latest add mcp
The MCP server exposes a get_element_context tool that returns the most recent element selection from the browser overlay. Your AI agent calls this tool to receive the context that you selected in the browser.
Flow:
get_element_context MCP toolAdd react-grab to your specific AI coding agent:
npx -y grab@latest add claude-code # Claude Code
npx -y grab@latest add cursor # Cursor
npx -y grab@latest add copilot # GitHub Copilot
npx -y grab@latest add codex # OpenAI Codex
npx -y grab@latest add gemini # Google Gemini CLI
npx -y grab@latest add opencode # OpenCode
npx -y grab@latest add amp # Amp
npx -y grab@latest add droid # Droid
Remove an integration:
npx -y grab@latest remove cursor
Extend react-grab with custom context menu actions, toolbar buttons, and lifecycle hooks:
import { registerPlugin } from "react-grab";
registerPlugin({
name: "send-to-jira",
hooks: {
// Add annotation to clipboard content
transformCopyContent: async (content, elements) => {
return content + "\n// Sent from react-grab";
},
// Custom file-open behavior
onOpenFile: (filePath, lineNumber) => {
// Return true if handled; false to use default behavior
return false;
},
},
actions: [
{
id: "jira-action",
label: "Create Jira Ticket",
shortcut: "J",
onAction: async (context) => {
await createJiraTicket({
filePath: context.filePath,
componentName: context.componentName,
html: context.element.outerHTML,
});
context.hideContextMenu();
},
},
{
id: "toolbar-inspect",
label: "Inspect",
target: "toolbar", // Places in toolbar instead of context menu
onAction: () => {
console.log("Inspect triggered");
},
},
],
theme: {
hue: 200, // Change overlay color (0-360 HSL)
crosshair: { enabled: false }, // Disable crosshair overlay
},
});
hooks: {
onActivate?: () => void
onDeactivate?: () => void
onElementHover?: (element: Element) => void
onElementSelect?: (element: Element) => boolean | void // return true to cancel default
onBeforeCopy?: (elements: Element[]) => void
transformCopyContent?: (content: string, elements: Element[]) => string | Promise<string>
onAfterCopy?: (elements: Element[], success: boolean) => void
onOpenFile?: (filePath: string, lineNumber?: number) => boolean | void
transformHtmlContent?: (html: string, elements: Element[]) => string | Promise<string>
transformAgentContext?: (ctx: AgentContext, elements: Element[]) => AgentContext
transformSnippet?: (snippet: string, element: Element) => string | Promise<string>
}
grab [command] [options]
Commands:
init Auto-detect project and install react-grab
add Connect react-grab to an AI coding agent (alias: install)
remove Disconnect from an AI coding agent
configure Configure options (activation key, context lines, etc.)
Options:
-y, --yes Skip confirmation prompts
-c, --cwd Working directory (default: process.cwd())
-v, --version Display version
-h, --help Display help
Pass options to init() for programmatic control (when not using the CDN script):
import { init } from "react-grab";
init({
enabled: true, // Enable/disable entirely
activationMode: "toggle", // "toggle" | "hold"
activationKey: "c", // Key to press (with Cmd/Ctrl)
maxContextLines: 10, // Limit React component stack depth
freezeReactUpdates: true, // Pause React state while active
getContent: async (elements) => { // Custom clipboard content formatter
const contexts = await generateSnippet(elements);
return contexts.join("\n---\n");
},
});
Disable entirely (before script loads):
window.__REACT_GRAB_DISABLED__ = true;
NODE_ENV === "development" or import.meta.env.DEV.init command: npx -y grab@latest init handles framework detection — don't manually add script tags unless needed.grab add mcp so agents can pull context without clipboard dependencies.freeze() from the primitives API when you need to inspect dynamic elements that disappear on hover.| Issue | Solution |
|---|---|
| Overlay not appearing | Check NODE_ENV === "development" wrapping; check window.__REACT_GRAB_DISABLED__ is not set |
Component name shows as null | Ensure react-grab script loads before React renders (use strategy="beforeInteractive" in Next.js) |
| File path missing | Requires React source maps enabled (dev mode only; not minified builds) |
| MCP tool returns empty | You need to select an element in the browser first before calling get_element_context |
install.sh (project setup) · add-agent.sh (agent integration)Weekly Installs
343
Repository
GitHub Stars
88
First Seen
Mar 12, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykWarn
Installed on
gemini-cli304
codex297
opencode288
github-copilot285
cursor285
kimi-cli284
AI Elements:基于shadcn/ui的AI原生应用组件库,快速构建对话界面
54,900 周安装
D1 Drizzle Schema:为Cloudflare D1生成正确ORM模式,避免SQLite差异错误
569 周安装
Monorepo 包链接指南:pnpm/npm/yarn/bun 工作区依赖管理详解
540 周安装
Sensei:GitHub Copilot for Azure技能合规性自动化改进工具
617 周安装
Google Apps Script 自动化脚本教程 - 免费实现 Google Sheets 与 Workspace 自动化
573 周安装
PowerPoint自动化生成工具:HTML转PPT,高保真布局与模板编辑工作流
558 周安装
AWS SDK Java 2.x DynamoDB 开发指南:增强客户端、事务与Spring Boot集成
332 周安装
grab init fails | Check Node.js >=18 and package manager (npm/pnpm/yarn/bun) is installed |