Files
2026-05-27 23:29:53 +01:00

9.3 KiB

Tasks: installer-port

1. Scaffold — @suaveplan/installer

  • 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.
  • 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.
  • 1.3 Subpath exports: ., ./types, ./errors, ./host, ./fs, ./manifest, ./testing.
  • 1.4 bin field: { "suaveplan-install": "./dist/bin/suaveplan-install.js" }.

2. Types and contract

  • 2.1 src/types/installer.types.ts — InstallerContext, InstallerPlugin<TAnswers, THandle>, InstallerFs, InstallerCli, DetectResult, PromptSchema<T>, JsonMerge, TextEdit.
  • 2.2 src/types/file-op.types.ts — FileOp discriminated union (write | patch-json | patch-text | mkdir | delete | rename) with per-variant conflict?: ConflictPolicy.
  • 2.3 src/error-codes.ts — defineCodes("INSTALLER", [...]) with codes from proposal §5. Sibling InstallerError extends SuaveplanError<InstallerErrorCode>.
  • 2.4 src/schemas/ — Zod boundary schemas for PluginManifest, FileOp, CLI flags. Marker // schema: boundary-only.

3. Virtual filesystem (./fs)

  • 3.1 src/fs/installer-fs.ts — InstallerFs interface (exists, readFile, readJson, stat, listDir, pathOf).
  • 3.2 src/fs/disk-fs.ts — concrete disk-backed implementation with abort propagation.
  • 3.3 src/fs/memory-fs.ts — in-memory implementation (used by ./testing).

4. Host pipeline (./host)

  • 4.1 src/host/host.ts — Host class orchestrating detect → prompts → plan → apply → postInstall. Each stage wrapped in OTel span installer.<stage> with plugin.id, plugin.version, dry_run attributes.
  • 4.2 src/host/detect.ts — runs plugin.detect?, normalises result, emits installer.detect event.
  • 4.3 src/host/prompts.ts — Zod-validates answers; --answers <file> bypass; --no-interactive rejects ambiguous prompts. Failure → INSTALLER.PROMPT_VALIDATION_FAILED.
  • 4.4 src/host/plan.ts — invokes plugin.plan(answers, ctx), validates returned FileOp[] against schema, returns plan record.
  • 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.
  • 4.6 src/host/apply/conflict.ts — resolves error | overwrite | skip-if-exists | merge | prompt per FileOp. --force collapses to overwrite.
  • 4.7 src/host/apply/json-merge.ts — implements JsonMerge (deep-merge with array-replace semantics matching @suaveplan/config).
  • 4.8 src/host/apply/text-patch.ts — applies TextEdit[] (anchor + insert/replace/delete), preserves trailing-newline policy.
  • 4.9 src/host/post-install.ts — runs plugin.postInstall?(handle, ctx) with abort propagation.

5. Plugin manifest (./manifest)

  • 5.1 src/manifest/manifest.ts — PluginManifestSchema (Zod), loadManifest(packagePath), validateManifest(raw). Failure → INSTALLER.PLUGIN_INVALID_MANIFEST.
  • 5.2 src/manifest/discover.ts — resolves @suaveplan/install-* and @<scope>/suaveplan-install-* from consumer node_modules. INSTALLER.PLUGIN_NOT_FOUND when missing.

6. CLI bin

  • 6.1 src/bin/suaveplan-install.ts — cli("suaveplan-install", "0.1.0") wiring add <plugin>, list, --dry-run, --force, --no-interactive, --only, --exclude, --answers <file>.
  • 6.2 add <plugin> command — discovers + loads plugin, builds InstallerContext, runs Host.
  • 6.3 list command — enumerates installed plugins from manifest discovery.

7. Testing harness (./testing)

  • 7.1 src/testing/run-plugin.ts — runPlugin(plugin, { answers, fs?, cli? }) returns { ops, applied, fs } for assertion. Zero real disk I/O.
  • 7.2 src/testing/script-cli.ts — non-TTY InstallerCli that returns scripted answers and records prompts asked.
  • 7.3 src/testing/installer-fs.test-helpers.ts — createMemoryFs(seed?), assertWrote(fs, path, predicate).

8. Spec — @suaveplan/installer

  • 8.1 openspec/changes/installer-port/specs/installer/spec.md with INSTALLER-01…INSTALLER-09, each carrying **Verified by:**.

9. Conformance tests — @suaveplan/installer

  • 9.1 src/host/host.spec-conformance.test.ts — INSTALLER-01 (lifecycle order), INSTALLER-02 (idempotent re-run), INSTALLER-03 (abort propagation).
  • 9.2 src/host/apply/apply.spec-conformance.test.ts — INSTALLER-04 (transactional apply + rollback), INSTALLER-05 (conflict policy).
  • 9.3 src/host/prompts.spec-conformance.test.ts — INSTALLER-06 (Zod validation, non-interactive bypass).
  • 9.4 src/manifest/manifest.spec-conformance.test.ts — INSTALLER-07 (manifest schema), INSTALLER-08 (plugin discovery).
  • 9.5 src/error-codes.spec-conformance.test.ts — INSTALLER-09 (frozen registry, namespaced codes).

10. Scaffold — @suaveplan/install-agent-skills

  • 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.
  • 10.2 Workspace deps: @suaveplan/installer, @suaveplan/error, @suaveplan/types, zod. All workspace:^.
  • 10.3 Subpath exports: ., ./manifest.

11. Skills bundle assembly

  • 11.1 scripts/build-skills-bundle.ts — copies every SKILL.md + asset directory into packages/platform/install-agent-skills/assets/skills/<name>/.
  • 11.2 assets/skills/manifest.json — generated { skills: [{ id, version, dir, files }] }. Zod-validated at build time.
  • 11.3 Pre-publish hook: bun run build:bundle runs the assembler before bunx turbo build.

12. Plugin implementation

  • 12.1 src/plugin.ts — exports default agentSkillsPlugin: InstallerPlugin<AgentSkillsAnswers, AgentSkillsHandle>.
  • 12.2 src/detect/detect.ts — checks for <targetDir>/skills/ and reports already-present skills.
  • 12.3 src/prompts/prompts.ts — Zod schema: targetDir (default .suaveplan/skills), only?: string[], exclude?: string[], overwrite?: boolean.
  • 12.4 src/plan/plan.ts — reads bundled manifest, applies --only / --exclude filter, emits mkdir + write ops + patch-json for skill index.
  • 12.5 src/apply/apply.ts — thin pass-through; transaction lives in the host.
  • 12.6 src/post-install/post-install.ts — prints installed N skills to <dir> plus next-steps.
  • 12.7 src/manifest-loader.ts — runtime loader for the bundled assets/skills/manifest.json. Failure → INSTALL_SKILLS.MANIFEST_INVALID.
  • 12.8 src/error-codes.ts — defineCodes("INSTALL_SKILLS", [...]).

13. Spec — @suaveplan/install-agent-skills

  • 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

  • 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).
  • 14.2 src/manifest-loader.spec-conformance.test.ts — INSTALL_SKILLS-04 (manifest validation).
  • 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)

  • 15.1 @suaveplan/installer — .md for every non-test/non-types/non-barrel .ts per openspec/AGENTS.md §4. Basic + Advanced examples mandatory.
  • 15.2 @suaveplan/install-agent-skills — same.
  • 15.3 Root README.md for both packages with quickstart.

16. Quality gates

  • 16.1 bunx turbo lint typecheck test --filter=@suaveplan/installer green.
  • 16.2 bunx turbo lint typecheck test --filter=@suaveplan/install-agent-skills green.
  • 16.3 bunx turbo test:coverage --filter=@suaveplan/installer 100 % istanbul on touched modules.
  • 16.4 bunx turbo test:coverage --filter=@suaveplan/install-agent-skills 100 % istanbul on touched modules.
  • 16.5 No banned patterns in packages/platform/installer/src/ or packages/platform/install-agent-skills/src/ per openspec/AGENTS.md §2.
  • 16.6 No biome-ignore in either src/ per openspec/AGENTS.md §2a.
  • 16.7 File-size check: every src/*.ts ≤ 300 lines, every *.test.ts ≤ 500 lines.
  • 16.8 Sibling .md audit per openspec/AGENTS.md §4 returns zero gaps.

17. Manifest + listing refresh

  • 17.1 Add installer and install-agent-skills entries to CLAUDE.md under ## Packages.
  • 17.2 bun scripts/folder-reorg/generate-manifest.ts to refresh MANIFEST.md.

18. Archive

  • 18.1 Fold specs/installer/spec.md delta into openspec/specs/installer/spec.md.
  • 18.2 Fold specs/install-agent-skills/spec.md delta into openspec/specs/install-agent-skills/spec.md.
  • 18.3 Move openspec/changes/installer-port/ to openspec/archive/2026-04-28-installer-port/.