engenty wizards
Plugins

Examples

Two plugins in the repository to read, run and copy.

v0.8.0

The repository has two example plugins. Load them from a checkout with one line in .env.local:

PLUGINS_DIR=examples/plugins

notify: one file

examples/plugins/notify.ts posts a line to an address whenever a real run of a wizard reaches its end.

import type { WizardsPluginFactory } from "@engenty/wizards/plugin";

const plugin: WizardsPluginFactory = (wizards) => {
  const url = wizards.config.get("NOTIFY_URL");
  if (!url) {
    wizards.log.warn("NOTIFY_URL is not set: nothing will be sent.");
    return;
  }
  wizards.server.on("run.done", async ({ run, wizard }) => {
    if (run.mode !== "live") {
      return;
    }
    await fetch(url, {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ wizard: wizard.title, run: run.id }),
      signal: AbortSignal.timeout(10_000),
    });
  });
};

export default plugin;
It shows
A plugin of one fileIts id is the file’s name
A settingNOTIFY_URL in the install’s .env, read at load time
A listenerTest runs left out, a time limit on the call

run-log: both halves

examples/plugins/run-log keeps a line for every run that ended and shows them in the studio.

FileShows
engenty.plugin.jsonA manifest
migrations/0001_init.sqlA table, run_log_entry, with an index
migrations/0002_space.sqlA column added later: the space of each line
src/schema.tsThe same table for Drizzle
src/plugin.tsA listener on the three run events (run.done, run.failed, run.cancelled), two routes (one for admins only, one that filters by space) and a tool, run-log.recent
ui/messages.tsIts texts in English and German
ui/plugin.tsxA section of the space page under Results with the space’s last runs, a page with the whole log, and a settings section that empties the log
package.jsonA workspace package whose build script builds the studio half

Build its studio half once, or on every save:

node scripts/build-plugin.mjs examples/plugins/run-log
node scripts/build-plugin.mjs examples/plugins/run-log --watch

Then, in the studio:

  1. Test a wizard to its end.
  2. Open the space’s Results with the tray icon in the app bar. “Runs” stands below the results and shows the last five runs of the space’s wizards. Its last line, “All … runs”, opens the page with the whole log.
  3. Settings → Runs shows how many lines are kept, and “Delete all” deletes them.
  4. An AI step can list the tool “Run log” and tell how the last runs ended.

The plugin of these pages

The contacts plugin these pages build up, piece by piece:

PiecePage
The table contacts_personTables
The listener that keeps who ran a wizardEvents
The routes that list and remove contactsRoutes
The tool contacts.lookupTools
The page and the settings sectionThe studio half

Tests to read

apps/runtime/test/plugins.test.ts writes small plugins into a folder and exercises them: finding, loading, a plugin that fails, routes, tables per tenant, tools in a run, events and reloading.

On this page