Created
March 31, 2026 14:37
-
-
Save itaydre/3339c1e7d805d590978d292b7cabf3da to your computer and use it in GitHub Desktop.
Dev Helper - Element inspector + agent bridge for local dev. Inspect elements, copy info to Claude Code.
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
| #!/bin/bash | |
| # iForms Dev Helper Installer | |
| # Usage: curl -sL <URL> | bash | |
| # or: bash dev-helper-installer.sh | |
| set -e | |
| GREEN='\033[0;32m' | |
| BLUE='\033[0;34m' | |
| GRAY='\033[0;90m' | |
| NC='\033[0m' | |
| BOLD='\033[1m' | |
| echo "" | |
| echo -e "${BLUE}${BOLD} Dev Helper Installer${NC}" | |
| echo -e "${GRAY} Element inspector + agent bridge for local dev${NC}" | |
| echo "" | |
| # Detect JS directory | |
| JS_DIR="" | |
| for dir in src/assets/js assets/js public/js static/js js; do | |
| if [ -d "$dir" ]; then | |
| JS_DIR="$dir" | |
| break | |
| fi | |
| done | |
| if [ -z "$JS_DIR" ]; then | |
| echo -e "${GRAY} No JS directory found. Where should I put the file?${NC}" | |
| read -p " Path (default: ./js): " JS_DIR | |
| JS_DIR="${JS_DIR:-js}" | |
| mkdir -p "$JS_DIR" | |
| fi | |
| TARGET="$JS_DIR/dev-helper.js" | |
| echo -e " Installing to ${BOLD}$TARGET${NC}" | |
| # Write the dev-helper.js file | |
| cat > "$TARGET" << 'DEVHELPER_EOF' | |
| (function() { | |
| if (window.__devHelperLoaded) return; | |
| window.__devHelperLoaded = true; | |
| var isActive = false; | |
| var selectedEls = []; | |
| var hoveredEl = null; | |
| var style = document.createElement('style'); | |
| style.textContent = ` | |
| .dh-panel { | |
| position: fixed; | |
| bottom: 20px; | |
| left: 20px; | |
| z-index: 99999; | |
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; | |
| font-size: 13px; | |
| color: #1a1a1a; | |
| direction: ltr; | |
| text-align: left; | |
| } | |
| .dh-toggle { | |
| width: 44px; | |
| height: 44px; | |
| border-radius: 50%; | |
| background: #236cc0; | |
| color: #fff; | |
| border: none; | |
| cursor: pointer; | |
| font-size: 20px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| box-shadow: 0 4px 16px rgba(0,0,0,0.2); | |
| transition: background 0.2s; | |
| } | |
| .dh-toggle:hover { background: #3588f2; } | |
| .dh-toggle.active { background: #e74c3c; } | |
| .dh-body { | |
| display: none; | |
| background: #fff; | |
| border-radius: 12px; | |
| box-shadow: 0 8px 32px rgba(0,0,0,0.18); | |
| width: 380px; | |
| max-height: 70vh; | |
| overflow: hidden; | |
| margin-bottom: 10px; | |
| border: 1px solid #e0e0e0; | |
| } | |
| .dh-body.open { display: flex; flex-direction: column; } | |
| .dh-header { | |
| padding: 12px 16px; | |
| background: #f8f8f8; | |
| border-bottom: 1px solid #e0e0e0; | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| font-weight: 600; | |
| font-size: 14px; | |
| } | |
| .dh-header-actions { display: flex; gap: 8px; align-items: center; } | |
| .dh-header-actions button { | |
| background: none; | |
| border: 1px solid #d0d0d0; | |
| border-radius: 6px; | |
| padding: 4px 10px; | |
| font-size: 12px; | |
| cursor: pointer; | |
| color: #555; | |
| } | |
| .dh-header-actions button:hover { background: #eee; } | |
| .dh-select-btn { | |
| background: #236cc0 !important; | |
| color: #fff !important; | |
| border-color: #236cc0 !important; | |
| } | |
| .dh-select-btn.selecting { | |
| background: #e74c3c !important; | |
| border-color: #e74c3c !important; | |
| } | |
| .dh-selected-list { | |
| padding: 8px 16px; | |
| max-height: 180px; | |
| overflow-y: auto; | |
| border-bottom: 1px solid #e0e0e0; | |
| } | |
| .dh-selected-item { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| padding: 6px 8px; | |
| margin-bottom: 4px; | |
| background: #f0f6ff; | |
| border-radius: 6px; | |
| font-size: 12px; | |
| font-family: 'SF Mono', Monaco, monospace; | |
| } | |
| .dh-selected-item .dh-tag { color: #236cc0; font-weight: 600; } | |
| .dh-selected-item .dh-class { color: #888; margin-left: 6px; } | |
| .dh-selected-item .dh-size { color: #aaa; margin-left: 6px; } | |
| .dh-remove-btn { | |
| background: none; | |
| border: none; | |
| color: #ccc; | |
| cursor: pointer; | |
| font-size: 16px; | |
| padding: 0 4px; | |
| line-height: 1; | |
| } | |
| .dh-remove-btn:hover { color: #e74c3c; } | |
| .dh-empty { | |
| padding: 16px; | |
| text-align: center; | |
| color: #aaa; | |
| font-size: 13px; | |
| } | |
| .dh-input-area { | |
| padding: 12px 16px; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 8px; | |
| } | |
| .dh-input-area textarea { | |
| width: 100%; | |
| border: 1px solid #d0d0d0; | |
| border-radius: 8px; | |
| padding: 8px 12px; | |
| font-size: 13px; | |
| font-family: inherit; | |
| resize: none; | |
| min-height: 60px; | |
| outline: none; | |
| direction: rtl; | |
| box-sizing: border-box; | |
| } | |
| .dh-input-area textarea:focus { border-color: #236cc0; } | |
| .dh-btn-row { display: flex; gap: 8px; } | |
| .dh-copy-btn { | |
| flex: 1; | |
| background: none; | |
| color: #555; | |
| border: 1px solid #d0d0d0; | |
| border-radius: 8px; | |
| padding: 8px 16px; | |
| font-size: 13px; | |
| font-weight: 600; | |
| cursor: pointer; | |
| white-space: nowrap; | |
| } | |
| .dh-copy-btn:hover { background: #f0f0f0; } | |
| .dh-send-btn { | |
| flex: 2; | |
| background: #236cc0; | |
| color: #fff; | |
| border: none; | |
| border-radius: 8px; | |
| padding: 8px 16px; | |
| font-size: 13px; | |
| font-weight: 600; | |
| cursor: pointer; | |
| white-space: nowrap; | |
| transition: background 0.2s; | |
| } | |
| .dh-send-btn:hover { background: #3588f2; } | |
| .dh-send-btn:disabled { background: #a0c4e8; cursor: not-allowed; } | |
| .dh-toast { | |
| position: fixed; | |
| bottom: 80px; | |
| left: 20px; | |
| background: #1a1a1a; | |
| color: #fff; | |
| padding: 10px 20px; | |
| border-radius: 8px; | |
| font-size: 13px; | |
| z-index: 100000; | |
| opacity: 0; | |
| transition: opacity 0.3s; | |
| pointer-events: none; | |
| } | |
| .dh-toast.show { opacity: 1; } | |
| .dh-highlight-outline { | |
| position: absolute; | |
| border: 2px solid #236cc0; | |
| background: rgba(35, 108, 192, 0.08); | |
| pointer-events: none; | |
| z-index: 99998; | |
| border-radius: 4px; | |
| transition: none; | |
| } | |
| .dh-hover-outline { | |
| position: absolute; | |
| border: 2px dashed #3588f2; | |
| background: rgba(53, 136, 242, 0.05); | |
| pointer-events: none; | |
| z-index: 99997; | |
| border-radius: 4px; | |
| } | |
| .dh-hover-label { | |
| position: absolute; | |
| top: -22px; | |
| left: 0; | |
| background: #3588f2; | |
| color: #fff; | |
| font-size: 11px; | |
| padding: 2px 6px; | |
| border-radius: 3px; | |
| font-family: 'SF Mono', Monaco, monospace; | |
| white-space: nowrap; | |
| pointer-events: none; | |
| } | |
| .dh-margin-overlay { | |
| position: absolute; | |
| background: rgba(246, 178, 107, 0.4); | |
| pointer-events: none; | |
| z-index: 99996; | |
| } | |
| .dh-padding-overlay { | |
| position: absolute; | |
| background: rgba(147, 196, 125, 0.45); | |
| pointer-events: none; | |
| z-index: 99997; | |
| } | |
| .dh-spacing-label { | |
| position: absolute; | |
| font-size: 9px; | |
| font-family: 'SF Mono', Monaco, monospace; | |
| color: #fff; | |
| pointer-events: none; | |
| z-index: 99999; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| `; | |
| document.head.appendChild(style); | |
| var toast = document.createElement('div'); | |
| toast.className = 'dh-toast'; | |
| document.body.appendChild(toast); | |
| function showToast(msg, duration) { | |
| toast.textContent = msg; | |
| toast.classList.add('show'); | |
| setTimeout(function() { toast.classList.remove('show'); }, duration || 2000); | |
| } | |
| var panel = document.createElement('div'); | |
| panel.className = 'dh-panel'; | |
| panel.innerHTML = '<div class="dh-body"><div class="dh-header"><span>Dev Helper</span><div class="dh-header-actions"><button class="dh-clear-btn">Clear</button><button class="dh-select-btn">Select</button></div></div><div class="dh-selected-list"><div class="dh-empty">Click "Select" then click elements on the page.<br>Hold Shift to multi-select.</div></div><div class="dh-input-area"><textarea placeholder="Type instructions for the agent..."></textarea><div class="dh-btn-row"><button class="dh-copy-btn">Copy</button><button class="dh-send-btn">Send to Agent</button></div></div></div><button class="dh-toggle" title="Dev Helper">⚙</button>'; | |
| document.body.appendChild(panel); | |
| var toggleBtn = panel.querySelector('.dh-toggle'); | |
| var body = panel.querySelector('.dh-body'); | |
| var selectBtn = panel.querySelector('.dh-select-btn'); | |
| var clearBtn = panel.querySelector('.dh-clear-btn'); | |
| var listEl = panel.querySelector('.dh-selected-list'); | |
| var textarea = panel.querySelector('textarea'); | |
| var copyBtn = panel.querySelector('.dh-copy-btn'); | |
| var sendBtn = panel.querySelector('.dh-send-btn'); | |
| var hoverBox = null; | |
| toggleBtn.addEventListener('click', function() { body.classList.toggle('open'); }); | |
| selectBtn.addEventListener('click', function() { | |
| isActive = !isActive; | |
| selectBtn.classList.toggle('selecting', isActive); | |
| selectBtn.textContent = isActive ? 'Stop' : 'Select'; | |
| toggleBtn.classList.toggle('active', isActive); | |
| if (!isActive) removeHover(); | |
| }); | |
| clearBtn.addEventListener('click', function() { | |
| selectedEls = []; | |
| renderList(); | |
| removeHighlights(); | |
| }); | |
| function getSelector(el) { | |
| if (el.id) return el.tagName.toLowerCase() + '#' + el.id; | |
| var tag = el.tagName.toLowerCase(); | |
| var cls = el.className && typeof el.className === 'string' | |
| ? '.' + el.className.trim().split(/\s+/).filter(function(c) { return c && !c.startsWith('dh-'); }).join('.') | |
| : ''; | |
| return tag + cls; | |
| } | |
| function getPath(el) { | |
| var parts = []; | |
| var cur = el; | |
| while (cur && cur !== document.body && parts.length < 3) { | |
| parts.unshift(getSelector(cur)); | |
| cur = cur.parentElement; | |
| } | |
| return parts.join(' > '); | |
| } | |
| function getOuterSnippet(el) { | |
| var clone = el.cloneNode(false); | |
| var html = clone.outerHTML; | |
| if (html.length > 120) html = html.substring(0, 120) + '...'; | |
| return html; | |
| } | |
| function buildOutput() { | |
| var instruction = textarea.value.trim(); | |
| var output = ''; | |
| if (selectedEls.length > 0) { | |
| output += 'Selected elements:\n'; | |
| selectedEls.forEach(function(el, i) { | |
| var rect = el.getBoundingClientRect(); | |
| output += '\n' + (i + 1) + '. ' + getPath(el) + '\n'; | |
| output += ' Size: ' + Math.round(rect.width) + 'x' + Math.round(rect.height) + '\n'; | |
| output += ' HTML: ' + getOuterSnippet(el) + '\n'; | |
| var cs = window.getComputedStyle(el); | |
| output += ' Styles: font-size=' + cs.fontSize + ', color=' + cs.color + ', bg=' + cs.backgroundColor + ', padding=' + cs.padding + ', margin=' + cs.margin + ', border-radius=' + cs.borderRadius + '\n'; | |
| }); | |
| } | |
| if (instruction) { output += '\nInstruction: ' + instruction + '\n'; } | |
| return output; | |
| } | |
| function renderList() { | |
| if (selectedEls.length === 0) { | |
| listEl.innerHTML = '<div class="dh-empty">Click "Select" then click elements on the page.<br>Hold Shift to multi-select.</div>'; | |
| return; | |
| } | |
| listEl.innerHTML = ''; | |
| selectedEls.forEach(function(el, i) { | |
| var rect = el.getBoundingClientRect(); | |
| var item = document.createElement('div'); | |
| item.className = 'dh-selected-item'; | |
| item.innerHTML = '<span><span class="dh-tag">' + el.tagName.toLowerCase() + '</span><span class="dh-class">' + (el.className && typeof el.className === 'string' ? '.' + el.className.trim().split(/\s+/).filter(function(c){ return !c.startsWith('dh-'); }).slice(0,2).join('.') : '') + '</span><span class="dh-size"> ' + Math.round(rect.width) + 'x' + Math.round(rect.height) + '</span></span><button class="dh-remove-btn" data-index="' + i + '">×</button>'; | |
| item.addEventListener('mouseenter', function() { highlightOne(el, 'hover'); }); | |
| item.addEventListener('mouseleave', function() { removeHover(); }); | |
| listEl.appendChild(item); | |
| }); | |
| listEl.querySelectorAll('.dh-remove-btn').forEach(function(btn) { | |
| btn.addEventListener('click', function(e) { | |
| e.stopPropagation(); | |
| var idx = parseInt(btn.getAttribute('data-index')); | |
| selectedEls.splice(idx, 1); | |
| renderList(); | |
| removeHighlights(); | |
| drawHighlights(); | |
| }); | |
| }); | |
| } | |
| function removeHighlights() { | |
| document.querySelectorAll('.dh-highlight-outline').forEach(function(el) { el.remove(); }); | |
| } | |
| function drawHighlights() { | |
| removeHighlights(); | |
| selectedEls.forEach(function(el) { | |
| var rect = el.getBoundingClientRect(); | |
| var box = document.createElement('div'); | |
| box.className = 'dh-highlight-outline'; | |
| box.style.top = (rect.top + window.scrollY) + 'px'; | |
| box.style.left = (rect.left + window.scrollX) + 'px'; | |
| box.style.width = rect.width + 'px'; | |
| box.style.height = rect.height + 'px'; | |
| document.body.appendChild(box); | |
| }); | |
| } | |
| function highlightOne(el, type) { | |
| removeHover(); | |
| var rect = el.getBoundingClientRect(); | |
| var cs = window.getComputedStyle(el); | |
| var scrollX = window.scrollX; | |
| var scrollY = window.scrollY; | |
| var pt = parseFloat(cs.paddingTop) || 0; | |
| var pr = parseFloat(cs.paddingRight) || 0; | |
| var pb = parseFloat(cs.paddingBottom) || 0; | |
| var pl = parseFloat(cs.paddingLeft) || 0; | |
| var mt = parseFloat(cs.marginTop) || 0; | |
| var mr = parseFloat(cs.marginRight) || 0; | |
| var mb = parseFloat(cs.marginBottom) || 0; | |
| var ml = parseFloat(cs.marginLeft) || 0; | |
| var hasMargin = mt || mr || mb || ml; | |
| var hasPadding = pt || pr || pb || pl; | |
| hoverBox = document.createElement('div'); | |
| hoverBox.style.position = 'absolute'; | |
| hoverBox.style.top = '0'; | |
| hoverBox.style.left = '0'; | |
| hoverBox.style.width = '0'; | |
| hoverBox.style.height = '0'; | |
| hoverBox.style.pointerEvents = 'none'; | |
| hoverBox.style.zIndex = '99997'; | |
| if (hasMargin) { | |
| var elTop = rect.top + scrollY; | |
| var elLeft = rect.left + scrollX; | |
| if (mt > 0) drawBox(hoverBox, 'dh-margin-overlay', elLeft - ml, elTop - mt, rect.width + ml + mr, mt, mt); | |
| if (mb > 0) drawBox(hoverBox, 'dh-margin-overlay', elLeft - ml, elTop + rect.height, rect.width + ml + mr, mb, mb); | |
| if (ml > 0) drawBox(hoverBox, 'dh-margin-overlay', elLeft - ml, elTop, ml, rect.height, ml); | |
| if (mr > 0) drawBox(hoverBox, 'dh-margin-overlay', elLeft + rect.width, elTop, mr, rect.height, mr); | |
| } | |
| if (hasPadding) { | |
| var elTop = rect.top + scrollY; | |
| var elLeft = rect.left + scrollX; | |
| if (pt > 0) drawBox(hoverBox, 'dh-padding-overlay', elLeft, elTop, rect.width, pt, pt); | |
| if (pb > 0) drawBox(hoverBox, 'dh-padding-overlay', elLeft, elTop + rect.height - pb, rect.width, pb, pb); | |
| if (pl > 0) drawBox(hoverBox, 'dh-padding-overlay', elLeft, elTop + pt, pl, rect.height - pt - pb, pl); | |
| if (pr > 0) drawBox(hoverBox, 'dh-padding-overlay', elLeft + rect.width - pr, elTop + pt, pr, rect.height - pt - pb, pr); | |
| } | |
| var outline = document.createElement('div'); | |
| outline.className = 'dh-hover-outline'; | |
| outline.style.top = (rect.top + scrollY) + 'px'; | |
| outline.style.left = (rect.left + scrollX) + 'px'; | |
| outline.style.width = rect.width + 'px'; | |
| outline.style.height = rect.height + 'px'; | |
| var labelParts = [getSelector(el) + ' — ' + Math.round(rect.width) + 'x' + Math.round(rect.height)]; | |
| labelParts.push('F:' + cs.fontSize); | |
| if (hasPadding) labelParts.push('P:' + pt + '/' + pr + '/' + pb + '/' + pl); | |
| if (hasMargin) labelParts.push('M:' + mt + '/' + mr + '/' + mb + '/' + ml); | |
| var label = document.createElement('div'); | |
| label.className = 'dh-hover-label'; | |
| label.textContent = labelParts.join(' '); | |
| outline.appendChild(label); | |
| hoverBox.appendChild(outline); | |
| document.body.appendChild(hoverBox); | |
| } | |
| function drawBox(parent, className, x, y, w, h, value) { | |
| if (w <= 0 || h <= 0) return; | |
| var box = document.createElement('div'); | |
| box.className = className; | |
| box.style.top = y + 'px'; | |
| box.style.left = x + 'px'; | |
| box.style.width = w + 'px'; | |
| box.style.height = h + 'px'; | |
| if (value && (w >= 16 || h >= 16)) { | |
| var lbl = document.createElement('div'); | |
| lbl.className = 'dh-spacing-label'; | |
| lbl.textContent = Math.round(value); | |
| lbl.style.top = y + 'px'; | |
| lbl.style.left = x + 'px'; | |
| lbl.style.width = w + 'px'; | |
| lbl.style.height = h + 'px'; | |
| lbl.style.color = '#fff'; | |
| lbl.style.fontWeight = '700'; | |
| lbl.style.textShadow = '0 1px 2px rgba(0,0,0,0.5)'; | |
| lbl.style.background = className.includes('margin') ? 'rgba(180,83,9,0.7)' : 'rgba(45,106,30,0.7)'; | |
| lbl.style.borderRadius = '3px'; | |
| parent.appendChild(lbl); | |
| } | |
| parent.appendChild(box); | |
| } | |
| function removeHover() { | |
| if (hoverBox) { hoverBox.remove(); hoverBox = null; } | |
| } | |
| document.addEventListener('mouseover', function(e) { | |
| if (!isActive) return; | |
| if (panel.contains(e.target)) return; | |
| hoveredEl = e.target; | |
| highlightOne(e.target); | |
| }); | |
| document.addEventListener('mouseout', function(e) { | |
| if (!isActive) return; | |
| if (panel.contains(e.target)) return; | |
| removeHover(); | |
| hoveredEl = null; | |
| }); | |
| document.addEventListener('click', function(e) { | |
| if (!isActive) return; | |
| if (panel.contains(e.target)) return; | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| var el = e.target; | |
| var idx = selectedEls.indexOf(el); | |
| if (e.shiftKey && idx > -1) { | |
| selectedEls.splice(idx, 1); | |
| } else if (e.shiftKey) { | |
| selectedEls.push(el); | |
| } else { | |
| selectedEls = [el]; | |
| } | |
| renderList(); | |
| drawHighlights(); | |
| }, true); | |
| copyBtn.addEventListener('click', function() { | |
| var output = buildOutput(); | |
| if (!output) return; | |
| navigator.clipboard.writeText(output).then(function() { showToast('Copied to clipboard'); }); | |
| }); | |
| sendBtn.addEventListener('click', function() { | |
| var output = buildOutput(); | |
| if (!output) { showToast('Select elements or type instructions first'); return; } | |
| navigator.clipboard.writeText(output).then(function() { | |
| showToast('Copied! Paste in Claude Code (Cmd+V)', 3000); | |
| textarea.value = ''; | |
| selectedEls = []; | |
| renderList(); | |
| removeHighlights(); | |
| }).catch(function() { showToast('Failed to copy to clipboard'); }); | |
| }); | |
| document.addEventListener('keydown', function(e) { | |
| if (e.key === 'Escape' && isActive) { | |
| e.preventDefault(); | |
| isActive = false; | |
| selectBtn.classList.remove('selecting'); | |
| selectBtn.textContent = 'Select'; | |
| toggleBtn.classList.remove('active'); | |
| removeHover(); | |
| selectedEls = []; | |
| renderList(); | |
| removeHighlights(); | |
| return; | |
| } | |
| if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key.toLowerCase() === 'd') { | |
| e.preventDefault(); | |
| if (!body.classList.contains('open')) { body.classList.add('open'); } | |
| isActive = !isActive; | |
| selectBtn.classList.toggle('selecting', isActive); | |
| selectBtn.textContent = isActive ? 'Stop' : 'Select'; | |
| toggleBtn.classList.toggle('active', isActive); | |
| if (!isActive) removeHover(); | |
| } | |
| }); | |
| window.addEventListener('scroll', drawHighlights); | |
| window.addEventListener('resize', drawHighlights); | |
| })(); | |
| DEVHELPER_EOF | |
| echo -e " ${GREEN}Done!${NC} File created at ${BOLD}$TARGET${NC}" | |
| echo "" | |
| # Auto-inject into HTML files | |
| SNIPPET='<script>if(location.hostname==="localhost"||location.hostname==="127.0.0.1"){var s=document.createElement("script");s.src="JS_PATH/dev-helper.js";document.body.appendChild(s);}</script>' | |
| SNIPPET="${SNIPPET//JS_PATH/$JS_DIR}" | |
| INJECTED=0 | |
| for html in $(find . -maxdepth 3 -name "*.html" -not -path "*/node_modules/*" -not -path "*/dist/*" -not -path "*/.git/*" 2>/dev/null); do | |
| # Skip if already has dev-helper | |
| if grep -q "dev-helper.js" "$html" 2>/dev/null; then | |
| continue | |
| fi | |
| # Inject before </body> | |
| if grep -q "</body>" "$html" 2>/dev/null; then | |
| sed -i.bak "s|</body>| $SNIPPET\n</body>|" "$html" | |
| rm -f "${html}.bak" | |
| echo -e " ${GREEN}✓${NC} Injected into ${GRAY}$html${NC}" | |
| INJECTED=$((INJECTED + 1)) | |
| fi | |
| done | |
| if [ "$INJECTED" -eq 0 ]; then | |
| echo -e " ${GRAY}No HTML files found to inject. Add this before </body>:${NC}" | |
| echo -e " ${GRAY}$SNIPPET${NC}" | |
| else | |
| echo -e "\n ${GREEN}Injected into $INJECTED file(s)${NC}" | |
| fi | |
| echo "" | |
| echo -e " ${BOLD}Features:${NC}" | |
| echo -e " ${GRAY}- Click the gear icon (bottom-left) or press Cmd+Shift+D${NC}" | |
| echo -e " ${GRAY}- Select elements to inspect (Shift+click for multi-select)${NC}" | |
| echo -e " ${GRAY}- See padding/margin/size overlays${NC}" | |
| echo -e " ${GRAY}- Copy element info + instructions for Claude Code${NC}" | |
| echo -e " ${GRAY}- Only loads on localhost (never in production)${NC}" | |
| echo "" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment