first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
# `run-plugin`
## Purpose
End-to-end test harness for plugins. `runPlugin(plugin, options)` wires up
an in-memory filesystem, a scripted CLI, a no-op logger, and a basic
template engine, then drives the plugin through the full
`detect → prompts → plan → apply → postInstall` pipeline. Returns the
filesystem and the recorded CLI interaction so tests can assert on what
was written and what was prompted. Zero real disk I/O.
## Features
- Sensible defaults: in-memory `MemoryFs`, scripted `ScriptCli`, no-op
logger, `{{var}}`-style template engine — all overridable.
- Returns `{ ops, summary, handle, dryRun, fs, cli }` so tests can
inspect the plan, the resulting fs, and the prompt history.
- Same `RunOptions` surface as `Host.run`: `dryRun`, `force`,
`noInteractive`, `only`, `exclude`, `signal`.
- Defaults `noInteractive` to `true` so test runs never block on a
prompt that wasn't scripted.
## Basic Example
```ts
import { runPlugin } from "@suaveplan/installer";
const result = await runPlugin(myPlugin, {
answers: { targetDir: "/.suaveplan/skills" },
});
expect(result.summary.written).toBe(5);
```
## Advanced Example
```ts
import { runPlugin, ScriptCli } from "@suaveplan/installer";
const cli = new ScriptCli({ confirm: [true, false] });
const ac = new AbortController();
const result = await runPlugin(myPlugin, {
cli,
signal: ac.signal,
answers: { skills: ["echo", "crypto"] },
only: ["crypto"],
force: false,
});
expect(cli.record.confirms).toEqual([
{ message: "Overwrite existing file?", answer: true },
]);
expect(result.ops.every((op) => op.path.includes("crypto"))).toBe(true);
```
## API Reference
- `runPlugin<TAnswers, THandle>(plugin, options): Promise<RunPluginResult<THandle>>`
- `interface RunPluginOptions<TAnswers>` —
`{ answers?, fs?, cli?, cwd?, logger?, templates?, signal?, dryRun?, force?, noInteractive?, only?, exclude? }`.
- `interface RunPluginResult<THandle> extends HostRunResult<THandle>`
— adds `fs: MemoryFs` and `cli: InstallerCli`.
## Implementation Notes
The default template engine handles only `{{varName}}` substitution and
returns empty string for unknown vars — that's enough for plugin tests
that don't care about templates and avoids adding a dependency on
`@suaveplan/templates` to the test surface. The default `cwd` is `/`
(POSIX root in `MemoryFs`'s namespace) so paths in plans can be written
literally. Tests that need a different `cwd` should pass it explicitly;
both `DiskFs` and `MemoryFs` honour the value identically.