Manifest and permissions
plugin.manifest.json tells the city who you are, where your experience lives and what it may ask for. We approve one exact combination of version, entry and permissions. Change any of them and the new release needs approval again.
Example
{
"schema": "zenclub.plugin/v1",
"id": "my-garden",
"name": "My garden",
"description": "Tend a small garden at your own pace.",
"coverLabel": "A small garden",
"version": "1.0.0",
"sdkProtocol": "zenclub.rpc/1",
"hostApi": {"major": 1, "minMinor": 2},
"entry": "https://my-garden.example/v1.0.0/",
"permissions": ["lifecycle.report", "storage.read", "storage.write", "session.report"],
"optionalPermissions": ["moments.create", "header.setActions"],
"modes": ["watch", "manual"],
"tags": ["garden", "slow"]
}Fields
| Field | Rule |
|---|---|
schema | Always zenclub.plugin/v1. |
id | 1 to 80 letters, digits, dots, underscores or hyphens, starting with a letter or digit. Never changes. |
name, description, coverLabel | Plain text up to 2048 characters each. coverLabel is the short caption on your cover. |
version | Semantic version, such as 1.4.0 or 1.5.0-beta.1. It must match the version you pass to connect(). |
sdkProtocol | Always zenclub.rpc/1. |
hostApi | The lowest host API you need, as {major, minMinor}. Ask for the lowest minor that works. |
entry | Absolute HTTPS URL of your page, with no user name, password or hash. Plain HTTP is accepted only on localhost. It must not share the platform's origin. |
permissions | Capabilities your experience cannot work without. No duplicates. |
optionalPermissions | Up to 32 capabilities you use when they are granted. Never repeat a required one. |
milestones | Optional: one fixed key, rule version and maximum tier, separately approved by the operator together with the reporting capability. |
modes | One or more of watch, manual and listen. You can only report a mode you declare. |
tags | Up to 10 tags of 32 characters or fewer. |
Capabilities
Each SDK method is a capability. A call to one that was not granted fails with FORBIDDEN before it leaves your frame. Check optional ones with sdk.supports(name) first.
| Capability | Host API | Use |
|---|---|---|
lifecycle.report | 1.0 | Report loading, ready or failed. |
storage.read | 1.0 | Read a save slot. |
storage.write | 1.0 | Write a save slot with a revision check. |
session.report | 1.0 | Report running, paused or ended for time measurement. |
runs.finish | 1.0 | Record a finished or restarted run with up to 20 numeric metrics. |
moments.create | 1.0 | Offer the visitor a picture to keep. The platform may ask them first. |
achievements.request | 1.0 | Ask the platform to verify and award a badge. |
counters.add | 1.2 | Add to a shared tally the operator has defined for you. |
events.report | 1.2 | Report a short named event, such as a finished chapter. |
shares.request | 1.2 | Open the platform's share sheet for a badge or for your experience. |
navigation.exit | 1.2 | Leave quietly to your experience's detail page. |
display.immersive | 1.3 | Ask the platform to hide its frame around you. |
header.setActions | 1.4 | Place your actions in the platform header. |
milestones.report | 1.6 | Report one approved private-city decoration from a confirmed save, when the player has enabled recording. |
Validate before you ask
The command-line tool runs the same checks as the platform and confirms that the host API you ask for is available. Validation does not grant anything. Only an approval does.
npx zenclub-plugin validate plugin.manifest.json --host=https://zenclub.appHost API versions
The current host API is 1.6, and it accepts plugins that ask for 1.0 to 1.6. Ask for the lowest minor you need and guard optional methods with sdk.supports(). To receive the sound preference, require 1.5 or later in both your manifest and connect(). Older plugins without milestone declarations receive the same grants and context as before.
Optional city milestones
Declare milestones.report as optional and add exactly one milestones entry. The first release has eight fixed keys: homestead, pond, clouds, bamboo, tea, stream, bell and lotus. Each rule version is its key followed by .1, with maxTier: 2. Approval pins that exact combination, version, entry and capability. Self-written declarations never grant access.
{
"hostApi": {"major": 1, "minMinor": 6},
"optionalPermissions": ["milestones.report"],
"milestones": [{"key": "tea", "ruleVersion": "tea.1", "maxTier": 2}]
}A plugin built with SDK 0.9 can keep an older minimum when reporting is optional. On a 1.0–1.5 host, without approval, or with device-only storage, keep normal gameplay and skip reporting. Older host approvals must omit the new grant. Required milestone reporting needs 1.6; recording must never become a prerequisite for play or login.