first commit
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
# `plugin`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Composes the agent-skills installer plugin from its constituent stages
|
||||
(`detect`, `prompts`, `plan`, `apply`, `postInstall`). Exposes both the
|
||||
default `agentSkillsPlugin` (no-options instance using the bundled
|
||||
manifest) and a `buildAgentSkillsPlugin(options)` factory for tests and
|
||||
embedders that want to override the bundle root or capture deterministic
|
||||
timestamps.
|
||||
|
||||
## Features
|
||||
|
||||
- Default export is `agentSkillsPlugin` so `import "@suaveplan/install-agent-skills"` returns a ready-to-mount
|
||||
plugin via `mod.default`.
|
||||
- Factory `buildAgentSkillsPlugin(options)` accepts `bundleRoot`,
|
||||
`manifestPath`, and `nowIso` for full test control.
|
||||
- The `apply` lambda derives `targetDir` from the planned `index.json`
|
||||
op so `postInstall` always sees the resolved path, even when answers
|
||||
used a relative path.
|
||||
- Stable plugin metadata: `id: "agent-skills"`, `version: "0.1.0"`.
|
||||
|
||||
## Basic Example
|
||||
|
||||
```ts
|
||||
import {
|
||||
agentSkillsPlugin,
|
||||
Host,
|
||||
DiskFs,
|
||||
} from "@suaveplan/installer";
|
||||
import "@suaveplan/install-agent-skills"; // ensures default export is loaded
|
||||
|
||||
const fs = new DiskFs({ cwd: process.cwd() });
|
||||
const host = new Host(ctx, fs);
|
||||
const result = await host.run(agentSkillsPlugin, {
|
||||
answers: { targetDir: ".suaveplan/skills" },
|
||||
});
|
||||
```
|
||||
|
||||
## Advanced Example
|
||||
|
||||
```ts
|
||||
import { buildAgentSkillsPlugin } from "@suaveplan/install-agent-skills";
|
||||
import { runPlugin } from "@suaveplan/installer/testing";
|
||||
|
||||
const plugin = buildAgentSkillsPlugin({
|
||||
bundleRoot: "/tmp/test-bundle",
|
||||
manifestPath: "/tmp/test-bundle/manifest.json",
|
||||
nowIso: "2026-04-28T00:00:00.000Z",
|
||||
});
|
||||
|
||||
const result = await runPlugin(plugin, {
|
||||
answers: {
|
||||
targetDir: "/x",
|
||||
only: ["crypto"],
|
||||
},
|
||||
});
|
||||
expect(result.handle?.installed).toBe(2);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `agentSkillsPlugin: InstallerPlugin<AgentSkillsAnswers, AgentSkillsHandle>`
|
||||
— default-options instance.
|
||||
- `buildAgentSkillsPlugin(options?): InstallerPlugin<AgentSkillsAnswers, AgentSkillsHandle>`
|
||||
— factory.
|
||||
- `interface AgentSkillsPluginOptions` —
|
||||
`{ bundleRoot?, manifestPath?, nowIso? }`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The default `agentSkillsPlugin` is created via
|
||||
`buildAgentSkillsPlugin()` so the no-options path stays
|
||||
test-coverage-friendly (one factory, two callers). The `apply`
|
||||
lambda's `readTargetFromOps` helper reads the trailing
|
||||
`/index.json` op to derive the resolved target — this is more robust
|
||||
than threading answers through closures because it survives the host's
|
||||
`only`/`exclude` filtering, which can drop earlier ops but never the
|
||||
index patch. The factory's options are forwarded to `plan` via spread
|
||||
conditionals so omitting any option produces a runtime that uses the
|
||||
default (the bundled manifest path, the bundled assets root, and a
|
||||
fresh `Date.now()` timestamp respectively). Tests use `nowIso` to fix
|
||||
the timestamp for snapshot assertions; production runs let it default
|
||||
so each install carries its own ISO 8601 marker in the index.
|
||||
Reference in New Issue
Block a user