Build & tools

Rebuild the userscript

node build.js

Requires Node.js. Output: unbanded.user.js. Sources are concatenated in the order defined in build.js (src/main.js always last).

Python tools

python tools/fetch_reaction_gifs.py           # scrape 10 GIFs/command from nekos.best (build time)
python tools/gen_reaction_bank.py             # regenerate the reaction manifest.json
python tools/build_assets.py                  # fallback: regenerate offline GIFs (Pillow)

nekos.best has a global rate limit (~200 req/min): the script throttles and fails fast on a long Retry-After. Re-run later for missing commands (python tools/fetch_reaction_gifs.py hug cry).

Source structure

FileRole
src/main.jsEntry point (always last)
src/core/adapter.jsBridge to the BAND client (DOM selectors, sending)
src/core/storage.jsBTTStore: localStorage persistence
src/core/plugin-manager.jsPlugin loader (fetch + eval, raw code for file import)
src/core/plugin-manager-builtin.jsRegistration of built-in plugins/commands
src/core/themes.jsBTTThemes: 10 built-in themes, JSON import/export
src/core/styles.jsBTTStyles: custom CSS
src/core/commands.jsBuilt-in slash commands
src/core/ui.js, ui-panel.js, ui-hooks.js, ui-autocomplete.js⚙ button, Settings page, keyboard interception, autocomplete
src/core/ui-settings.jsFull Settings page
src/core/ui-emoji.jsEmoji picker
src/plugins/*Built-in plugins (afk, games, pet-pet, reactions, tools)

Reaction bank

18 commands × 10 GIFs. Manifest at src/assets/reactions/manifest.json. Loaded from absolute CDN (jsDelivr → Statically → same-origin) with JSON/image validation.

Adapting selectors

If sending messages or reading avatars fails: open DevTools (F12) on band.us, inspect the composer, send button and avatars, update src/core/adapter.js, then node build.js and reinstall.