Manifest overview
Every AppOS plugin keeps its plugin.json manifest at the plugin root — in
the dev tree and in the installed plugin directory alike. The one exception is
a catalog-published zip, which nests the runtime manifest at
appos/runtime/plugin.json until the installer copies it to the root at
install time — see Catalog bundle layout below. The
manifest declares the plugin’s identity, when it activates, which permissions
it needs, and any system or plugin dependencies.
The manifest is validated against the JSON Schema at
schemas/plugin-v1.json.
Add a $schema reference for editor autocomplete:
{ "$schema": "https://appos.space/schemas/plugin-v1.json", "id": "com.example.my-plugin", "name": "My Plugin", "version": "1.0.0", "runtime": "javascript", "entrypoint": "dist/main.js"}Required fields
Section titled “Required fields”id, name, version, and runtime are always required. Plugins with
"runtime": "javascript" (all third-party plugins) must also declare
entrypoint. "core-swift" is reserved for host-bundled core plugins.
Key sections
Section titled “Key sections”- Field reference — every manifest field, generated from the JSON Schema.
- Permission scopes — the full catalog of
scopes accepted in
permissions, generated from the SDK’s machine-readable constraints. - Limits — host-enforced runtime quotas (storage, shell, network, and more).
- Extension points — the
extensions[]array for contributing to core-plugin extension points.
Catalog bundle layout
Section titled “Catalog bundle layout”A dev tree keeps plugin.json at the plugin root — that is what local and
sideload installs load. Bundles published to the AppOS catalog use AppOS
Catalog Bundle Layout v1, which carries TWO manifests because the catalog’s
submit validation and the desktop installer read different schemas:
manifest.jsonat the zip root — the catalogmanifest-v1document (schema,slug,kind,version,title,license,capabilities,permissions,compatibility,entry; unknown keys rejected). Validated at publish time.appos/runtime/plugin.json— the AppOS runtime manifest (the schema documented on these pages). Read by the desktop app at install time.
space-appos-myplugin-1.0.0.zip├── manifest.json # catalog manifest-v1├── appos/│ └── runtime/│ └── plugin.json # AppOS runtime manifest (this schema)├── dist/│ └── main.js # runtime payload at the zip root└── webview/ assets/ README.md LICENSE ...Rules:
- Installer resolution is root-first. A root
plugin.jsonalways wins; otherwise the desktop installer consults the single well-known fallbackappos/runtime/plugin.jsonand copies it to the bundle root at install time (“normalize-at-install”); neither present fails the install withmanifestMissing. There is no globbing — the fallback is one constant path. - Verification precedes manifest resolution. SHA-256 (both install paths) and, on the catalog install path, the publisher-verified gate plus Ed25519 signature verification all run before extraction — the hash and signature checks cover the exact zip bytes, so no manifest is read until verification passes.
- Exactly one catalog-manifest candidate. Nothing named
plugin.jsonormanifest.jsonmay exist at the zip root or one level deep except the single catalog manifest — the submit scan rejects zero candidates (no_manifest) and more than one (ambiguous_bundle_root). Depth 2 keeps the runtime manifest invisible to that scan. - Runtime-manifest paths are relative to the ZIP ROOT, not to
appos/runtime/— e.g."entrypoint": "dist/main.js". - A dev-layout bundle (root
plugin.json, nomanifest.json) installs locally but is NOT publishable to the catalog: its rootplugin.jsonwould be selected as the catalog-manifest candidate and failmanifest-v1validation (manifest_invalid).
Validation
Section titled “Validation”This repo ships a validator for the runtime plugin.json manifest only —
it checks against schemas/plugin-v1.json, the schema documented on these
pages:
node scripts/validate-schema.mjs path/to/plugin.jsonThe catalog manifest.json at the zip root uses a different schema — catalog
manifest-v1 — and has no local validator in this repo, so don’t point
validate-schema.mjs at it: you’d get irrelevant runtime-schema errors.
Catalog manifests are validated server-side at publish time — the submit step
re-extracts manifest.json from your uploaded zip and validates it strictly
(unknown keys rejected; schema, slug, title, and entry required).
Failures surface as manifest_invalid errors in the publish API’s
prepare → submit response.