diff --git a/docs/cli-reference.md b/docs/cli-reference.md index a13999123f..23ad0ff87c 100644 --- a/docs/cli-reference.md +++ b/docs/cli-reference.md @@ -1025,6 +1025,7 @@ fn plugin dev [--once] [--ai-scan] Subcommands: `list|ls`, `install`, `rescan`, `trust`, `untrust`, `verify`, `uninstall`, `enable`, `disable`, `create`, `new`, `dev`. Scope semantics: +- `fn plugin install ` accepts a built plugin directory or installed package name, not a packed `.tgz` tarball; extract tarballs before installing. - `fn plugin install` / `fn plugin uninstall` are **global** operations - `fn plugin enable` / `fn plugin disable` are **project-scoped** operations (`--project` selects the project context) - `fn plugin list` shows globally installed plugins plus enabled/disabled state for the current project context diff --git a/docs/plugins/external-authoring.md b/docs/plugins/external-authoring.md index f25dcbb3e4..fe0ccea5ef 100644 --- a/docs/plugins/external-authoring.md +++ b/docs/plugins/external-authoring.md @@ -46,7 +46,7 @@ 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. +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 diff --git a/docs/plugins/external-proof-point-runbook.md b/docs/plugins/external-proof-point-runbook.md index 5cdd7af4e9..ae8ca5a17e 100644 --- a/docs/plugins/external-proof-point-runbook.md +++ b/docs/plugins/external-proof-point-runbook.md @@ -99,15 +99,23 @@ fn plugin list If the proof point uses the packaged-install path instead of `plugin dev`, run the equivalent install/enable/list loop: + + ```bash pnpm build pnpm test pnpm pack -fn plugin install ./fusion-plugin-proof-point-plugin-0.1.0.tgz +tar -xzf fusion-plugin-proof-point-plugin-0.1.0.tgz +fn plugin install ./package fn plugin enable fusion-plugin-proof-point-plugin fn plugin list ``` +Troubleshooting: FN-6471 found that `npx @runfusion/fusion@0.43.1 plugin install ./fusion-plugin-proof-point-plugin-0.1.0.tgz` fails with `Plugin entry file must end with .js, .mjs, or .cjs: /fusion-plugin-proof-point-plugin-0.1.0.tgz`. The failure is expected for a raw tarball because `fn plugin install` accepts a built plugin directory (or installed package name), not a packed `.tgz`; extract first and install from `./package`. This corrects the packaged-install snippet originally added by FN-6438. + Record the exact commands actually run. Do not summarize a command as successful unless its transcript shows exit code 0 or equivalent success output. ## Evidence to capture diff --git a/packages/cli/src/__tests__/external-proof-point-runbook-install.test.ts b/packages/cli/src/__tests__/external-proof-point-runbook-install.test.ts new file mode 100644 index 0000000000..b455e846e5 --- /dev/null +++ b/packages/cli/src/__tests__/external-proof-point-runbook-install.test.ts @@ -0,0 +1,40 @@ +import { readFileSync } from "node:fs"; +import { resolve } from "node:path"; +import { describe, expect, it } from "vitest"; + +const workspaceRoot = resolve(import.meta.dirname, "../../../.."); +const runbookPath = resolve(workspaceRoot, "docs", "plugins", "external-proof-point-runbook.md"); +const authoringPath = resolve(workspaceRoot, "docs", "plugins", "external-authoring.md"); + +const rawTarballInstallPattern = /fn plugin install\s+\S*\.tgz\b/; + +/* +FNXC:Plugins 2026-06-15-02:57: +FN-6474 guards the packaged-install proof path after FN-6471 showed raw tarballs are rejected as non-JS file entrypoints. Keep this test static and docs-only so the runbook cannot regress without invoking the real CLI or network. +*/ +describe("external plugin proof-point packaged install docs", () => { + it("does not tell readers to install a raw tarball in the runbook", () => { + const runbook = readFileSync(runbookPath, "utf8"); + + expect(runbook).not.toMatch(rawTarballInstallPattern); + }); + + it("extracts the packed tarball before installing the unpacked package directory", () => { + const runbook = readFileSync(runbookPath, "utf8"); + const packIndex = runbook.indexOf("pnpm pack"); + const extractIndex = runbook.indexOf("tar -xzf fusion-plugin-proof-point-plugin-0.1.0.tgz"); + const installIndex = runbook.indexOf("fn plugin install ./package"); + + expect(packIndex).toBeGreaterThanOrEqual(0); + expect(extractIndex).toBeGreaterThan(packIndex); + expect(installIndex).toBeGreaterThan(extractIndex); + }); + + it("keeps the authoring guide from installing raw tarballs", () => { + const authoringGuide = readFileSync(authoringPath, "utf8"); + + expect(authoringGuide).not.toMatch(rawTarballInstallPattern); + expect(authoringGuide).toContain("tar -xzf fusion-plugin-my-plugin-0.1.0.tgz"); + expect(authoringGuide).toContain("fn plugin install ./package"); + }); +});