Plugin Revibe

Plugin Revibe describes how plugins fit into the BlockDoc Canonical Revibe architecture, and how we can vibe code new plugins, distribute them and gradually revibe existing Federated Wiki plugins one at a time. The core idea is that plugins are just another kind of block in BlockDoc, with clear contracts and simple manifests, so that both humans and agents can evolve them safely over time.

# Plugin Block Shape At the BlockDoc level every plugin instance is just a block with a predictable shape. A plugin block has at least: - `id` stable identifier. - `type` either `"plugin"` or a more specific string like `"plugin:graphviz"`. - `props.pluginId` a global identifier such as `graphviz`, `timeline`, `chorus`. - `props.config` plugin specific configuration data. - `props.legacyItem` optional original Fedwiki `story` item for backwards compatibility. This keeps BlockDoc simple. The plugin block does not contain any behaviour, only configuration and a reference to the plugin implementation by `pluginId`.

# Plugin Registry The behaviour lives in a plugin registry, not in the block itself. Each client (React editor, web component SPA, CLI viewer) has a registry object that maps `pluginId` to a plugin module. A plugin module exports: - A schema describing `props.config` and its defaults. - A render function for the visual representation of the block. - Optional editor UI for configuring `config`. - Optional helpers for Markdown and Fedwiki JSON views. At startup each client loads a set of plugin modules and registers them with the registry. When it encounters a plugin block with `props.pluginId`, it asks the registry for a matching module and calls its render function. If no module is found, the client falls back to a generic “raw plugin block” view that shows `props.legacyItem` or raw JSON, so nothing ever becomes invisible.

# Vibe Coding New Plugins New plugins can be vibe coded incrementally with the help of agents such as Sourcegraph Amp. The typical workflow looks like this. First, create a little spec page in the wiki describing the plugin idea and its configuration fields. Second, ask Amp to generate a plugin module skeleton in the plugin repo: - A TypeScript or JavaScript module exporting a `pluginId`. - A `configSchema` describing the allowed keys and types. - A basic `render` function that renders a placeholder box with the current config. Third, wire the plugin into the registry in the React client and add a test page in BlockDoc that uses a `plugin` block with that `pluginId`. Fourth, iterate conversationally with Amp on the plugin render function and config UI, using BlockDoc snapshots and visual tests to keep changes small and inspectable. Because plugins are just modules referenced by `pluginId`, they can be developed, tested and even hot reloaded without touching the core BlockDoc model.

# Distribution And Discovery Plugins are distributed as small packages that implement the plugin module contract. At the simplest level a “plugin” is just a folder or repository containing: - The plugin module source file. - An optional stylesheet. - A manifest file declaring `pluginId`, version, and entrypoint. Sites and clients decide which plugin manifests they trust. A Fedwiki style index page can list available plugins and link to their manifests, letting communities curate plugin sets suited to their needs. Because the registry interface is minimal, different clients can host plugins in different ways, from local file paths on a homelab to remote URLs pulled from a shared plugin index.

# Revibing Existing Plugins Existing Fedwiki plugins can be revibed one at a time without a flag day. When we first import Fedwiki JSON, all unknown story item types are mapped to generic `plugin` blocks with `props.legacyItem` holding the original item data. Initially these render as raw plugin blocks, showing the old JSON in a simple frame. To revibe a specific plugin: - Write a plugin module with `pluginId` that matches the legacy plugin name. - Have its `render` function interpret `props.legacyItem` and present a cleaner UI while leaving the original data structure intact. - Optionally add a `migrate` helper that maps `legacyItem` into a richer `props.config` while still allowing `blockDocToFedwikiJson` to emit the original shape. This lets us upgrade the experience for one plugin at a time, while existing servers and clients that only understand the old plugin format continue to work.

# Incremental Block Types Some legacy plugin types deserve to become first class BlockDoc block types rather than staying as generic plugins. For each such candidate we can follow a two stage path. First stage: - Keep treating them as generic `plugin` blocks with `props.legacyItem`. - Implement a plugin module that renders them nicely. Second stage: - Introduce a new BlockDoc type, for example `graphviz` or `map`. - Teach the Fedwiki JSON adapter to map that legacy plugin item directly into the new BlockDoc type. - Add a small migration function that upgrades old `plugin` blocks to the new type when a page is loaded. Because BlockDoc is canonical, these migrations can be expressed as pure functions, tested by agents and applied progressively across a farm.

# Agent Friendly Design The plugin system is designed to be agent friendly from the start. The rules for how plugins map onto BlockDoc are explicit and live in a single place, not scattered through the codebase. Agents can: - Inspect all plugin modules in a registry and generate documentation pages summarising their config schemas. - Propose migrations that convert frequently used plugin blocks into new dedicated block types. - Automatically add tests to ensure `blockDocToFedwikiJson` and `fedwikiJsonToBlockDoc` remain compatible as plugin logic evolves. Vibe coding new plugins becomes a conversation with the agent around well defined contracts, not a dive into tangled DOM manipulation.