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

plugin.manifest.json
{
  "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

FieldRule
schemaAlways zenclub.plugin/v1.
id1 to 80 letters, digits, dots, underscores or hyphens, starting with a letter or digit. Never changes.
name, description, coverLabelPlain text up to 2048 characters each. coverLabel is the short caption on your cover.
versionSemantic version, such as 1.4.0 or 1.5.0-beta.1. It must match the version you pass to connect().
sdkProtocolAlways zenclub.rpc/1.
hostApiThe lowest host API you need, as {major, minMinor}. Ask for the lowest minor that works.
entryAbsolute 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.
permissionsCapabilities your experience cannot work without. No duplicates.
optionalPermissionsUp to 32 capabilities you use when they are granted. Never repeat a required one.
milestonesOptional: one fixed key, rule version and maximum tier, separately approved by the operator together with the reporting capability.
modesOne or more of watch, manual and listen. You can only report a mode you declare.
tagsUp 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.

CapabilityHost APIUse
lifecycle.report1.0Report loading, ready or failed.
storage.read1.0Read a save slot.
storage.write1.0Write a save slot with a revision check.
session.report1.0Report running, paused or ended for time measurement.
runs.finish1.0Record a finished or restarted run with up to 20 numeric metrics.
moments.create1.0Offer the visitor a picture to keep. The platform may ask them first.
achievements.request1.0Ask the platform to verify and award a badge.
counters.add1.2Add to a shared tally the operator has defined for you.
events.report1.2Report a short named event, such as a finished chapter.
shares.request1.2Open the platform's share sheet for a badge or for your experience.
navigation.exit1.2Leave quietly to your experience's detail page.
display.immersive1.3Ask the platform to hide its frame around you.
header.setActions1.4Place your actions in the platform header.
milestones.report1.6Report 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.

shell
npx zenclub-plugin validate plugin.manifest.json --host=https://zenclub.app

Host 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.

plugin.manifest.json
{
  "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.