Files
fusion/docs/plugins/external-authoring.md
gsxdsm 3326984a6d FN-7913: add fn plugin publish --dry-run preflight command
Adds a non-mutating `fn plugin publish` CLI command that preflights a plugin before manual pack/publish, giving external plugin authors an offline readiness check.

- New `packages/cli/src/commands/plugin-publish.ts` with `runPluginPublish`, `collectPluginPreflight`, and `classifyVersionBump` (strict x.y.z semver bump classification), reusing `loadManifestFromPath` / `resolvePluginEntryFile` from the install path
- Wire `fn plugin publish <path> [--dry-run] [--previous-version <semver>]` into `bin.ts` command routing, dynamic import list, and help text
- Add test coverage in `plugin-publish.test.ts` and update `bin.test.ts` for the new subcommand
- Update `docs/PLUGIN_AUTHORING.md`, `docs/cli-reference.md`, and `docs/plugins/external-authoring.md` to document the new preflight command
- Add changeset `.changeset/fn-7913-plugin-publish-dry-run.md` (minor, @runfusion/fusion)

Files changed:
 .changeset/fn-7913-plugin-publish-dry-run.md      |   7 +
 docs/PLUGIN_AUTHORING.md                          |   9 +-
 docs/cli-reference.md                             |   5 +-
 docs/plugins/external-authoring.md                |  14 +-
 packages/cli/src/__tests__/bin.test.ts            |   2 +-
 packages/cli/src/__tests__/plugin-publish.test.ts | 197 ++++++++++++++++
 packages/cli/src/bin.ts                           |  22 +-
 packages/cli/src/commands/plugin-publish.ts       | 272 ++++++++++++++++++++++
 8 files changed, 521 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-7913

Fusion-Task-Lineage: 27bdf937-3195-4619-9d01-b6af4fbba487

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 21:27:38 -07:00

3.6 KiB

External Plugin Authoring

This guide is for plugin authors using an installed @runfusion/fusion CLI. You do not need access to the Fusion monorepo.

Prerequisites

  • Node.js 18+
  • pnpm (or use the equivalent npm commands where noted)
  • An installed Fusion CLI available as fn

1. Scaffold a standalone plugin

fn plugin new my-plugin
cd my-plugin
pnpm install

The scaffold creates a standalone package named fusion-plugin-my-plugin. It depends on the published @runfusion/fusion package and imports SDK helpers from @runfusion/fusion/plugin-sdk; it must not contain private @fusion/* imports or workspace:* dependencies.

2. Develop locally with hot reload

Start Fusion locally, then run the plugin dev loop from the plugin directory:

fn plugin dev .

fn plugin dev .:

  1. Runs the plugin build script (pnpm build, with npm run build fallback).
  2. Resolves the compiled JavaScript entry from package.json exports/main or dist/index.js.
  3. Reads and validates the root manifest.json.
  4. Installs and enables the plugin into the local Fusion plugin store.
  5. Watches src/ and, on save, rebuilds and hot-reloads with the Fusion plugin loader.

For a single CI-safe build/install/load pass without a watcher, use:

fn plugin dev . --once

You can also run the build yourself:

pnpm build

Troubleshooting: plugin entrypoints must be compiled JavaScript. fn plugin install and fn plugin dev reject .ts source entrypoints, so run the build before installing if you are not using the dev loop. A raw *.tgz is not a valid fn plugin install argument; extract it first with tar -xzf and install from the unpacked ./package directory.

3. Test

pnpm test

If you prefer npm for a scaffold that supports it:

npm test

4. Preflight publish readiness

Before packing, run the offline publish preflight against the built plugin directory:

fn plugin publish --dry-run .

The preflight validates manifest.json, rejects missing builds or .ts source entrypoints by resolving the compiled JavaScript entry the same way fn plugin install does, verifies the default-exported plugin manifest and declared lifecycle hooks, and reports the version bump class when you pass --previous-version <semver>. It does not install, upload, publish, tag, or contact a registry.

5. Package

Build first, then create an npm tarball:

pnpm build
pnpm pack

For my-plugin version 0.1.0, the tarball is named like:

fusion-plugin-my-plugin-0.1.0.tgz

The scaffolded package publishes only the files declared in package.json (dist, manifest.json, and package metadata) and exposes the plugin through:

{
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.js"
    }
  }
}

Before sharing the tarball, confirm the artifact does not include private monorepo-only strings:

  • no @fusion/* imports or dependencies
  • no workspace:* dependency ranges
  • SDK imports come from @runfusion/fusion/plugin-sdk

6. Install elsewhere

On another machine with Fusion installed, extract or install the tarball, then point Fusion at the extracted plugin directory:

tar -xzf fusion-plugin-my-plugin-0.1.0.tgz
fn plugin install ./package
fn plugin enable fusion-plugin-my-plugin

If the plugin directory is already available, install it directly:

fn plugin install /path/to/fusion-plugin-my-plugin
fn plugin enable fusion-plugin-my-plugin

Use fn plugin list to confirm the plugin is installed and enabled for the current project.