Skip to main content

Your own library source

The app installs scripts from sources: URLs that return a JSON catalogue. The Tsum Tsum library is built by the public tsum-tsum-catalogue repository and served from GitHub Pages; you can publish one the same way, and anyone can add it under the app's Sources tab.

1. What a script archive must contain​

A plain zip with the script's files at its root (or inside exactly one wrapper folder, which the installer strips):

FileRequiredWhat
index.jsone of these twoThe script. A classic script, not a module: start(settings) and stop() must be global functions.
index.htmlone of these twoThe settings page. Must define onEvent(type) and onLog(message); builds the settings object and evaluates start(...) through the host bridge.
quickbar.htmlnoA Quick Bar page. A script without one simply has no Quick Bar button.
images/noTemplates for the host's image matching.
anything elsenoData files the script reads from its own folder — this script ships tsums.dat.

The install fails if neither index.js nor index.html is at the root after extraction. There is no manifest inside the archive: the script's game, name and version come from the catalogue entry, and the app records them beside the install.

For this repository, npm run build produces such an archive (TsumTsum-<Channel>-<version>.zip).

2. Hash it​

Every entry carries the SHA-256 of its zip as 64 hex characters. The app computes the digest while downloading and discards a file whose digest does not match before writing anything, so the hash is what makes a source safe to trust with an install.

sha256sum TsumTsum-Beta-5.0a2.zip # Linux / Git Bash
Get-FileHash TsumTsum-Beta-5.0a2.zip # PowerShell

This repository's build writes it beside the archive as <archive>.zip.sha256; the release tool re-hashes the bytes it copies.

3. The catalogue format​

A source URL returns one JSON object:

{
"Name": "My Scripts",
"Updated": "2026-09-11T10:00:00Z",
"Scripts": [
{
"Game": "Tsum Tsum",
"Name": "My Tsum Script",
"Version": "1.0",
"Date": "2026-09-11 10:00:00",
"Hash": "006f503949df3dda5080375dc6ff24cd6f5aa9cbc5e3fbad549abb15ce9ae3a9",
"File": "https://github.com/you/my-scripts/raw/main/Mine/TsumTsum/Beta/MyTsum-1.0.zip",
"Message": "**Changes**\n1. First release.",
"Versions": [
{ "Version": "1.0", "Date": "2026-09-11 10:00:00",
"Hash": "006f503949df3dda5080375dc6ff24cd6f5aa9cbc5e3fbad549abb15ce9ae3a9",
"File": "https://github.com/you/my-scripts/raw/main/Mine/TsumTsum/Beta/MyTsum-1.0.zip" }
]
}
]
}
FieldRequiredMeaning
NameyesThe source's display name, and the first segment of every install folder, so never change it once published. Official GAP is reserved for the app's own source; a user source claiming it is shown struck through, marked unsafe and refused.
UpdatednoWhen the index was built. Informational.
Scripts[]yesOne entry per script. May be empty.
Scripts[].GameyesThe game. Becomes a segment of the install folder: scripts/<Source>/<Game>/<Name>/.
Scripts[].NameyesThe script's display name; the last segment of the install folder, spaces dashed.
Scripts[].VersionyesFree-form; compared by equality.
Scripts[].DatenoYYYY-MM-DD HH:MM:SS, UTC by convention.
Scripts[].HashyesSHA-256 of the zip, 64 hex characters.
Scripts[].FileyesAn absolute http(s) URL to the zip.
Scripts[].MessagenoThe release note, rendered as Markdown behind the card's notes button. A short numbered list reads best on a phone.
Scripts[].Versions[]noBuilds still installable, newest first; the first row is the same build the entry's own fields describe. Each row needs Version, Hash and File. The app offers them in a menu on the card so a player can roll back. Omit it and the entry reads as a one-version history.

An entry missing a required field is skipped and the rest of the catalogue still loads. Keep the index small — the app caps a catalogue at about 2 MB — which is why a history row carries no Message.

4. Host it on GitHub Pages​

The Tsum Tsum catalogue is the worked example, and copying its layout gets you its build script and workflow for free.

The layout​

my-scripts/
├── .github/workflows/build-catalogue.yml builds the index and publishes it
├── build-catalogue.sh folds every metadata.json into catalogue.json
├── build-catalogue.ps1 the same, for PowerShell
├── .gitignore catalogue.json (generated, never committed)
└── <Game>/<Channel>/
├── MyTsum-1.0.zip the archive(s)
├── metadata.json one entry, File relative to this folder
└── CHANGELOG.md optional, for people

Per-script metadata.json files are the entries above with one difference: File (and each Versions[].File) is a filename relative to that folder, and the build script rewrites it into the raw download URL for that file, derived from the repository's own origin remote and current branch:

tsum-tsum-catalogue/LineTsumTsum/Production/metadata.json
loading...

The build script​

Reads every metadata.json under the repository, rewrites each File to https://github.com/<owner>/<repo>/raw/<branch>/<path>, and writes catalogue.json. It needs jq. Change the Name near the end to your own — it becomes your players' install folder, and Official GAP is the one name the app refuses:

tsum-tsum-catalogue/build-catalogue.sh
loading...

The workflow​

On every push to main, the workflow runs the script and publishes catalogue.json to GitHub Pages. catalogue.json is never committed. Its Discord step does nothing unless you add a webhook secret.

tsum-tsum-catalogue/.github/workflows/build-catalogue.yml
loading...

Turn on Pages​

In the repository on GitHub: Settings → Pages → Build and deployment → Source: GitHub Actions. Push, wait for the Build catalogue.json workflow to go green, and the index is at https://<owner>.github.io/<repo>/catalogue.json.

Any other static host works the same way — the app does a plain HTTP GET and follows redirects. Raw GitHub URLs (raw.githubusercontent.com, or github.com/<owner>/<repo>/raw/<branch>/...) serve the zips; Pages is only needed for the index because the app caches what it fetched and re-checks it on each launch.

5. Add it in the app​

Open the Sources tab, add the URL, and the Library lists what the source publishes with a download disc beside anything not yet installed. The app re-checks every source once per launch and on the refresh button; a script whose published hash differs from the installed one gets an UPDATE badge.

Anything added here is unverified: a source can publish any archive under any name, which is why the hash check exists and why the app's own dialog says to add only sources you trust. A website or tool can hand the app a gap://add-source?url=… link to offer your source; the app still asks the player before adding it. A script installed from your source gets no special access either: every switch on its access screen starts off (Trust and access).

6. Publishing an update​

  1. Build the new zip and hash it.
  2. In metadata.json, set the top-level fields to the new build and prepend a row to Versions (keep the previous rows you still want installable; drop the archives you remove).
  3. Add a section to the folder's CHANGELOG.md if you keep one.
  4. Commit the zip and the metadata, push, and let the workflow publish.

This repository's npm run release:<channel> does exactly these steps for the Tsum Tsum catalogue — Release to the catalogue — and tools/release/release.js is a reasonable starting point for a release script of your own.