# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## What this is GreasyBoii is a browser extension (a lightweight Greasemonkey/Tampermonkey-style tool) that injects custom JavaScript and CSS into pages based on URL-substring or CSS-selector match rules, configured through a popup UI. There is no build system, package manager, or test suite — it's plain HTML/CSS/JS shipped straight to the browser. ## Repository layout The extension is maintained as two **parallel, independently-edited** implementations: - `chrome/` — Manifest V3 (service worker background script) - `firefox/` — Manifest V2 (persistent background script, `browser.*` namespace) Each directory is a complete, self-contained extension (manifest, background script, content script, popup HTML/CSS/JS, vendored Bootstrap, icons). **There is no shared source** — a change to matching/rule logic in one directory must be manually ported to the other. When editing behavior, always check whether the same fix is needed in both `chrome/*.js` and `firefox/*.js`; diff the two files first (`diff chrome/foo.js firefox/foo.js`) to see how they currently diverge before deciding how to apply a change to both. Key API differences between the two versions: - Namespace: `chrome.*` vs. the promise-based `browser.*`. Style is otherwise mixed on the Chrome side rather than uniform: `chrome/background.js` keeps the original callback style throughout; `chrome/content.js` and `chrome/popup.js` were ported from the Firefox files and use the promise form instead (valid since Chrome 88+ returns a Promise from most `chrome.*` calls when the callback is omitted — the manifest already requires Chrome 88+). Don't "fix" this into one style without checking both still work; it's a leftover of how the port was done, not a bug. - Chrome's `background.js` handles JS execution via `chrome.scripting.executeScript` (world: `MAIN`) to bypass page CSP, relayed there from `chrome/content.js`'s `injectJavaScript`; Firefox's `content.js` instead injects a `