MyronCMS Developers Hub Docs sandbox review

Core Concepts

Manifest Schema

manifest.json is the local identity and requested-capability declaration for an extension package. The loader parses it before registering actions, MIC resolvers, mail transports, admin routes, or migrations.

The recommended complete shape is:

{
  "vendor": "my_vendor",
  "name": "My Vendor Extension",
  "version": "0.1.0",
  "requiredScopes": ["content.read"],
  "hasMigrations": false,
  "adminRoutes": []
}

Human Path

Place the manifest at:

app/extensions/{vendor}/manifest.json

Use the same snake_case vendor in the directory and manifest. If the directory contains hyphens, the loader normalizes them to underscores before comparing against the manifest vendor. The reference directory myron-sample therefore maps to manifest vendor myron_sample.

AI Path

An AI coding agent may create and edit this file in the repository. It should prefer the complete manifest shape above even when the parser currently supplies defaults for some fields.

An installed MCP client does not write manifests. It can only interact with the runtime contributions that load after manifest parsing, registration, enablement, scope grants, and bootstrap registration succeed.

Field Reference

FieldTypeRecommendedCurrent parser behaviorFailure states
vendorstringRequiredTrimmed string; must match ^[a-z][a-z0-9_]*$ and equal the normalized directory vendor.Missing/empty/invalid vendor; vendor-directory mismatch.
namestringRequiredTrimmed string; must not be empty.Missing or empty name.
versionstringRequiredTrimmed string; must not be empty.Missing or empty version.
requiredScopeslist<string>Required in the recommended manifest shapeDefaults to [] when absent; must be an array when present; values must be in MyronApiScopes::ALL_BASE.Non-list value; unknown scope.
hasMigrationsbooleanRequired in the recommended manifest shapeDefaults to false when absent; coerced to boolean.No hard failure for absence.
adminRouteslist<object>Required in the recommended manifest shapeDefaults to [] when absent; must be an array when present; entries are normalized to key and path.Non-list value; non-object entry; invalid key; missing/absolute/traversing path.

The current parser does not hard-fail when requiredScopes, hasMigrations, or adminRoutes are omitted. The documentation still recommends including them so package intent is explicit and reviewable.

Scope Values

Manifest scopes are limited to the six base extension scopes:

ScopeMeaning
design.readRead design surfaces.
design.writeMutate design surfaces.
content.readRead content surfaces.
content.writeMutate content surfaces.
administration.readRead administration surfaces.
administration.writeMutate administration surfaces.

The manifest declares what the extension needs. The operator grant determines what the extension is allowed to load with.

Admin Route Entries

Each admin route entry uses:

{
  "key": "sample-hello",
  "path": "admin/routes/hello.php"
}

Route keys must match:

^[a-z][a-z0-9_-]*$

Route paths must be relative, non-empty, not absolute, and must not contain ...

Failure Modes

FailureSource enforcement
Manifest file missingExtensionManifest::fromFile()
Invalid JSONjson_decode() result check
Invalid vendor formatExtensionManifest::fromFile()
Vendor mismatchExtensionManifest::fromFile()
Missing nameExtensionManifest::fromFile()
Missing versionExtensionManifest::fromFile()
requiredScopes is not a listnormalizeScopes()
Unknown scopenormalizeScopes()
adminRoutes is not a listnormalizeAdminRoutes()
Admin route entry is not an objectnormalizeAdminRoutes()
Invalid route keynormalizeAdminRoutes()
Unsafe route pathnormalizeAdminRoutes()

Verification

Run:

php app/tests/verify-extension-system-foundation.php

The test confirms the sample manifest parses, vendor mismatches are rejected, and unknown manifest scopes are rejected.