Skip to content

Migrate optional features to the plugin system; define the core/plugin line #564

Description

@melvincarvalho

Follow-up to #206 (plugin system) and #164 (extract WebFinger/OAuth). The observation driving this: JSS's optional features are already pseudo-plugins — server.js registers each as an encapsulated Fastify plugin with options, gated by a createServer flag. The plugin system (#206) shouldn't be built and then have plugins written for it; it should formalize what eight features already do, then open the door to third parties.

The core/plugin line

Core (never plugins): LDP/storage, the auth chain (Bearer/DPoP/NIP-98), WAC. These ARE the pod — everything depends on them, and "disabling" them is just a broken server. Honest layering keeps them in src/.

Bundled plugins (migrate):

Feature Today Notes
notifications notificationsPlugin
ActivityPub activityPubPlugin + flag
webrtc webrtcPlugin + path option
terminal terminalPlugin security-sensitive — default off stays
tunnel tunnelPlugin
remoteStorage remoteStoragePlugin
MCP createServer({mcp: true}) its TOOLS table also becomes a plugin seam (#206)
IDP / WebFinger / OAuth idpPlugin exactly #164's ask

Migration mechanics (mostly mechanical)

  1. Each feature gains a jss.plugin.json ({id, version, entry}) pointing at the module that already exists; entry wraps the current Fastify plugin in activate(api) using api.fastify.
  2. createServer flags become plugins.entries.<id>.{enabled, config} — keep the old booleans as deprecated aliases for a transition window.
  3. Adopt openclaw's "bundled plugin" concept (shared with jsclaw): shipped in-tree, sensible defaults, but loaded through the same machinery as external plugins — so plugins list shows them, allow/deny applies, and the loader has eight battle-tested consumers from day one.
  4. The features themselves are the test suite: behavior must be byte-identical behind the new loading path.

Ordering

  1. Plugin system for JSS #206 loader lands (manifest, policy, api.fastify)
  2. One low-risk migration proves it (tunnel or remoteStorage)
  3. Extract WebFinger and OAuth into standalone always-on plugins #164 (IDP/WebFinger/OAuth) — the already-requested one
  4. The rest in any order; MCP last (it grows the extra registerMcpTool seam while moving)

Result: server.js shrinks toward core-only, every optional feature demonstrates the plugin contract, and third-party plugins (#157 CardDAV, #184 pane store) arrive into a system with eight working examples.

Reference: the same migration logic in jsclaw — its channels/commands/MCP tools were built in-tree first, then the plugin layer (jsclaw/jsclaw#64, jsclaw/jsclaw#77) formalized the seams they already used.

Metadata

Metadata

Assignees

No one assigned

    Labels

    pluginCould be implemented as a plugin (#206); core/plugin line defined in #564

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions