Developer platform · 3 / 9

Build a plugin: a theme first, then other kinds

Walk through “create plugin → generate project → check and preview → pack and sign” with a theme, then see how other kinds differ in manifest and upload files.

← All tutorials

Create the plugin on the seller site

“My plugins” → “Create plugin”: kind theme, an ID under your claimed namespace such as com.example.ocean, plus a Chinese name and summary. ID and kind cannot change later; the ID names the product, so keep version numbers out of it — 1.0.0 and 1.0.1 share one ID. Do not add prices or publish yet.

Get the theme tool

The theme tool cdnca-site-theme needs Node.js 22 LTS or later and has no dependencies. It currently ships with the development source; there is no public download or npm package yet. Ask for the theme tool package matching your control plane version (bin/, lib/, package.json and a readme) through “Contact” in the site footer, stating your control plane version and OS. You can register your key and create the plugin before it arrives.

CDNCA_THEME_TOOL="$(pwd -P)/bin/cdnca-site-theme.mjs"
test -f "$CDNCA_THEME_TOOL"

Generate the project

node "$CDNCA_THEME_TOOL" init "$PWD/ocean" \
  --template user+site \
  --plugin-id com.example.ocean \
  --name Ocean

cd ocean

Replace the sample ID with yours; --name may be a Chinese name. user+site generates both the user console and public site themes; use user or site for just one. The target directory must be empty.

FilePurpose
theme.config.jsonTheme settings and packing configuration
console-theme.jsonUser console theme (user template)
site/index.html, site/assets/Public site template and assets (site template)
auth/auth.cssSign-in page styles
content-schema.json, preview/content.jsonSite content schema and local preview content (site template)
plugin.manifest.jsonPlugin declaration and publisher details
schemas/config.schema.jsonFields the customer can configure
supply-chain/SBOM and build provenance

Edit the publisher name, support URL and Chinese description in plugin.manifest.json. supply-chain/ must describe your real dependencies and build; the sample values are not a declaration.

Check and preview locally

node "$CDNCA_THEME_TOOL" check
node "$CDNCA_THEME_TOOL" preview

check prints “预检通过 (N bytes)” on success and lists each problem with code and field, exiting 1. preview listens on 127.0.0.1:4173 by default (--port changes it), prints the address and keeps running until Ctrl+C. --screenshot captures the first screen as the preview image and exits. Local preview covers content and style only; sign-in, installation, real data and customer permissions are verified in a control plane.

Pack and sign

node "$CDNCA_THEME_TOOL" pack \
  --version 1.0.0 \
  --sign \
  --key "$CDNCA_PUBLISHER_KEY" \
  --cdnca-plugin "$CDNCA_PLUGIN_CLI"

pack writes the digests of content, configuration schema and supply-chain files into the manifest, then calls cdnca-plugin sign-manifest. Upload these three files from dist/:

  1. dist/manifest.signed.json: the signed manifest
  2. dist/schemas/config.schema.json: the configuration schema
  3. dist/theme.json: the theme content

How to confirm: the terminal prints the content, schema, manifest and signed lines, the three files exist, and the signed manifest shows the expected plugin ID, version, publisher and compatibility range (template default >=1.0.35 <2.0.0). The exit code alone is not enough; check those lines and files. A missing preview image is only a notice, but put a preview.webp (1200×750, up to 512 KiB) in the project root anyway.

Do not upload a zip of the project and do not edit files in dist/; change the sources and run check and pack again, or digests and signature will not match.

Other kinds: manifest and upload files

Kinds without the theme tool use a hand-written manifest per the plugin manifest schema, then sign-manifest. A manifest needs at least:

PartWhat to check
api_version, kindmarketplace.cdnca.io/v1 and Plugin
metadataPlugin ID, canonical SemVer without a leading v, Chinese name and summary, publisher ID/name/support URL
spec.compatibility.control_apiCompatible control plane versions
spec.entrypointThe single entrypoint that matches the kind
spec.permissionsThe minimum permissions actually needed
spec.configuration_schemaRelative path and SHA-256 of the configuration schema
spec.supply_chainSHA-256 of the real SBOM and provenance
integrityWritten by sign-manifest; do not edit
EntrypointFiles to upload
theme, rule_packSigned manifest, configuration schema, content file
ui_pageSigned manifest and configuration schema only; pages live on your verified HTTPS origin
external_httpsSigned manifest, configuration schema, 1–16 platform packages (field package:<platform>, e.g. package:linux-amd64)

Limits: manifest 256 KiB, configuration schema 64 KiB, theme and rule content 8 MiB, one platform package 64 MiB by default, a whole upload 200 MiB by default. Packages are zip, tar.gz or tar without path traversal, links or other unsafe entries. Each kind’s full fields, protocol and review rules are in its guide.