Developer SDK for Marginalia packages.
This repo defines the shared contract between package authors, the firmware, and the registry/hub:
- manifest schema
- package kinds and execution classes
- permissions vocabulary
- compatibility rules
- reference package structure
This is the v1 contract for the Xteink X3/X4 firmware line.
Marginalia packages are either:
static: validated manifest data with no executable package runtimemodule: loaded into the firmware host for themes, sleep screens, reader hooks, widgets, and integrationsapp: a standalone experience with its own navigation lifecycle
Package kinds:
themesleep_screenreader_moduleintegrationapp
Packages can also declare static contributes entries for firmware-visible extension points. The first contribution
point is catalog.providers, which lets integration packages add OPDS/RWPM-style catalog providers without adding a
new firmware feature for each provider. Static contribution packages should use execution: "static" and do not need
runtime entrypoints.
schema/manifest.v1.schema.jsonschema/theme.v1.schema.jsondocs/package-contract.mddocs/community-sdk.md
python3 tools/validate_manifest.py path/to/manifest.jsonThe default local profile matches what current firmware accepts for SD/Wi-Fi side loading. Use the stricter publish
profile for packages that are ready for a registry or hub:
python3 tools/validate_manifest.py --profile publish path/to/manifest.jsonpython3 tools/create_package.py org.example.hangman "Hangman" --kind app --output ./packagesThe command writes a side-loadable package folder with:
manifest.jsonREADME.mdsrc/entrypoints.json
Use --profile local for the smallest manifest accepted by current firmware. Use the default publish profile when the
package is meant to become a registry or hub entry.
python3 tools/build_package.py ./packages/hangman --output ./dist --jsonThe builder validates the manifest, rejects paths the firmware side-loader would reject, creates a deterministic package archive name, and prints the SHA-256 checksum that registry and hub entries should publish.
Firmware-safe archives are capped at 96 files, 512 KiB total uncompressed data, 128 KiB per file, and 180 bytes per relative archive path.
python3 tools/build_catalog_entry.py ./packages/hangman \
--archive-output ./dist \
--entry-output ./entries/org.example.hangman.json \
--artifact-url https://example.org/org.example.hangman-0.1.0.mpkg.zip \
--source-url https://github.com/example/marginalia-packages.git \
--source-ref v0.1.0 \
--source-path hangmanThe command builds the .mpkg.zip, computes its checksum and size, and writes a catalog entry shaped for
marginalia-registry. The source fields make registry entries reviewable in the same spirit as RT-Thread package
metadata: the artifact is what firmware installs, while the source repository and ref are what humans inspect.