this post sux
README.md

sux — userscript version #

The same Jev feed filter as the extension in the parent directory, packaged as a single userscript for Tampermonkey or Violentmonkey (any browser). Rules, thresholds, caching, and hide-until-judged behavior are identical; see ../README.md.

Install #

  1. Install Tampermonkey or Violentmonkey.
  2. Open sux.user.js in the manager (drag the file in, or use its "install from file/URL"), and allow the api.typesafe.ai connection when prompted.
  3. Open bsky.app, click the sux pill at the bottom right (or use the manager's sux settings menu command), paste your API key, press Test, enable a rule, flip Filtering on.

Greasemonkey 4 is not supported (it only provides the async GM.* API).

Differences from the extension #

  • Settings UI is a floating panel inside bsky.app (Shadow DOM, isolated from the page's CSS) instead of a browser sidebar.
  • No browser-theme colors: always Everforest dark.
  • No page-world fetch interceptor: it was only a supplement; posts come from the DOM scan, as in the extension.
  • Per-tab engine: each tab has its own queue and stats. Settings and the verdict cache are shared across tabs via userscript storage, and settings changes propagate live to other open tabs.
  • API key lives in the userscript manager's storage for this script.

Development #

Edit src/ (and ../shared.js, which is inlined verbatim), then rebuild:

node userscript/build.mjs            # writes userscript/sux.user.js
node userscript/build.mjs --check    # fails if sux.user.js is stale
node --test userscript/test/         # build freshness + metadata checks
source typesafe_api_key.secret.sh && node userscript/scripts/live-e2e.mjs   # live end-to-end

live-e2e.mjs launches a throwaway headless Chrome that acts as the userscript manager. It injects the script at document-start on real bsky.app, calls the real API (the key stays in Node and never reaches the page), and checks filtering, the panel's Test button, the on/off toggle, and the persisted cache.

sux.user.js is committed so it can be installed directly.

Layout: src/meta.txt (metadata block), src/main.js (engine + feed + panel; merges background.js, content.js, sidebar.js), src/panel.html, src/panel.css.