3.2 KiB
Install-Agent-Skills — Spec
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).