Skip to main content

Manifest

The timon field in package.json declares the plugin contract. The npm package uses type: "module"; main points to host code, when present, and exports["./client"] points to the browser entry.

FieldContract
idRequired; 3–40 lowercase letters, digits or hyphens in the current third-party validator
apiVersionRequired positive integer; minimum supported API contract
kindOne kind or a nonempty list; inferred from slots when absent
label, description, authorOptional nonempty display strings
coverOptional package-relative image path, not a remote URL
screenshotsAdditional package-relative images; default []
permissionsRequested capabilities; default []
client.slotsAdmitted UI surfaces; default []
client.externalExternal module declarations; default []
client.modeesm by default; schema also accepts iframe
declaresSlots opened for other components, mapped to single, list or keyed
routePage route; required for a page, forbidden otherwise
modifiesInformational list of affected surfaces; default []
containsChild manifest IDs for bundles only
settingsDeclarative fields: key, type, label, optional default
license.requiredWhether the licence must explicitly permit the plugin; default false

Slot names have lowercase alphanumeric dot-separated segments beginning with a letter. Routes start with /, use lowercase alphanumeric or hyphenated segments and contain no query or traversal. Covers and screenshots are confined to the package and accept PNG, WebP, JPG, JPEG or SVG paths.

Unknown manifest keys are ignored. Known fields with invalid values, incompatible kinds/slots or an API version newer than the daemon are refused. Use the real templates' ESM mode for browser plugins; an accepted schema option alone does not demonstrate an alternate runtime integration.

Shared browser modules

Keep these imports external to a browser bundle:

react
react-dom
@timon/ui
@timon/api
@timon/theme
@timon/navigate

For esbuild, use format: 'esm', bundle: true and an external array containing those exact specifiers. Do not embed another React instance. Include the built browser file in the published package: installation does not run lifecycle scripts.

Host entry

Export apply(ctx) and register routes or effects through the context. ctx.router() mounts routes beneath /api/plugins/<encoded-id>/ and removes them when the plugin unloads. The /-/ path prefix is reserved for platform endpoints.

If you export inject, it may name only kanban, missions, notify, storage, settings, events, http and host. It may not name db, bus or another internal service. Requested permissions are separate from dependency injection.