# Tasks: installer-port ## 1. Scaffold — `@suaveplan/installer` - [x] 1.1 Create `packages/platform/installer/` with `package.json` (`@suaveplan/installer@0.0.0`), `tsconfig.json` extending `@suaveplan/typescript-config/library.json`, `vitest.config.ts` via `createTestConfig()`, root `README.md`. - [x] 1.2 Workspace deps: `@suaveplan/cli`, `@suaveplan/templates`, `@suaveplan/validation`, `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`, `@suaveplan/logger`, `@opentelemetry/api`, `zod`. All `workspace:^` for internal, `catalog:` for external. - [x] 1.3 Subpath exports: `.`, `./types`, `./errors`, `./host`, `./fs`, `./manifest`, `./testing`. - [x] 1.4 `bin` field: `{ "suaveplan-install": "./dist/bin/suaveplan-install.js" }`. ## 2. Types and contract - [x] 2.1 `src/types/installer.types.ts` — `InstallerContext`, `InstallerPlugin`, `InstallerFs`, `InstallerCli`, `DetectResult`, `PromptSchema`, `JsonMerge`, `TextEdit`. - [x] 2.2 `src/types/file-op.types.ts` — `FileOp` discriminated union (`write` | `patch-json` | `patch-text` | `mkdir` | `delete` | `rename`) with per-variant `conflict?: ConflictPolicy`. - [x] 2.3 `src/error-codes.ts` — `defineCodes("INSTALLER", [...])` with codes from proposal §5. Sibling `InstallerError` extends `SuaveplanError`. - [x] 2.4 `src/schemas/` — Zod boundary schemas for `PluginManifest`, `FileOp`, CLI flags. Marker `// schema: boundary-only`. ## 3. Virtual filesystem (`./fs`) - [x] 3.1 `src/fs/installer-fs.ts` — `InstallerFs` interface (`exists`, `readFile`, `readJson`, `stat`, `listDir`, `pathOf`). - [x] 3.2 `src/fs/disk-fs.ts` — concrete disk-backed implementation with abort propagation. - [x] 3.3 `src/fs/memory-fs.ts` — in-memory implementation (used by `./testing`). ## 4. Host pipeline (`./host`) - [x] 4.1 `src/host/host.ts` — `Host` class orchestrating `detect → prompts → plan → apply → postInstall`. Each stage wrapped in OTel span `installer.` with `plugin.id`, `plugin.version`, `dry_run` attributes. - [x] 4.2 `src/host/detect.ts` — runs `plugin.detect?`, normalises result, emits `installer.detect` event. - [x] 4.3 `src/host/prompts.ts` — Zod-validates answers; `--answers ` bypass; `--no-interactive` rejects ambiguous prompts. Failure → `INSTALLER.PROMPT_VALIDATION_FAILED`. - [x] 4.4 `src/host/plan.ts` — invokes `plugin.plan(answers, ctx)`, validates returned `FileOp[]` against schema, returns plan record. - [x] 4.5 `src/host/apply/apply.ts` — staged-tmp + atomic rename per file, transaction journal, rollback on failure. `--dry-run` prints plan and exits before this stage. - [x] 4.6 `src/host/apply/conflict.ts` — resolves `error | overwrite | skip-if-exists | merge | prompt` per `FileOp`. `--force` collapses to `overwrite`. - [x] 4.7 `src/host/apply/json-merge.ts` — implements `JsonMerge` (deep-merge with array-replace semantics matching `@suaveplan/config`). - [x] 4.8 `src/host/apply/text-patch.ts` — applies `TextEdit[]` (anchor + insert/replace/delete), preserves trailing-newline policy. - [x] 4.9 `src/host/post-install.ts` — runs `plugin.postInstall?(handle, ctx)` with abort propagation. ## 5. Plugin manifest (`./manifest`) - [x] 5.1 `src/manifest/manifest.ts` — `PluginManifestSchema` (Zod), `loadManifest(packagePath)`, `validateManifest(raw)`. Failure → `INSTALLER.PLUGIN_INVALID_MANIFEST`. - [x] 5.2 `src/manifest/discover.ts` — resolves `@suaveplan/install-*` and `@/suaveplan-install-*` from consumer `node_modules`. `INSTALLER.PLUGIN_NOT_FOUND` when missing. ## 6. CLI bin - [x] 6.1 `src/bin/suaveplan-install.ts` — `cli("suaveplan-install", "0.1.0")` wiring `add `, `list`, `--dry-run`, `--force`, `--no-interactive`, `--only`, `--exclude`, `--answers `. - [x] 6.2 `add ` command — discovers + loads plugin, builds `InstallerContext`, runs `Host`. - [x] 6.3 `list` command — enumerates installed plugins from manifest discovery. ## 7. Testing harness (`./testing`) - [x] 7.1 `src/testing/run-plugin.ts` — `runPlugin(plugin, { answers, fs?, cli? })` returns `{ ops, applied, fs }` for assertion. Zero real disk I/O. - [x] 7.2 `src/testing/script-cli.ts` — non-TTY `InstallerCli` that returns scripted answers and records prompts asked. - [x] 7.3 `src/testing/installer-fs.test-helpers.ts` — `createMemoryFs(seed?)`, `assertWrote(fs, path, predicate)`. ## 8. Spec — `@suaveplan/installer` - [x] 8.1 `openspec/changes/installer-port/specs/installer/spec.md` with `INSTALLER-01`…`INSTALLER-09`, each carrying `**Verified by:**`. ## 9. Conformance tests — `@suaveplan/installer` - [x] 9.1 `src/host/host.spec-conformance.test.ts` — `INSTALLER-01` (lifecycle order), `INSTALLER-02` (idempotent re-run), `INSTALLER-03` (abort propagation). - [x] 9.2 `src/host/apply/apply.spec-conformance.test.ts` — `INSTALLER-04` (transactional apply + rollback), `INSTALLER-05` (conflict policy). - [x] 9.3 `src/host/prompts.spec-conformance.test.ts` — `INSTALLER-06` (Zod validation, non-interactive bypass). - [x] 9.4 `src/manifest/manifest.spec-conformance.test.ts` — `INSTALLER-07` (manifest schema), `INSTALLER-08` (plugin discovery). - [x] 9.5 `src/error-codes.spec-conformance.test.ts` — `INSTALLER-09` (frozen registry, namespaced codes). ## 10. Scaffold — `@suaveplan/install-agent-skills` - [x] 10.1 Create `packages/platform/install-agent-skills/` with `package.json` (`@suaveplan/install-agent-skills@0.0.0`), `tsconfig.json`, `vitest.config.ts`, `README.md`. - [x] 10.2 Workspace deps: `@suaveplan/installer`, `@suaveplan/error`, `@suaveplan/types`, `zod`. All `workspace:^`. - [x] 10.3 Subpath exports: `.`, `./manifest`. ## 11. Skills bundle assembly - [x] 11.1 `scripts/build-skills-bundle.ts` — copies every `SKILL.md` + asset directory into `packages/platform/install-agent-skills/assets/skills//`. - [x] 11.2 `assets/skills/manifest.json` — generated `{ skills: [{ id, version, dir, files }] }`. Zod-validated at build time. - [x] 11.3 Pre-publish hook: `bun run build:bundle` runs the assembler before `bunx turbo build`. ## 12. Plugin implementation - [x] 12.1 `src/plugin.ts` — exports default `agentSkillsPlugin: InstallerPlugin`. - [x] 12.2 `src/detect/detect.ts` — checks for `/skills/` and reports already-present skills. - [x] 12.3 `src/prompts/prompts.ts` — Zod schema: `targetDir` (default `.suaveplan/skills`), `only?: string[]`, `exclude?: string[]`, `overwrite?: boolean`. - [x] 12.4 `src/plan/plan.ts` — reads bundled manifest, applies `--only` / `--exclude` filter, emits `mkdir` + `write` ops + `patch-json` for skill index. - [x] 12.5 `src/apply/apply.ts` — thin pass-through; transaction lives in the host. - [x] 12.6 `src/post-install/post-install.ts` — prints `installed N skills to ` plus next-steps. - [x] 12.7 `src/manifest-loader.ts` — runtime loader for the bundled `assets/skills/manifest.json`. Failure → `INSTALL_SKILLS.MANIFEST_INVALID`. - [x] 12.8 `src/error-codes.ts` — `defineCodes("INSTALL_SKILLS", [...])`. ## 13. Spec — `@suaveplan/install-agent-skills` - [x] 13.1 `openspec/changes/installer-port/specs/install-agent-skills/spec.md` with `INSTALL_SKILLS-01`…`INSTALL_SKILLS-05`, each with `**Verified by:**`. ## 14. Conformance tests — `@suaveplan/install-agent-skills` - [x] 14.1 `src/plan/plan.spec-conformance.test.ts` — `INSTALL_SKILLS-01` (default = all skills), `INSTALL_SKILLS-02` (`--only` / `--exclude` filter), `INSTALL_SKILLS-03` (skill-index patch shape). - [x] 14.2 `src/manifest-loader.spec-conformance.test.ts` — `INSTALL_SKILLS-04` (manifest validation). - [x] 14.3 `src/plugin.e2e.spec-conformance.test.ts` — `INSTALL_SKILLS-05` (end-to-end via `runPlugin` against memory fs writes full skill set, zero conflicts on fresh target). ## 15. Docs (sibling `.md` per implementation `.ts`) - [x] 15.1 `@suaveplan/installer` — `.md` for every non-test/non-types/non-barrel `.ts` per `openspec/AGENTS.md` §4. Basic + Advanced examples mandatory. - [x] 15.2 `@suaveplan/install-agent-skills` — same. - [x] 15.3 Root `README.md` for both packages with quickstart. ## 16. Quality gates - [x] 16.1 `bunx turbo lint typecheck test --filter=@suaveplan/installer` green. - [x] 16.2 `bunx turbo lint typecheck test --filter=@suaveplan/install-agent-skills` green. - [x] 16.3 `bunx turbo test:coverage --filter=@suaveplan/installer` 100 % istanbul on touched modules. - [x] 16.4 `bunx turbo test:coverage --filter=@suaveplan/install-agent-skills` 100 % istanbul on touched modules. - [x] 16.5 No banned patterns in `packages/platform/installer/src/` or `packages/platform/install-agent-skills/src/` per `openspec/AGENTS.md` §2. - [x] 16.6 No `biome-ignore` in either `src/` per `openspec/AGENTS.md` §2a. - [x] 16.7 File-size check: every `src/*.ts` ≤ 300 lines, every `*.test.ts` ≤ 500 lines. - [x] 16.8 Sibling `.md` audit per `openspec/AGENTS.md` §4 returns zero gaps. ## 17. Manifest + listing refresh - [x] 17.1 Add `installer` and `install-agent-skills` entries to `CLAUDE.md` under `## Packages`. - [x] 17.2 `bun scripts/folder-reorg/generate-manifest.ts` to refresh `MANIFEST.md`. ## 18. Archive - [x] 18.1 Fold `specs/installer/spec.md` delta into `openspec/specs/installer/spec.md`. - [x] 18.2 Fold `specs/install-agent-skills/spec.md` delta into `openspec/specs/install-agent-skills/spec.md`. - [x] 18.3 Move `openspec/changes/installer-port/` to `openspec/archive/2026-04-28-installer-port/`.