Appearance
Packaging and signing
Package
To give your extension to someone, package it. With its folder loaded (see Developing from a folder), open the app's ⋯ menu and choose Package…. Sorus writes one file, <id>-<version>.pagesapp.
They install it with + beside Apps › Install from a file…. Sorus shows what it brings and builds on, and lets them map your types onto theirs, before installing.
A .pagesapp is a JSON file holding every file of the extension:
json
{ "format": "pages-app", "version": 1, "files": { "manifest.json": "<base64>", "…": "…" } }Updates
Bump version and package again. Installing a newer version over an older one updates it, keeping the person's objects; Sorus refuses to replace a version with an older one. An update that asks for more needs approving again; see Permissions.
Installed extensions live in the workspace, so they sync to the person's other devices.
Signing
Extensions made by Sorus are signed with its key, which earns them the trusted tier. The signature is signature.json, at the top of the folder:
json
{ "keyId": "pages-2026", "digest": "<hex>", "signature": "<base64>" }digestis a SHA-256 over every other file: for each file, sorted by path, the linepath\0<sha-256 of the file, hex>\n.signatureis an Ed25519 signature of the digest, by the keykeyIdnames.
When Sorus reads an extension:
- no
signature.json: unsigned, so sandboxed; - a signature that matches, by a key Sorus trusts: signed;
- a key Sorus doesn't know, or files changed after signing: a package is refused. A folder being developed just reads as unsigned.
In the pages-apps repository, node scripts/sign.mjs signs every extension, or node scripts/sign.mjs movies one. The private key lives outside the repositories, in ../.signing/ or wherever $PAGES_SIGNING_KEY points.