-
Notifications
You must be signed in to change notification settings - Fork 326
feat: Chrome Extension Enhancements & Documentation #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
creativerezz
wants to merge
6
commits into
aidenybai:main
from
creativerezz:feat/chrome-extension-v2
Closed
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
98ab647
feat(chrome-extension): add Chrome extension package for React Grab
creativerezz 419fac6
feat(chrome-extension): add visual previews (screenshots, thumbnails …
creativerezz 4a5caff
feat(chrome-extension): enhance popup with error handling, loading st…
creativerezz 881c044
Update README.md
creativerezz 2c2d50e
docs: Add LLM-specific project overview and architecture documentatio…
creativerezz 136ea55
feat: Add Chrome extension demo GIF and update README with extension …
creativerezz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| { | ||
| "permissions": { | ||
| "allow": [ | ||
| "Bash(pnpm install)", | ||
| "Bash(pnpm build:*)", | ||
| "Bash(chmod:*)", | ||
| "Bash(./scripts/generate-icons.sh:*)", | ||
| "Bash(cat:*)", | ||
| "Bash(pnpm add:*)", | ||
| "Bash(pnpm --filter react-grab build:*)", | ||
| "Bash(pnpm --filter chrome-extension build:*)" | ||
| ] | ||
| }, | ||
| "enableAllProjectMcpServers": true, | ||
| "enabledMcpjsonServers": [ | ||
| "shadcn", | ||
| "nuxt-ui", | ||
| "Better Auth", | ||
| "supabase" | ||
| ] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,171 @@ | ||
| # CLAUDE.md | ||
|
|
||
| This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. | ||
|
|
||
| ## Overview | ||
|
|
||
| React Grab is a developer tool that allows you to grab any element in your React app and provide it to AI coding assistants (Cursor, Claude Code, etc.) by holding ⌘C (or Ctrl+C) and clicking elements. The library captures HTML snippets and React component ownership stacks to provide rich context. | ||
|
|
||
| ## Monorepo Structure | ||
|
|
||
| This is a pnpm workspace monorepo with three packages: | ||
|
|
||
| - **`packages/react-grab`**: Main library package (TypeScript) | ||
| - Core instrumentation logic in `src/instrumentation.ts` - captures component stacks and HTML snippets | ||
| - Overlay UI in `src/overlay.ts` - visual feedback when hovering/selecting elements | ||
| - Hotkey tracking in `src/hotkeys.ts` - keyboard event handling | ||
| - Adapters in `src/adapters.ts` - integration with external tools (e.g., Cursor) | ||
| - Vite plugin in `src/plugins/vite.ts` - automatic script injection for Vite projects | ||
|
|
||
| - **`packages/kitchen-sink`**: Demo/testing application using Vite + React 19 | ||
| - Used to manually test react-grab functionality during development | ||
|
|
||
| - **`packages/website`**: Documentation website built with Next.js 16 App Router | ||
| - Marketing site and installation instructions | ||
| - Uses Tailwind CSS v4 and Framer Motion | ||
|
|
||
| ## Development Commands | ||
|
|
||
| **Build the main library:** | ||
| ```bash | ||
| pnpm build | ||
| ``` | ||
|
|
||
| **Watch mode (rebuilds on file changes):** | ||
| ```bash | ||
| pnpm dev | ||
| ``` | ||
|
|
||
| **Linting:** | ||
| ```bash | ||
| pnpm lint # Check for issues | ||
| pnpm lint:fix # Auto-fix issues | ||
| ``` | ||
|
|
||
| **Formatting:** | ||
| ```bash | ||
| pnpm format # Format all files with Prettier | ||
| pnpm check # Run both linting and format check | ||
| ``` | ||
|
|
||
| **Testing changes:** | ||
| ```bash | ||
| cd packages/kitchen-sink | ||
| pnpm dev # Start Vite dev server | ||
| # Then hold ⌘C and click elements to test functionality | ||
| ``` | ||
|
|
||
| **Run single package commands:** | ||
| ```bash | ||
| pnpm --filter react-grab build | ||
| pnpm --filter kitchen-sink dev | ||
| pnpm --filter website dev | ||
| ``` | ||
|
|
||
| ## Build System | ||
|
|
||
| The main library uses `tsup` for bundling (config: `packages/react-grab/tsup.config.ts`): | ||
|
|
||
| 1. **IIFE build** (`dist/index.global.js`): Browser-ready script tag version with global `ReactGrab` namespace | ||
| 2. **ESM/CJS builds** (`dist/index.js`, `dist/index.cjs`): For npm package consumers | ||
| 3. **Vite plugin build** (`dist/plugins/vite.js`, `dist/plugins/vite.cjs`): Separate entry point for Vite integration | ||
|
|
||
| The library automatically initializes when loaded via script tag by reading `data-*` attributes from the script element. | ||
|
|
||
| ## Code Architecture | ||
|
|
||
| **Key Flow:** | ||
| 1. User holds activation hotkey (default: ⌘C) | ||
| 2. Progress indicator shows key hold duration (default: 500ms) | ||
| 3. When threshold reached, overlay mode activates | ||
| 4. Mouse movement tracked to identify element under cursor (excluding react-grab's own overlay elements) | ||
| 5. Selection overlay highlights hovered element with visual feedback | ||
| 6. On click, captures: | ||
| - HTML snippet of element (via `getHTMLSnippet`) | ||
| - React component ownership stack (via `getStack` using React DevTools internals) | ||
| - Filters and serializes stack for clarity | ||
| 7. Copies formatted text to clipboard wrapped in `<referenced_element>` tags | ||
| 8. If adapter configured, opens in external tool (e.g., Cursor composer) | ||
|
|
||
| **State Management:** | ||
| - Custom store implementation in `src/utils/store.ts` with subscription support | ||
| - Global `libStore` tracks: pressed keys, mouse position, overlay mode (hidden/visible/copying) | ||
|
|
||
| **Performance Optimizations:** | ||
| - RequestAnimationFrame-based rendering to batch DOM updates | ||
| - Throttled mouse move handling to avoid excessive updates | ||
| - Element visibility checks before selection (filters invisible elements) | ||
| - Continuous render loop only updates when state changes | ||
|
|
||
| ## Code Style Guidelines | ||
|
|
||
| **From `.cursor/rules/codebase-guidelines.mdc`:** | ||
|
|
||
| - Use **TypeScript interfaces** over types | ||
| - Use **arrow functions** over function declarations | ||
| - Use **kebab-case** for filenames | ||
| - Use **descriptive variable names** (avoid abbreviations like `x`, prefer `innerElement`) | ||
| - Remove unused code and avoid repetition | ||
| - Only add comments when absolutely necessary | ||
| - Prefix hacks with `// HACK: reason for hack` | ||
| - Keep interfaces/types at global scope | ||
| - React component layout: Props interface first, then named arrow function export | ||
| - Avoid type casting ("as") unless absolutely necessary | ||
| - Move inline SVGs to `icon-NAME.tsx` files with component name `IconNAME` | ||
|
|
||
| **Example:** | ||
| ```typescript | ||
| interface UserPreferences { | ||
| enableOverlay: boolean; | ||
| hotkey: string; | ||
| } | ||
|
|
||
| const getUserPreferences = (): UserPreferences => { | ||
| // Implementation | ||
| }; | ||
| ``` | ||
|
|
||
| ## Release Process | ||
|
|
||
| Uses [Changesets](https://github.com/changesets/changesets) for version management: | ||
|
|
||
| 1. Create a changeset when making changes affecting the public API: | ||
| ```bash | ||
| pnpm changeset | ||
| ``` | ||
|
|
||
| 2. Follow prompts to describe changes (patch/minor/major) | ||
| 3. Commit the generated changeset file | ||
| 4. Maintainers will handle versioning and publishing: | ||
| ```bash | ||
| pnpm version # Bumps versions based on changesets | ||
| pnpm release # Builds and publishes to npm | ||
| ``` | ||
|
|
||
| ## Requirements | ||
|
|
||
| - **Node.js**: v18 or higher | ||
| - **pnpm**: v8 or higher (enforced via engines in package.json) | ||
|
|
||
| ## Testing Strategy | ||
|
|
||
| No automated unit tests currently. Testing is done manually via the kitchen-sink demo: | ||
|
|
||
| 1. Start kitchen-sink dev server | ||
| 2. Hold ⌘C (or Ctrl+C on Windows/Linux) for 500ms | ||
| 3. Click various elements to verify: | ||
| - Overlay positioning and styling | ||
| - HTML snippet capture | ||
| - Component stack extraction | ||
| - Clipboard copying | ||
| - External adapter integration (if configured) | ||
| 4. Test across multiple browsers: Chrome, Firefox, Safari | ||
| 5. Test edge cases: deeply nested components, elements with transforms, scrolled containers | ||
|
|
||
| ## Common Gotchas | ||
|
|
||
| - The library uses React DevTools internals (via `bippy` package) to extract component stacks - this is fragile and may break with React updates | ||
| - Overlay positioning respects element transforms and border radius by reading computed styles | ||
| - Script tag must be in `<head>` with `strategy="beforeInteractive"` for Next.js to ensure it loads before React hydration | ||
| - Vite plugin only applies in development mode (`apply: "serve"`) | ||
| - Elements with `data-react-grab-ignore` attribute (using `ATTRIBUTE_NAME` constant) are excluded from selection |
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same in relation to my comment above. I would remove this too if you're hoping for anything to get merged. I'm not a maintainer. Just a passerby. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| # React Grab - Agentic LLM Guide | ||
|
|
||
| This file provides context and instructions for AI agents working on the React Grab codebase. | ||
|
|
||
| ## Project Overview | ||
| React Grab is a developer tool that allows users to "grab" elements in a React app to capture their HTML and component stack for use with AI coding assistants. | ||
|
|
||
| ## Monorepo Structure | ||
| The project is a **pnpm workspace** monorepo. | ||
|
|
||
| - **`packages/react-grab`**: The core library. | ||
| - `src/instrumentation.ts`: Core logic for capturing component stacks. | ||
| - `src/overlay.ts`: UI overlay for element selection. | ||
| - `src/hotkeys.ts`: Keyboard event handling. | ||
| - `src/plugins/vite.ts`: Vite plugin implementation. | ||
| - **`packages/kitchen-sink`**: Demo/testing application (Vite + React 19). | ||
| - **`packages/website`**: Documentation site (Next.js 16). | ||
|
|
||
| ## Development Commands | ||
| Run these from the root directory: | ||
|
|
||
| - **Build**: `pnpm build` (Builds all packages) | ||
| - **Dev (Watch)**: `pnpm dev` (Rebuilds on change) | ||
| - **Lint**: `pnpm lint` / `pnpm lint:fix` | ||
| - **Format**: `pnpm format` | ||
| - **Test**: No automated unit tests. Use `packages/kitchen-sink` for manual verification. | ||
| - `cd packages/kitchen-sink && pnpm dev` | ||
| - Hold `Cmd+C` and click elements to test. | ||
|
|
||
| ## Code Style Guidelines | ||
| - **Language**: TypeScript (use interfaces, not types). | ||
| - **Functions**: Arrow functions preferred. | ||
| - **Naming**: Kebab-case for filenames. Descriptive variable names. | ||
| - **Components**: Props interface first, then named export. | ||
| - **Icons**: Move inline SVGs to `icon-NAME.tsx`. | ||
|
|
||
| ## Key Architecture Notes | ||
| - **Instrumentation**: Uses `bippy` (React DevTools internals) to extract component stacks. | ||
| - **Overlay**: Renders a visual overlay over the DOM using `requestAnimationFrame`. | ||
| - **State**: Custom store in `src/utils/store.ts`. | ||
|
|
||
| ### React Internals Access (IMPORTANT) | ||
|
|
||
| React Grab relies on **React's internal fiber tree** to map DOM elements back to their React components. This is accessed via the `bippy` library. | ||
|
|
||
| **What is React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED?** | ||
| - React's **intentionally scary-named** internal API exposing the fiber tree | ||
| - The name is a warning: "This is unstable and subject to change without notice" | ||
| - Not a public API = no semver guarantees | ||
|
|
||
| **How React Grab Uses It:** | ||
| ```typescript | ||
| // packages/react-grab/src/instrumentation.ts | ||
| import { _fiberRoots, getFiberFromHostInstance, instrument } from "bippy"; | ||
| ``` | ||
|
|
||
| **Why bippy?** | ||
| - Abstracts direct access to React internals | ||
| - Handles fiber tree traversal safely | ||
| - Provides utilities for: | ||
| - Finding which component "owns" a DOM element | ||
| - Building component hierarchy (Parent → Child → GrandChild) | ||
| - Source mapping (file + line number) | ||
|
|
||
| **The Flow:** | ||
| ``` | ||
| User clicks element | ||
| ↓ | ||
| getFiberFromHostInstance(element) | ||
| ↓ | ||
| bippy → React internals | ||
| ↓ | ||
| Fiber node retrieved | ||
| ↓ | ||
| Walk fiber tree for component stack | ||
| ↓ | ||
| "Button → Form → LoginPage" | ||
| ``` | ||
|
|
||
| **⚠️ IMPORTANT LIMITATION:** | ||
| This approach is **fragile**. React can change its internal structure at any time since it's not a public API. Updates to React may break `bippy` until it's updated. Always test with new React versions. | ||
|
|
||
| ## Release Process | ||
| - Uses **Changesets**. | ||
| - Run `pnpm changeset` to generate a version bump for public API changes. | ||
|
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey! You shouldn't commit your
settings.local.jsonfile.I recommend creating a global
~/.gitignorefile to catch theCLAUDE.local.mdandsettings.local.jsonfiles.Typically the versions without
*.local*are the ones committed in a repository if that is the standard for that particular repo.