Files
wehub-resource-sync b3a7f98e5a
CI / E2E Cloudflare (4/8) (push) Failing after 0s
CI / E2E Cloudflare (8/8) (push) Failing after 1s
CI / Lint (push) Failing after 1s
Auto Extract / Extract (push) Failing after 4s
CI / Version Check (push) Failing after 9s
CI / Integration Tests (push) Failing after 1s
CI / E2E tests (1/8) (push) Failing after 1s
CI / E2E tests (2/8) (push) Failing after 2s
CI / E2E tests (3/8) (push) Failing after 2s
CI / Browser Tests (push) Failing after 1s
CI / E2E tests (5/8) (push) Failing after 1s
CI / E2E Cloudflare (2/8) (push) Failing after 2s
CI / Typecheck (push) Failing after 1s
CI / Changeset Validation (push) Failing after 2s
CI / E2E Cloudflare (5/8) (push) Failing after 1s
CI / E2E Cloudflare (6/8) (push) Failing after 1s
CI / E2E Cloudflare (7/8) (push) Failing after 1s
CodeQL / Analyze (javascript-typescript) (push) Failing after 1s
Format / Format (push) Failing after 0s
CodeQL / Analyze (actions) (push) Failing after 4s
CI / E2E tests (4/8) (push) Failing after 1s
CI / E2E tests (6/8) (push) Failing after 1s
CI / E2E tests (7/8) (push) Failing after 2s
CI / E2E tests (8/8) (push) Failing after 1s
CI / E2E Cloudflare (1/8) (push) Failing after 1s
CI / E2E Cloudflare (3/8) (push) Failing after 2s
Preview Releases / Publish Preview (push) Failing after 0s
zizmor / Run zizmor (push) Failing after 1s
Release / Release (push) Failing after 2s
CI / Smoke Tests (push) Failing after 5m36s
CI / Tests (push) Failing after 6m36s
Release / Sync Templates (push) Has been skipped
CI / E2E Tests (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:23:53 +08:00

655 lines
16 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://emdashcms.com/schemas/emdash-plugin.schema.json",
"title": "EmDash plugin manifest",
"description": "Hand-authored manifest for publishing a plugin to the EmDash plugin registry. Lives next to the plugin's `package.json` as `emdash-plugin.jsonc`.",
"type": "object",
"properties": {
"$schema": {
"$ref": "#/$defs/__schema0"
},
"slug": {
"$ref": "#/$defs/__schema1"
},
"version": {
"$ref": "#/$defs/__schema2"
},
"license": {
"$ref": "#/$defs/__schema3"
},
"publisher": {
"$ref": "#/$defs/__schema4"
},
"capabilities": {
"$ref": "#/$defs/__schema5"
},
"allowedHosts": {
"$ref": "#/$defs/__schema7"
},
"storage": {
"$ref": "#/$defs/__schema9"
},
"admin": {
"$ref": "#/$defs/__schema16"
},
"author": {
"$ref": "#/$defs/__schema27"
},
"authors": {
"$ref": "#/$defs/__schema32"
},
"security": {
"$ref": "#/$defs/__schema33"
},
"securityContacts": {
"$ref": "#/$defs/__schema37"
},
"name": {
"$ref": "#/$defs/__schema38"
},
"description": {
"$ref": "#/$defs/__schema39"
},
"keywords": {
"$ref": "#/$defs/__schema40"
},
"sections": {
"$ref": "#/$defs/__schema42"
},
"repo": {
"$ref": "#/$defs/__schema52"
},
"release": {
"$ref": "#/$defs/__schema53"
}
},
"required": [
"slug",
"license",
"publisher",
"capabilities",
"allowedHosts",
"storage"
],
"additionalProperties": false,
"$defs": {
"__schema0": {
"type": "string",
"description": "Path or URL to the JSON Schema describing this file. Editors use this for completion and validation."
},
"__schema1": {
"type": "string",
"minLength": 1,
"maxLength": 64,
"pattern": "^[a-z][a-z0-9_-]*$",
"title": "Slug",
"description": "URL-safe plugin identifier within the publisher's namespace. ASCII letter then letters/digits/hyphens/underscores, max 64 characters. Combined with the publisher DID, this is the registry's primary key.",
"examples": [
"gallery",
"image-resizer",
"my-plugin"
]
},
"__schema2": {
"type": "string",
"minLength": 1,
"maxLength": 64,
"pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?$",
"title": "Version",
"description": "Plugin version. Semver 2.0 subset; build-metadata `+...` is disallowed (the atproto record-key alphabet has no `+`). Bumped on every release.",
"examples": [
"0.1.0",
"1.2.3",
"1.0.0-rc.1"
]
},
"__schema3": {
"type": "string",
"minLength": 1,
"maxLength": 256,
"title": "License",
"description": "SPDX license expression (e.g. \"MIT\", \"Apache-2.0\", \"MIT OR Apache-2.0\"). Required on first publish; ignored on subsequent publishes (the existing profile wins).",
"examples": [
"MIT",
"Apache-2.0",
"MIT OR Apache-2.0"
]
},
"__schema4": {
"type": "string",
"title": "Publisher",
"description": "Atproto DID or handle of the publishing identity. Pinned on first publish to prevent accidental publishes from a different account. DIDs are recommended (durable); handles work but are mutable.",
"examples": [
"did:plc:abc123def456",
"example.com"
]
},
"__schema5": {
"default": [],
"maxItems": 32,
"type": "array",
"items": {
"$ref": "#/$defs/__schema6"
},
"title": "Capabilities",
"description": "Trust contract: what runtime APIs the plugin is allowed to use. Changing this between releases requires a version bump because installed users have consented to the old contract."
},
"__schema6": {
"type": "string",
"minLength": 1
},
"__schema7": {
"default": [],
"maxItems": 64,
"type": "array",
"items": {
"$ref": "#/$defs/__schema8"
},
"title": "Allowed hosts",
"description": "Allow-list of outbound host patterns when `network:request` is declared. Subdomain wildcards use a leading `*.`. Required (non-empty) when `network:request` is declared without `network:request:unrestricted`.",
"examples": [
[
"api.example.com",
"*.cdn.example.com"
]
]
},
"__schema8": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"__schema9": {
"default": {},
"type": "object",
"propertyNames": {
"$ref": "#/$defs/__schema10"
},
"additionalProperties": {
"$ref": "#/$defs/__schema11"
},
"title": "Storage",
"description": "Storage collections the plugin uses. Each collection is namespaced to this plugin at runtime."
},
"__schema10": {
"type": "string",
"minLength": 1,
"pattern": "^[a-z][a-z0-9_]*$"
},
"__schema11": {
"type": "object",
"properties": {
"indexes": {
"$ref": "#/$defs/__schema12"
},
"uniqueIndexes": {
"$ref": "#/$defs/__schema14"
}
},
"required": [
"indexes"
],
"additionalProperties": false,
"title": "Storage collection",
"description": "Index configuration for a single storage collection. Indexes are either single field names or composite (array of field names)."
},
"__schema12": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"minItems": 1,
"type": "array",
"items": {
"$ref": "#/$defs/__schema13"
}
}
]
}
},
"__schema13": {
"type": "string",
"minLength": 1
},
"__schema14": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"minItems": 1,
"type": "array",
"items": {
"$ref": "#/$defs/__schema15"
}
}
]
}
},
"__schema15": {
"type": "string",
"minLength": 1
},
"__schema16": {
"type": "object",
"properties": {
"pages": {
"$ref": "#/$defs/__schema17"
},
"widgets": {
"$ref": "#/$defs/__schema22"
}
},
"additionalProperties": false,
"title": "Admin surface",
"description": "Pages and widgets the plugin exposes in the admin UI. The plugin's `admin` route handler renders Block Kit content for each path / widget id at runtime."
},
"__schema17": {
"maxItems": 32,
"type": "array",
"items": {
"$ref": "#/$defs/__schema18"
}
},
"__schema18": {
"type": "object",
"properties": {
"path": {
"$ref": "#/$defs/__schema19"
},
"label": {
"$ref": "#/$defs/__schema20"
},
"icon": {
"$ref": "#/$defs/__schema21"
}
},
"required": [
"path",
"label"
],
"additionalProperties": false,
"title": "Admin page",
"description": "A single admin page declaration. The plugin's `admin` route handler is responsible for rendering Block Kit content for this path."
},
"__schema19": {
"type": "string",
"minLength": 2,
"maxLength": 128,
"pattern": "^\\/[a-z0-9][a-z0-9/_-]*$"
},
"__schema20": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"__schema21": {
"type": "string",
"minLength": 1,
"maxLength": 64
},
"__schema22": {
"maxItems": 32,
"type": "array",
"items": {
"$ref": "#/$defs/__schema23"
}
},
"__schema23": {
"type": "object",
"properties": {
"id": {
"$ref": "#/$defs/__schema24"
},
"title": {
"$ref": "#/$defs/__schema25"
},
"size": {
"$ref": "#/$defs/__schema26"
}
},
"required": [
"id"
],
"additionalProperties": false,
"title": "Admin widget",
"description": "A single dashboard widget declaration."
},
"__schema24": {
"type": "string",
"minLength": 1,
"maxLength": 64,
"pattern": "^[a-z][a-z0-9_-]*$"
},
"__schema25": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"__schema26": {
"type": "string",
"enum": [
"full",
"half",
"third"
]
},
"__schema27": {
"$ref": "#/$defs/__schema28"
},
"__schema28": {
"type": "object",
"properties": {
"name": {
"$ref": "#/$defs/__schema29"
},
"url": {
"$ref": "#/$defs/__schema30"
},
"email": {
"$ref": "#/$defs/__schema31"
}
},
"required": [
"name"
],
"additionalProperties": false,
"title": "Author",
"description": "A single author entry. Mirrors the lexicon's author shape."
},
"__schema29": {
"type": "string",
"minLength": 1,
"maxLength": 256,
"description": "Display name."
},
"__schema30": {
"type": "string",
"maxLength": 1024,
"format": "uri",
"description": "Author's homepage or profile URL. Either this or `email` is recommended."
},
"__schema31": {
"type": "string",
"maxLength": 256,
"format": "email",
"pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
"description": "Author's contact email. Either this or `url` is recommended."
},
"__schema32": {
"minItems": 1,
"maxItems": 32,
"type": "array",
"items": {
"$ref": "#/$defs/__schema28"
},
"title": "Authors (multiple)",
"description": "Multi-author form. Mutually exclusive with `author`. Use the singular `author` if there is only one."
},
"__schema33": {
"$ref": "#/$defs/__schema34"
},
"__schema34": {
"type": "object",
"properties": {
"url": {
"$ref": "#/$defs/__schema35"
},
"email": {
"$ref": "#/$defs/__schema36"
}
},
"additionalProperties": false,
"title": "Security contact",
"description": "A single security contact. At least one of `url` or `email` must be present."
},
"__schema35": {
"type": "string",
"maxLength": 1024,
"format": "uri",
"description": "Security disclosure URL (e.g. a security.txt or vulnerability-reporting page). Either this or `email` is required."
},
"__schema36": {
"type": "string",
"maxLength": 256,
"format": "email",
"pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
"description": "Security contact email. Either this or `url` is required."
},
"__schema37": {
"minItems": 1,
"maxItems": 8,
"type": "array",
"items": {
"$ref": "#/$defs/__schema34"
},
"title": "Security contacts (multiple)",
"description": "Multi-contact form. Mutually exclusive with `security`. Use the singular `security` if there is only one."
},
"__schema38": {
"type": "string",
"minLength": 1,
"maxLength": 1024,
"title": "Display name",
"description": "Human-readable name shown in directory listings. Defaults to the plugin's `id` when omitted."
},
"__schema39": {
"type": "string",
"minLength": 1,
"maxLength": 1024,
"title": "Description",
"description": "Short description (<= 140 graphemes by FAIR convention). Aggregators may truncate longer values when displaying in compact lists."
},
"__schema40": {
"maxItems": 5,
"type": "array",
"items": {
"$ref": "#/$defs/__schema41"
},
"title": "Keywords",
"description": "Search keywords (<= 5 entries, FAIR convention)."
},
"__schema41": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"__schema42": {
"type": "object",
"properties": {
"description": {
"$ref": "#/$defs/__schema43"
},
"installation": {
"$ref": "#/$defs/__schema48"
},
"faq": {
"$ref": "#/$defs/__schema49"
},
"changelog": {
"$ref": "#/$defs/__schema50"
},
"security": {
"$ref": "#/$defs/__schema51"
}
},
"additionalProperties": false,
"title": "Profile sections",
"description": "Long-form package documentation (description / installation / faq / changelog / security). Each value is CommonMark Markdown (inline or a `{ file }` ref) capped at 20000 bytes / 2000 graphemes. Rendered on the package's registry page."
},
"__schema43": {
"$ref": "#/$defs/__schema44"
},
"__schema44": {
"anyOf": [
{
"$ref": "#/$defs/__schema45"
},
{
"$ref": "#/$defs/__schema46"
}
],
"title": "Section value",
"description": "Either inline CommonMark Markdown or a `{ file }` reference to a sibling Markdown file."
},
"__schema45": {
"type": "string",
"description": "Inline CommonMark Markdown for this section. Capped at 20000 bytes / 2000 graphemes."
},
"__schema46": {
"type": "object",
"properties": {
"file": {
"$ref": "#/$defs/__schema47"
}
},
"required": [
"file"
],
"additionalProperties": false,
"title": "Section file reference",
"description": "Loads the section's Markdown from a sibling file instead of inlining it in the manifest."
},
"__schema47": {
"type": "string",
"minLength": 1,
"maxLength": 1024,
"description": "Path to a CommonMark Markdown file, relative to the manifest. Its content is read inline into the section at publish time."
},
"__schema48": {
"$ref": "#/$defs/__schema44"
},
"__schema49": {
"$ref": "#/$defs/__schema44"
},
"__schema50": {
"$ref": "#/$defs/__schema44"
},
"__schema51": {
"$ref": "#/$defs/__schema44"
},
"__schema52": {
"type": "string",
"maxLength": 1024,
"format": "uri",
"pattern": "^https:\\/\\/",
"title": "Source repository",
"description": "HTTPS URL of the plugin's source repository. Surfaced in registry listings.",
"examples": [
"https://github.com/emdash-cms/plugin-gallery"
]
},
"__schema53": {
"type": "object",
"properties": {
"requires": {
"$ref": "#/$defs/__schema54"
},
"artifacts": {
"$ref": "#/$defs/__schema57"
}
},
"additionalProperties": false,
"title": "Release",
"description": "Per-release fields: environment constraints (`requires`) and media artifacts (icon / screenshot / banner)."
},
"__schema54": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/__schema55"
},
"additionalProperties": {
"$ref": "#/$defs/__schema56"
},
"title": "Environment requirements",
"description": "Host environment constraints for this release, keyed by `env:*` (e.g. \"env:astro\", \"env:emdash\") with semver-range values. EmDash refuses to install a release whose constraints the host does not satisfy.",
"examples": [
{
"env:emdash": ">=1.0.0",
"env:astro": ">=4.16"
}
]
},
"__schema55": {
"type": "string"
},
"__schema56": {
"type": "string",
"minLength": 1
},
"__schema57": {
"type": "object",
"properties": {
"icon": {
"$ref": "#/$defs/__schema58"
},
"banner": {
"$ref": "#/$defs/__schema62"
},
"screenshots": {
"$ref": "#/$defs/__schema63"
}
},
"additionalProperties": false,
"title": "Artifacts",
"description": "Release media artifacts. `icon` and `banner` are single images; `screenshots` is a gallery array."
},
"__schema58": {
"$ref": "#/$defs/__schema59"
},
"__schema59": {
"type": "object",
"properties": {
"file": {
"$ref": "#/$defs/__schema60"
},
"lang": {
"$ref": "#/$defs/__schema61"
}
},
"required": [
"file"
],
"additionalProperties": false,
"title": "Artifact file reference",
"description": "A media file (PNG / JPEG / WebP / GIF / AVIF) bundled into a release as an icon, screenshot, or banner."
},
"__schema60": {
"type": "string",
"minLength": 1,
"maxLength": 1024,
"description": "Path to the image file, relative to the manifest. Resolved, hashed, measured, and uploaded at publish time."
},
"__schema61": {
"type": "string",
"minLength": 2,
"maxLength": 64,
"description": "BCP 47 language tag for a localised artifact (e.g. \"en\", \"pt-BR\").",
"examples": [
"en",
"pt-BR"
]
},
"__schema62": {
"$ref": "#/$defs/__schema59"
},
"__schema63": {
"minItems": 1,
"maxItems": 8,
"type": "array",
"items": {
"$ref": "#/$defs/__schema59"
},
"title": "Screenshots",
"description": "Screenshot gallery for the plugin's detail page (<= 8 entries)."
}
}
}