You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Composability testing across the plugins collection (33 plugins) surfaced a pattern: the loader knows almost nothing about a plugin until activate() is already running, so every mismatch is discovered by crashing.
Observed while trial-composing on one server:
20 of 33 plugins hard-require config (18 need config.baseUrl; terminal correctly refuses to boot an open shell without auth config). The only way to discover this is to boot and read the throw — and boot is fail-closed, so one missing config key = no server. It took four boot attempts to find a 13-plugin set that co-loads (which then ran conflict-free — isolation is in good shape; discoverability is the gap).
The roster (api.plugins) carries only { id, prefix, module }, so meta-plugins like admin/dashboard can enumerate siblings but can't describe them.
Proposal: an optional exported meta object that plugins declare and the loader reads before calling activate():
exportconstmeta={name: 'gamestr',// stable id — solves #614 explicitly, no path heuristicsdescription: 'Points system: bump / day aggregation / stream over hour files',version: '0.1.0',jss: '>=0.0.219',// engine compat rangeconfig: {// declared config surfacebaseUrl: {required: true,description: 'Public origin for absolute URLs in feeds/JRDs'},token: {required: false,description: 'Shared secret for privileged routes'},},}
Loader behavior, all backwards-compatible (no meta = exactly today's behavior):
Pre-activate validation — required config missing produces one precise boot error naming the plugin, the key, and its description (instead of whatever the plugin's own throw says), or a skip-with-warning if a lenient mode ever exists.
Roster enrichment — api.plugins entries carry description/version, so admin and dashboard can render a real catalog.
Downstream, not now: a declared-metadata convention is the enabler for an install story (jspod install <repo> reading the meta before mounting) and compat checks — WordPress's plugin header (Plugin Name: … Requires at least: …) is the 20-year precedent: that one convention made its directory, installer, and compatibility matrix possible.
Alternatives considered: a WordPress-style comment header (parseable without importing the module — nice for registries, but the loader imports anyway) or a plugin.json sidecar (keeps metadata out of code, but splits the plugin across two files). The exported object is the most natural fit for ESM and is trivially optional.
Deliberately filed as a marker/discussion, not a mandate — plugin conventions are still in an experimentation phase and this should be shaped by more plugin-building experience.
Composability testing across the plugins collection (33 plugins) surfaced a pattern: the loader knows almost nothing about a plugin until
activate()is already running, so every mismatch is discovered by crashing.Observed while trial-composing on one server:
config.baseUrl;terminalcorrectly refuses to boot an open shell without auth config). The only way to discover this is to boot and read the throw — and boot is fail-closed, so one missing config key = no server. It took four boot attempts to find a 13-plugin set that co-loads (which then ran conflict-free — isolation is in good shape; discoverability is the gap).pod/plugin.jsapp-repo layout defeats.api.plugins) carries only{ id, prefix, module }, so meta-plugins likeadmin/dashboardcan enumerate siblings but can't describe them.Proposal: an optional exported
metaobject that plugins declare and the loader reads before callingactivate():Loader behavior, all backwards-compatible (no
meta= exactly today's behavior):meta.namewins over path derivation for the id — fixes Plugin id derivation defeats the pod/plugin.js convention — every app derives id "pod" #614 without guessing at generic directory names.api.pluginsentries carrydescription/version, soadminanddashboardcan render a real catalog.jspod install <repo>reading the meta before mounting) and compat checks — WordPress's plugin header (Plugin Name: … Requires at least: …) is the 20-year precedent: that one convention made its directory, installer, and compatibility matrix possible.Alternatives considered: a WordPress-style comment header (parseable without importing the module — nice for registries, but the loader imports anyway) or a
plugin.jsonsidecar (keeps metadata out of code, but splits the plugin across two files). The exported object is the most natural fit for ESM and is trivially optional.Deliberately filed as a marker/discussion, not a mandate — plugin conventions are still in an experimentation phase and this should be shaped by more plugin-building experience.