A Chrome extension that pins a small badge into the corner of a page when its URL matches a rule you define — so you always know which brand, environment, client, or account you're looking at before you act on it.
The motivating case is brand + environment (a dev/stage/prod fleet
that looks identical across tabs), but the matching engine is general
purpose: it works just as well for client labels on agency work, "internal
tool — not customer facing" warnings, or one rule labeling a whole fleet of
admin panels by hostname.
No build step, no npm dependencies, no bundler. Everything ships as-is.
- Open
chrome://extensions. - Turn on Developer mode (top right).
- Click Load unpacked and select this directory.
- A starter config seeds itself automatically on first install — open any
http://localhost:3000page to see a badge, or click the toolbar icon to add a rule for the site you're actually on.
- Click the toolbar icon to open the popup. On a page with no matching rule it shows + Add rule; on a matched page it shows Edit, Disable rule (just that rule — a quick, reversible off-switch), and Snooze (this host, for the browser session). Add/Edit opens a compact form — pattern, group, title, tags (with autocomplete from tags you've already used), note, and one color+frame row with a live preview — and warns before saving if the rule would conflict with (or be shadowed by) one you already have.
- Alt+click a badge to cycle it through the four screen corners (and reset its size); drag it anywhere (no modifier key needed) and that position is remembered too. A plain click does nothing. Drag its bottom-right corner (a plain browser resize handle) to grow or shrink it, up to the size of the screen — also remembered per host.
- The popup's footer has the global Enable/Disable switch and a link to the full Options page: a raw JSON config editor, a live pattern tester (paste any URL, see exactly which rule wins and why), and a Groups pane for full point-and-click CRUD over groups, rules, and tag colors — no JSON required.
- Keyboard shortcuts:
Alt+Shift+Mopens the popup,Alt+Shift+Ktoggles everything off/on. Both are rebindable atchrome://extensions/shortcuts.
sitemark/
├── manifest.json
├── src/
│ ├── lib/ # pure, Node-testable: matching, colors, templates, config, quick-add
│ ├── content.js # renders the badge on matching pages
│ ├── render.js # shared badge DOM builder (content script + previews)
│ ├── badge.css.js # the badge's shadow-root stylesheet, as a string
│ ├── ruleform.js # shared rule-editing fields (popup + Options Groups)
│ ├── sw.js # service worker: kill switch, seeding
│ ├── popup/ # toolbar popup: summary view + add/edit form
│ └── options/ # config editor, pattern tester, Groups (full CRUD)
├── icons/
└── tests/ # node:test, zero dependencies
Everything runs on plain Node — no install step:
node --test tests/*.test.js(node --test tests/ with a bare directory argument hits an unrelated bug in
some newer Node builds; the glob form above always works.)
After editing any file under src/, reload the extension from
chrome://extensions (or hit the refresh icon on its card) to pick up the
change — service worker changes may need "service worker (inactive)" clicked
first to see errors.
./package.shWrites sitemark.zip at the repo root, containing only manifest.json,
icons/, and src/ — the exact files Chrome needs. Everything else here
(tests/, this file, CLAUDE.md, PRIVACY.md, git metadata) is dev-only
and never enters the zip.
CLAUDE.md in this directory is the full design spec this project was built
against — hard requirements, the matching algorithm, the storage schema, and
the manual test checklist. If you're changing how rules are matched, how the
badge renders, or the storage format, read that first; it documents why
things work the way they do, including a few deliberate deviations from an
earlier draft of the spec (documented inline where they occur) forced by
what Chrome's extension platform actually allows without asking for extra
permissions.