| tools | ||
| .gitignore | ||
| approval-queue-bulk-actions.user.js | ||
| authors.json | ||
| AutoSelectDeleted.js | ||
| Changelog.md | ||
| DuplicateThreadScanner.user.js | ||
| F95-Suite.js | ||
| F95_BRATR_Management_Ratings_Helper.js | ||
| F95RuleSelect.js | ||
| F95TagSelect.user.js | ||
| f95zone-ticket-manager.user.js | ||
| F95Zone_TemplateMaker.userscript.js | ||
| GameScanner.js | ||
| GodotPrefixUpdater.user.js | ||
| link-manager.js | ||
| manifest.json | ||
| MultizoneBulkDelete.user.js | ||
| package-lock.json | ||
| package.json | ||
| PromoteCurrentTime.js | ||
| RabbitHole.js | ||
| README.md | ||
| report-organizer.js | ||
| report-queue-csv-export.user.js | ||
| ReprortSorter.user.js | ||
| rule7-notify.js | ||
| SharedIPManager.js | ||
| ThreadExporter.js | ||
F95 scripts
Anything using tools.zonies.xyz, you must create an API key under your profile.
F95 Suite (F95-Suite.js)
The unified userscript F95-Suite.js is not edited by hand. It is generated from standalone sources (for example RabbitHole.js, GameScanner.js) by a small Node builder.
Regenerating the suite
From the repository root (scripts/):
node tools/merge-f95-suite.mjs
Requirements: Node.js (any recent LTS is fine) and npm install once at the repo root (installs @sentry/node for the merge tool only). The script reads each configured source file, strips that file’s // ==UserScript== … ==/UserScript== header, optionally applies a patch function, wraps the body in function init…() { … }, concatenates everything into F95-Suite.js, and runs a Unicode sanitizer on the output.
Optional: Bugsink (Sentry-compatible) telemetry
If BUGSINK_DSN or SENTRY_DSN is set when you run the merge (for example in a gitignored .env file or CI secrets), the generated F95-Suite.js will:
- Add Tampermonkey
// @require(pinned Sentry browser bundle) and// @connectfor the hostname parsed from your DSN. - Call
Sentry.initwith Bugsink-oriented options (tracesSampleRate: 0,autoSessionTracking: false,sendDefaultPii: false; see Bugsink SDK recommendations). - Forward
console.warnandconsole.errorto Bugsink;console.log/info/debugstay in the browser console only. - Define
window.f95suiteBugsinkInfo(message, optionalContext)for rare explicitinfoevents.
The merge script itself can also report build failures to Bugsink using the same DSN (release defaults to merge-f95-suite@<manifest version>; successful “Wrote …” lines are not sent).
Optional environment variables:
| Variable | Purpose |
|---|---|
BUGSINK_DSN or SENTRY_DSN |
Client DSN URL (required for any telemetry) |
BUGSINK_ENV |
environment tag (defaults: userscript in the bundle, development in the merge tool) |
BUGSINK_RELEASE |
Overrides default release (f95-suite@<version> / merge-f95-suite@<version>) |
Shipping the DSN: embedding the DSN in the published userscript is normal for client-side error reporting; anyone with the file can send events to that project. Prefer keeping the DSN out of git and injecting it only in release builds; use Bugsink rate limits and retention to limit abuse.
Standalone RabbitHole.js: leave RH_BUGSINK_DSN empty when using the suite. For Tampermonkey-only RabbitHole, set RH_BUGSINK_DSN, then uncomment the documented // @require / // @connect lines in that file’s header.
After a successful run you should see something like:
Wrote …\F95-Suite.js (… KB)
Install or update F95-Suite.js in Tampermonkey (or your manager of choice). Use the in-page Suite settings (gear) to enable or disable each module; toggles are stored under keys prefixed with f95suite_module_.
Adding a new script to the merge
All edits happen in tools/merge-f95-suite.mjs unless you only need a new source file.
-
Add the source file at the repo root (or another path you reference), with a normal Tampermonkey-style header (
@match,@grant, etc.) for standalone installs. The merge removes that header in the bundle; the unified script uses the grants declared inSUITE_PREAMBLEinsidemerge-f95-suite.mjs. If your script needs aGM_*API not already listed there, add the matching// @grantlines toSUITE_PREAMBLEso the suite userscript is allowed to use them. -
sourcesarray (bottom ofmerge-f95-suite.mjs): append an object in merge order:name: stable id, camelCase (e.g.myWidget). Used everywhere below.file: path relative to the repo root, e.g.'MyWidget.user.js'.patch:(s) => sif no transform is needed, or a function that returns the source string after string replacements (seerabbitHole,autoSelectDeleted, orsharedIpManagerfor examples).
-
INIT_NAMESmap: one entry whose key isnameand value is the init function nameinit+ Pascal-style suffix consistent with existing modules, e.g.myWidget: 'initMyWidget'. -
SUITE_PREAMBLE(large template string): extend the bundled runtime in three places:URL_PREDICATES: addmyWidget: () => hostIsF95() && …so the module only runs on the URLs you intend.MODULE_META: add{ id: 'myWidget', label: '…', hint: '…' }for the Suite settings panel (theidmust matchname).
-
SUITE_BOOTSTRAP: inF95SUITE_INITS, add a row:['myWidget', initMyWidget, URL_PREDICATES.myWidget],Order controls init order among modules.
-
Metadata: bump
SUITE_PREAMBLE@version/@descriptionwhen you ship a meaningful suite change. -
Run
node tools/merge-f95-suite.mjsand commit the updatedF95-Suite.js(andmerge-f95-suite.mjs) together with your new source file.
Convention: each merged file’s top-level code should run when its init…() is invoked (same as today: an IIFE or loose statements at file scope). Do not assume the standalone @name / @match from the source file apply inside the suite; only URL_PREDICATES and the suite’s @match lines control where the bundled code is loaded (the init still gates per module).