{"_id":"@andsam/shopify-grab","_rev":"3-8e25b13cba7e9f82eadf3340d55fb460","name":"@andsam/shopify-grab","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@andsam/shopify-grab","version":"0.1.0","keywords":["agent","context","grab","shopify","liquid","theme"],"license":"MIT","_id":"@andsam/shopify-grab@0.1.0","maintainers":[{"name":"sammyjoyce","email":"sam@andsam.co"}],"dist":{"shasum":"41cc247b3713bbc8a96483d27d211e3093b6558f","tarball":"https://registry.npmjs.org/@andsam/shopify-grab/-/shopify-grab-0.1.0.tgz","fileCount":17,"integrity":"sha512-PB0DJT5TM2ncfkGRMURfeeX5dMXug2UjCmJufXKuGRaoRpoujtsjch0MiiS/7Ov01hm9Fu0+wlDG13VY7VYnSA==","signatures":[{"sig":"MEUCIGSxG5urSqWpXM9leiuRKgtj5lcIw3wcNMLIidpHKlrKAiEAkDDSbnmQJvtzZvnEzJ5AabZk5oSxAtbvornO3KQQ6HM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":651118},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","browser":"dist/index.global.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./core":{"import":{"types":"./dist/core/index.d.ts","default":"./dist/core/index.js"},"require":{"types":"./dist/core/index.d.cts","default":"./dist/core/index.cjs"}},"./styles.css":"./dist/styles.css","./package.json":"./package.json","./dist/styles.css":"./dist/styles.css"},"gitHead":"1d97b4c8df8d2e0f697084a3a001bc6b6e2a33ee","scripts":{"dev":"concurrently \"pnpm:css:watch\" \"tsup --watch --ignore-watch dist\"","build":"NODE_ENV=production tsup","prebuild":"mkdir -p dist && tailwindcss -i ./src/styles.css -o ./dist/styles.css -m","css:build":"tailwindcss -i ./src/styles.css -o ./dist/styles.css -m","css:watch":"tailwindcss -i ./src/styles.css -o ./dist/styles.css -w"},"_npmUser":{"name":"sammyjoyce","email":"sam@andsam.co"},"_npmVersion":"11.8.0","description":"Select context for coding agents directly from your Shopify theme","directories":{},"_nodeVersion":"25.4.0","dependencies":{"solid-js":"^1.9.10"},"_hasShrinkwrap":false,"devDependencies":{"clsx":"^2.1.1","tsup":"^8.2.4","typescript":"^5.9.3","@babel/core":"^7.28.5","@types/node":"^20.19.23","tailwindcss":"^4.1.0","concurrently":"^9.1.2","tailwind-merge":"^2.5.5","@tailwindcss/cli":"^4.1.17","babel-preset-solid":"^1.9.10","esbuild-plugin-babel":"^0.2.3","@babel/preset-typescript":"^7.28.5"},"_npmOperationalInternal":{"tmp":"tmp/shopify-grab_0.1.0_1770008235648_0.6071051778128469","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@andsam/shopify-grab","version":"0.1.1","keywords":["agent","context","grab","shopify","liquid","theme"],"license":"MIT","_id":"@andsam/shopify-grab@0.1.1","maintainers":[{"name":"sammyjoyce","email":"sam@andsam.co"}],"homepage":"https://github.com/sammyjoyce/shopify-grab#readme","bugs":{"url":"https://github.com/sammyjoyce/shopify-grab/issues"},"dist":{"shasum":"8c1f0f13aa0572b9f09e32a8d978d3a9e46c47a9","tarball":"https://registry.npmjs.org/@andsam/shopify-grab/-/shopify-grab-0.1.1.tgz","fileCount":17,"integrity":"sha512-gQwo7KwMnRyqOmUGDbXWnbr/m/yRsw1exW+ZUux7qNdCAMIHtg7r1+iB+HtTZ4PxsHcnSjzCISe2RG7dDEExpQ==","signatures":[{"sig":"MEQCIA4zDN1R4dmhUwnO+rH6QZsGkeZUZBmYvgh5ckoQLkhCAiATiHCKFUIWxU4Xjn6JHOsqdIgWrrc3VjcLZazuL1XyXA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":699732},"main":"dist/index.js","type":"module","_from":"file:andsam-shopify-grab-0.1.1.tgz","types":"dist/index.d.ts","module":"dist/index.js","browser":"dist/index.global.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./core":{"import":{"types":"./dist/core/index.d.ts","default":"./dist/core/index.js"},"require":{"types":"./dist/core/index.d.cts","default":"./dist/core/index.cjs"}},"./styles.css":"./dist/styles.css","./package.json":"./package.json","./dist/styles.css":"./dist/styles.css"},"scripts":{"dev":"concurrently \"pnpm:css:watch\" \"tsup --watch --ignore-watch dist\"","build":"NODE_ENV=production tsup","prebuild":"mkdir -p dist && tailwindcss -i ./src/styles.css -o ./dist/styles.css -m","css:build":"tailwindcss -i ./src/styles.css -o ./dist/styles.css -m","css:watch":"tailwindcss -i ./src/styles.css -o ./dist/styles.css -w"},"_npmUser":{"name":"sammyjoyce","email":"sam@andsam.co"},"_resolved":"/tmp/aad4300403dbb72df341c7768843b26c/andsam-shopify-grab-0.1.1.tgz","_integrity":"sha512-gQwo7KwMnRyqOmUGDbXWnbr/m/yRsw1exW+ZUux7qNdCAMIHtg7r1+iB+HtTZ4PxsHcnSjzCISe2RG7dDEExpQ==","repository":{"url":"git+https://github.com/sammyjoyce/shopify-grab.git","type":"git"},"_npmVersion":"11.8.0","description":"Select context for coding agents directly from your Shopify theme","directories":{},"_nodeVersion":"25.4.0","dependencies":{"solid-js":"^1.9.10"},"_hasShrinkwrap":false,"devDependencies":{"clsx":"^2.1.1","tsup":"^8.2.4","typescript":"^5.9.3","@babel/core":"^7.28.5","@types/node":"^20.19.23","tailwindcss":"^4.1.0","concurrently":"^9.1.2","tailwind-merge":"^2.5.5","@tailwindcss/cli":"^4.1.17","babel-preset-solid":"^1.9.10","esbuild-plugin-babel":"^0.2.3","@babel/preset-typescript":"^7.28.5"},"_npmOperationalInternal":{"tmp":"tmp/shopify-grab_0.1.1_1770011841940_0.9677713717765632","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@andsam/shopify-grab","version":"0.2.0","description":"Select context for coding agents directly from your Shopify theme","keywords":["agent","context","grab","shopify","liquid","theme"],"license":"MIT","repository":{"type":"git","url":"git+https://github.com/sammyjoyce/shopify-grab.git"},"homepage":"https://github.com/sammyjoyce/shopify-grab#readme","bugs":{"url":"https://github.com/sammyjoyce/shopify-grab/issues"},"type":"module","main":"dist/index.js","module":"dist/index.js","browser":"dist/index.global.js","types":"dist/index.d.ts","exports":{"./package.json":"./package.json",".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./core":{"import":{"types":"./dist/core/index.d.ts","default":"./dist/core/index.js"},"require":{"types":"./dist/core/index.d.cts","default":"./dist/core/index.cjs"}},"./styles.css":"./dist/styles.css","./dist/styles.css":"./dist/styles.css"},"dependencies":{"solid-js":"^1.9.10"},"devDependencies":{"@babel/core":"^7.28.5","@babel/preset-typescript":"^7.28.5","@tailwindcss/cli":"^4.1.17","@types/node":"^20.19.23","babel-preset-solid":"^1.9.10","clsx":"^2.1.1","concurrently":"^9.1.2","esbuild-plugin-babel":"^0.2.3","tailwind-merge":"^2.5.5","tailwindcss":"^4.1.0","tsup":"^8.2.4","typescript":"^5.9.3"},"scripts":{"css:build":"tailwindcss -i ./src/styles.css -o ./dist/styles.css -m","css:watch":"tailwindcss -i ./src/styles.css -o ./dist/styles.css -w","prebuild":"mkdir -p dist && tailwindcss -i ./src/styles.css -o ./dist/styles.css -m","build":"NODE_ENV=production tsup","dev":"concurrently \"pnpm:css:watch\" \"tsup --watch --ignore-watch dist\""},"_id":"@andsam/shopify-grab@0.2.0","_integrity":"sha512-b/IL7zl241AdZGFooQkNGu189BeCxHCfEdRDYDC1i46kRto7YGjlsyb/cU7T2SX/dh9P8bW3bcwE3RB5wm80sA==","_resolved":"/tmp/185a274d3b9925a76f983c891acbeba4/andsam-shopify-grab-0.2.0.tgz","_from":"file:andsam-shopify-grab-0.2.0.tgz","_nodeVersion":"25.4.0","_npmVersion":"11.8.0","dist":{"integrity":"sha512-b/IL7zl241AdZGFooQkNGu189BeCxHCfEdRDYDC1i46kRto7YGjlsyb/cU7T2SX/dh9P8bW3bcwE3RB5wm80sA==","shasum":"0f7b945fac9c20e51899fd879db338af41fbb088","tarball":"https://registry.npmjs.org/@andsam/shopify-grab/-/shopify-grab-0.2.0.tgz","fileCount":17,"unpackedSize":700316,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHxpWsRa9qznSz6eBZUut7wxZwb3I9kDfBNIZqp1C/7TAiEAiVvjLYbTwu1Mf0A9TCvUyOFyW69hGYquBXKutI7vBbE="}]},"_npmUser":{"name":"sammyjoyce","email":"sam@andsam.co"},"directories":{},"maintainers":[{"name":"sammyjoyce","email":"sam@andsam.co"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/shopify-grab_0.2.0_1770012847635_0.6277807502664181"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-02T04:57:15.594Z","modified":"2026-02-02T06:14:07.975Z","0.1.0":"2026-02-02T04:57:15.818Z","0.1.1":"2026-02-02T05:57:22.134Z","0.2.0":"2026-02-02T06:14:07.833Z"},"bugs":{"url":"https://github.com/sammyjoyce/shopify-grab/issues"},"license":"MIT","homepage":"https://github.com/sammyjoyce/shopify-grab#readme","keywords":["agent","context","grab","shopify","liquid","theme"],"repository":{"type":"git","url":"git+https://github.com/sammyjoyce/shopify-grab.git"},"description":"Select context for coding agents directly from your Shopify theme","maintainers":[{"name":"sammyjoyce","email":"sam@andsam.co"}],"readme":"# Shopify Grab\n\nSelect context for coding agents directly from your Shopify theme.\n\nBased on [react-grab](https://github.com/aidenybai/react-grab) by Aiden Bai (MIT licensed), adapted for Shopify Liquid themes instead of React apps.\n\n## How it works\n\nPoint at any element on your Shopify store and press **Cmd+C** (Mac) or **Ctrl+C** (Windows/Linux) to copy the element's HTML, section type, block type, and file path context to your clipboard, ready to paste into your coding agent (Cursor, Claude Code, Copilot, etc.).\n\nExample output:\n\n```\n<div class=\"product-card\" data-section-id=\"template--123__featured-collection\">\n  Product Title\n  $29.99\n</div>\n  in section \"featured-collection\" (sections/featured-collection.liquid)\n  in block \"product\" [block-abc123]\n```\n\n## Install\n\n### Script tag (recommended for Shopify themes)\n\nAdd this to your `theme.liquid` layout file inside `<head>`:\n\n```liquid\n{% if request.design_mode or settings.enable_dev_tools %}\n  <script src=\"https://unpkg.com/@andsam/shopify-grab/dist/index.global.js\" crossorigin=\"anonymous\"></script>\n{% endif %}\n```\n\n### Snippet approach\n\nCreate a snippet `snippets/shopify-grab.liquid`:\n\n```liquid\n{% if request.design_mode %}\n  <script src=\"https://unpkg.com/@andsam/shopify-grab/dist/index.global.js\" crossorigin=\"anonymous\"></script>\n{% endif %}\n```\n\nThen render it in your layout: `{% render 'shopify-grab' %}`\n\n### Theme App Extension\n\nIf you're building a Shopify app, include the script in your theme app extension's block:\n\n```liquid\n<script src=\"https://unpkg.com/@andsam/shopify-grab/dist/index.global.js\" crossorigin=\"anonymous\"></script>\n```\n\n## Usage\n\nOnce installed, hover over any UI element and press:\n\n- **Cmd+C** on Mac\n- **Ctrl+C** on Windows/Linux\n\nThis copies the element's context to your clipboard, including:\n\n- **HTML preview** of the element with key attributes\n- **Section type** and file path (e.g., `sections/header.liquid`)\n- **Block type** if inside a section block\n- **Snippet name** if using data-snippet attributes\n\n## What gets detected\n\nShopify Grab detects theme structure from:\n\n- `data-shopify-editor-section` attributes (JSON with section type, settings, blocks)\n- `data-shopify-editor-block` attributes (JSON with block type)\n- `data-section-id` and `data-section-type` attributes\n- `.shopify-section` class and `#shopify-section-*` IDs\n- `.shopify-block` class and `#shopify-block-*` IDs\n- `data-snippet` custom attributes (for snippet identification)\n\nThese attributes are automatically present in the Shopify Theme Editor and on storefront preview pages.\n\n## Liquid Profiler (Advanced)\n\nShopify Grab includes a built-in Liquid profiler that taps into the same profiling API used by Shopify's Theme Inspector Chrome extension. When enabled, it provides **file paths, line numbers, and render times** for every Liquid template, giving you bippy-level source introspection for Shopify themes.\n\n### How it works\n\n1. Authenticates with Shopify Identity (same OAuth flow as Theme Inspector)\n2. Fetches Speedscope-format profiling data from Shopify's servers\n3. Parses the profiling frames to build a source map\n4. Maps DOM elements to their Liquid source files via section/block correlation\n\n### Quick start\n\n```javascript\nconst sg = window.__SHOPIFY_GRAB__;\n\n// Sign in with your Shopify partner/staff account (opens popup)\nawait sg.profilerSignIn();\n\n// Fetch profiling data for the current page\nawait sg.profilerProfile();\n\n// Now hover + Cmd/Ctrl+C includes file:line info!\n// Example output with profiler enabled:\n//\n// <div class=\"product-card\">\n//   Premium Widget\n//   $29.99\n// </div>\n//   in featured-collection (at sections/featured-collection.liquid:42) (15.2ms)\n//   in product-card (at snippets/product-card.liquid:3) (4.1ms)\n//   render: 19.3ms\n```\n\n### Profiler API\n\n```javascript\nconst sg = window.__SHOPIFY_GRAB__;\n\n// Authentication\nawait sg.profilerSignIn();      // Sign in (opens OAuth popup)\nsg.profilerSignOut();            // Sign out and clear tokens\nsg.profilerIsAuthenticated();    // Check if signed in\n\n// Profiling\nconst profile = await sg.profilerProfile();  // Fetch profile for current page\nsg.profilerHasProfile();                     // Check if profile data loaded\nsg.profilerClearCache();                     // Clear cached profiles\n\n// Element source resolution\nsg.getSourceForElement(element);       // Full source stack (layout -> template -> section -> snippet)\nsg.getBestSourceForElement(element);   // Most specific source location\nsg.getRenderTimeForElement(element);   // Section render time in ms\n\n// Status monitoring\nsg.profilerGetStatus();  // { state: \"idle\" | \"authenticating\" | \"authenticated\" | \"fetching\" | \"ready\" | \"error\" }\nsg.profilerOnStatusChange((status) => console.log(status));\n```\n\n### Requirements\n\n- A Shopify partner or staff account with access to the store\n- The store must be accessible (live or via `shopify theme dev`)\n- Profiling is read-only and does not affect store performance\n\n### Without the profiler\n\nShopify Grab works without authentication, using DOM-based detection (data attributes, section IDs, class patterns). The profiler just adds richer source context.\n\n## Features\n\n- Same overlay UI as react-grab (crosshair, selection highlight, floating label)\n- **Liquid profiler** for file:line source context (like bippy for React)\n- Shopify green color scheme\n- Canvas-based overlay for smooth 60fps animations\n- Shadow DOM isolation (doesn't conflict with theme styles)\n- Drag to select multiple elements\n- Right-click context menu with Copy, Copy HTML, Copy Screenshot\n- Cursor IDE Lexical editor clipboard format support\n- Plugin system for customization\n- Render time display per section\n\n## API\n\n```javascript\n// Access the global API\nconst api = window.__SHOPIFY_GRAB__;\n\n// Programmatic control\napi.activate();\napi.deactivate();\napi.toggle();\napi.isActive();\n\n// Copy an element's context\napi.copyElement(document.querySelector('.product-card'));\n\n// Get display name for an element\napi.getDisplayName(element); // \"featured-collection\" or \"header/menu\"\n\n// Get source info (uses profiler when available)\nconst source = await api.getSource(element);\n// { filePath: \"sections/header.liquid\", lineNumber: 42, componentName: \"header\" }\n```\n\n## License\n\nMIT. Based on react-grab by Aiden Bai.\n","readmeFilename":"README.md"}