Skip to content

Repository files navigation

alist-registry

Community plugin and theme index for AList v4

Validate Publish License

English | 简体中文

A plugin source and theme source for AList v4, addable from Admin → Plugins → Sources and Admin → Appearance → Theme Market. Not an official index — a community-maintained list of third-party plugins and themes, validated by CI against the schema alist-org/alist's backend parses.

Contents

Add this source

PluginsAdmin → Plugins → Sources → Add source:

Field Value
Name alist-registry (or anything you like)
Index URL https://raw.githubusercontent.com/AlistGo/alist-registry/main/dist/plugins/index.json
Public key see Signing and trust

ThemesAdmin → Appearance → Theme Market → Add source:

Field Value
Name alist-registry
Index URL https://raw.githubusercontent.com/AlistGo/alist-registry/main/dist/themes/index.json
Public key optional — blank installs everything as untrusted

Both files are generated by CI from plugins/ and themes/ (publish.yml) and committed back to main on every merge.

Index schema

Both index files mirror alist-org/alist's Go structs field-for-field; CI enforces this on every pull request.

Plugin index entry

Mirrors internal/extension/index.go's IndexEntry — an array of these is what GET .../plugins/sources fetches and extension.FetchIndex parses.

Field Type Required Notes
id string yes reverse-domain, ^[a-zA-Z0-9][a-zA-Z0-9._-]*$, no .. — must match plugin.json's own id
name string yes display name
version string yes plain MAJOR.MINOR.PATCH
kind string yes one ext.Kind value, e.g. StorageDriver
core_api string yes semver constraint, e.g. ^0.1.0
sha256 string yes hex sha256 of the .tar.gz at url
url string yes https:// download URL of the package
sig string no base64 detached signature, informational only — the backend does not check it against the downloaded bytes at install time
license string yes must be open-source; proprietary (or any closed license) is refused
source_url string yes a missing source_url is treated as closed-source
pricing string yes free or paid; paid is refused

Signature verification happens inside the .tar.gz, not against this index's sha256/sig fields. Every package is a directory containing plugin.json, its binary, checksums.txt (a sha256 manifest of every other file), and signature (an ed25519 signature over checksums.txt, produced by alist plugin sign). extension.TieredVerifier.DetermineTier reads checksums.txt/signature from inside the downloaded archive at install time, never the index entry's sha256/sig. A package with no checksums.txt/signature inside it installs as third-party (🔴) regardless of what the index says about it. This repository's CI still checks sha256 against the real downloaded bytes to catch a stale or wrong entry, but that check belongs to this registry, not to the AList backend.

Theme catalog entry

Mirrors internal/thememarket/thememarket.go's CatalogEntry — an array of these is what a theme source's index URL serves.

Field Type Required Notes
id string yes the catalog entry's own id, a distinct namespace from the downloaded descriptor's own "id" field
name string no display name
author string no
version string no if present, use plain MAJOR.MINOR.PATCH so update/rollback comparisons are well-defined
url string yes https:// URL of the theme's JSON descriptor
sha256 string yes hex sha256 of the descriptor at url — enforced by the backend at install time (thememarket.DownloadTheme)
preview string no https:// preview image URL
has_js bool no whether the descriptor carries a non-blank js field
mode string no light, dark, or omitted — descriptive, never enforced
signature string no hex ed25519 signature over id|version|sha256|url (canonicalEntrySigningInput) — required and verified only if the source has a public key configured

A theme source's public key is optional (thememarket.Source.PubKey): with none configured, every theme from that source installs as untrusted. With one configured, every entry it serves must carry a verifying signature or installation is refused.

A theme descriptor itself only needs to parse as a JSON object with a non-empty string "id" field (ValidateDescriptor). Token colors, CSS sanitization, and JS gating are checked on the frontend at load time.

Repository layout

plugins/<plugin-id>/entry.json   one file per plugin, id = directory name
themes/<theme-id>/entry.json     one file per theme, id = directory name
themes/<theme-id>/theme.json     (optional) the theme descriptor, if hosted here
dist/plugins/index.json          generated: published plugin source index
dist/themes/index.json           generated: published theme source catalog
scripts/                         validator + index builder (Python, stdlib only)

dist/ is generated by CI and committed back to main on every merge — do not hand-edit it.

Signing and trust

This registry's ed25519 public key, for entries a maintainer has reviewed and signed personally:

44447605a7bc68e1a4acca29d1d4d3bfb21575fc83d432a18d731de50d5da158

The matching private key is not in this repository and not a CI secret; it is held offline and used manually for packages a maintainer has rebuilt from source and reviewed. Most entries in plugins/ are not signed by this key and install as third-party (🔴), the same tier as any URL-installed plugin. Ask for a review in your pull request if you want one — signing is never automatic.

plugins/com.example.demoplugin is signed with this key, to exercise the format and the verified-tier install path.

Contributing

See CONTRIBUTING.md for how to submit a plugin or theme, or open an issue from .github/ISSUE_TEMPLATE/ first.

Validation and CI

scripts/validate.py checks every entry.json: required fields, https://-only URLs, a real sha256 match against the downloaded package/descriptor, strict MAJOR.MINOR.PATCH versions, valid plugin ids/kinds, and — given a git ref to diff against — that an update never lowers a version.

python3 scripts/validate.py            # full check, including downloads
python3 scripts/validate.py --no-hash  # schema-only, no network access

scripts/build_index.py aggregates every entry into dist/plugins/index.json / dist/themes/index.json. CI runs this on every push to main after validation passes.

License

MIT.

About

Community plugin and theme index for AList v4

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages