// publishing
Publish an extension
An extension is a single JavaScript file that runs inside the Nullock proxy. Getting it into the catalog is a pull request plus one script — you never hand-edit the integrity fields.
1. Add a catalog entry
Open a PR against extensions/marketplace.json with your entry. Leave sha256 and permissions empty — the sync script fills them.
{
"id": "my-extension",
"name": "My Extension",
"summary": "One sentence describing what it does.",
"version": "0.1.0",
"author": "your-github-handle",
"categories": ["scanner", "passive"],
"url": "https://raw.githubusercontent.com/<you>/<repo>/<tag>/<path>.js",
"hooks": ["nullock.onResponse"]
}
2. Generate the integrity fields
Run the sync script. It hashes the committed .js, reads the // nullock:permissions directive out of your source, and rewrites both fields. CI runs it with --check and fails the build if what you committed does not match.
bash scripts/marketplace_sync.sh
Rules that matter
- Pin the url to a tag or commit, never a branch. Branch content can change after the hash is computed, and the next person to install then gets an integrity failure.
- Declare permissions honestly. You gain nothing by omitting them — Nullock reads the
// nullock:permissionsdirective out of your script regardless, and an undeclared capability is surfaced to the user as a warning at install time. - Keep it to pure JS. The engine is a QJSEngine sandbox with no filesystem, no network of its own, and no npm. Anything that can rewrite traffic (
nullock.onRequest) needs themodify-requestsgrant. - Add a version directive —
// nullock:version 0.1.0— so Nullock can tell an installed copy from an update.
Why the sha256 is generated, not typed
That hash is the only thing between a compromised CDN and arbitrary code running inside someone's proxy. A hand-typed hash drifts the moment anyone touches the file, and a drifted hash breaks every install — at which point the tempting fix is to stop verifying. So it is generated and CI-checked, never authored by hand.