Files
suaveplan/openspec/archive/2026-04-28-installer-port/specs/install-agent-skills/spec.md
2026-05-27 23:29:53 +01:00

34 lines
3.2 KiB
Markdown

# Install-Agent-Skills — Spec Delta (installer-port)
## ADDED Requirements
### INSTALL_SKILLS-01 — Default plan installs every bundled skill
When no `--only` or `--exclude` filter is supplied, `agentSkillsPlugin.plan(answers, ctx)` MUST emit `FileOp[]` covering every entry in the bundled `assets/skills/manifest.json`. The plan MUST contain exactly one `mkdir` op per skill directory, one `write` op per file enumerated under that skill's `files` array, and exactly one `patch-json` op targeting the project skill index (creating it when absent). The default `targetDir` MUST be `.suaveplan/skills` relative to `ctx.cwd`.
**Verified by:** `src/plan/plan.spec-conformance.test.ts` (`INSTALL_SKILLS-01`).
### INSTALL_SKILLS-02 — `--only` and `--exclude` filters
When `answers.only` is a non-empty array, the plan MUST contain ops only for skills whose `id` appears in `only`. When `answers.exclude` is a non-empty array, the plan MUST omit ops for skills whose `id` appears in `exclude`. When both are supplied, `only` is applied first and `exclude` second. An `only` or `exclude` entry not present in the bundled manifest MUST surface as `InstallSkillsError(INSTALL_SKILLS.UNKNOWN_SKILL)` carrying the unknown id.
**Verified by:** `src/plan/plan.spec-conformance.test.ts` (`INSTALL_SKILLS-02`).
### INSTALL_SKILLS-03 — Skill-index patch shape
The `patch-json` op targeting the project skill index MUST use `JsonMerge` to upsert an entry of shape `{ id: string, version: string, dir: string, source: "@suaveplan/install-agent-skills", installedAt: string }` for each installed skill, where `installedAt` is an ISO 8601 UTC timestamp captured at plan time. The merge MUST replace any prior entry with the same `id` (idempotent re-install). The index file path MUST default to `<targetDir>/index.json` and MUST be created with conflict policy `merge`.
**Verified by:** `src/plan/plan.spec-conformance.test.ts` (`INSTALL_SKILLS-03`).
### INSTALL_SKILLS-04 — Bundled manifest validation
`loadBundledManifest()` MUST Zod-validate `assets/skills/manifest.json` at runtime. Required schema: `{ skills: Array<{ id: string, version: string (semver), dir: string, files: string[] }> }`. Validation failures MUST surface as `InstallSkillsError(INSTALL_SKILLS.MANIFEST_INVALID, { cause })`. The loader MUST NOT cache across invocations of `runPlugin` in the testing harness so that test fixtures can swap in alternate manifests.
**Verified by:** `src/manifest-loader.spec-conformance.test.ts` (`INSTALL_SKILLS-04`).
### INSTALL_SKILLS-05 — End-to-end install on fresh target
`runPlugin(agentSkillsPlugin, { answers: { targetDir: "/x" } })` against an empty `MemoryFs` MUST result in: every skill directory created under `/x`, every skill file written with the expected bytes, the skill index file written at `/x/index.json` with one entry per installed skill, zero conflicts reported, and a `postInstall` summary recording the installed count. The same harness invocation re-run against the resulting fs MUST be idempotent under default conflict policy `merge` for the index and `skip-if-exists` for already-present files (no `INSTALLER.APPLY_CONFLICT` raised).
**Verified by:** `src/plugin.e2e.spec-conformance.test.ts` (`INSTALL_SKILLS-05`).