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

4.3 KiB

create-suaveplan-plugin — interactive scaffold for new plugins

Package: create-suaveplan-plugin Status: PROPOSED Type: new-package Stage: 8 — see umbrella openspec/changes/api-plugin-foundation/

Why

Per design doc §13.7, plugin authors should never start from an empty directory. create-suaveplan-plugin <name> generates a complete, immediately-testable plugin skeleton with plugin.json, definePlugin body, host-test, integration test (with real Postgres when DB is selected), both vitest configs, migrations, and a README. The author runs bun test, sees green, then replaces the skeleton.

The scaffold ships AS a plugin loaded by @suaveplan/installer — consistent with how install-agent-skills works. The binary entrypoint is bunx create-suaveplan-plugin <name> (or bun create suaveplan-plugin <name>).

What changes

  • ADDED: Bin create-suaveplan-plugin mounted under @suaveplan/installer plugin host.
  • ADDED: Interactive prompt asking about: plugin name, isolation tier, capabilities selected (multi-select), DB engine (postgres / sqlite / surrealdb / none), whether to scaffold GraphQL / WS / SSE / sagas / 2PC / per-tenant jobs.
  • ADDED: Template output, generated atomically into a fresh directory:
    • plugin.json — every section commented with explanatory text AND populated with minimal viable values for selected capabilities.
    • src/index.ts — definePlugin({ ... }) skeleton hitting every selected capability with TODO-marked handler bodies that compile + pass type-check on day one.
    • src/index.test.ts — createTestHost against the skeleton; one it(...) per capability declaring "host wires the capability + calls a no-op handler".
    • tests/integration/example.integration.test.ts — uses testing-integration-postgres (or sqlite / surrealdb per prompt). Runs only when INTEGRATION=1.
    • vitest.config.ts and vitest.integration.config.ts — pre-wired with createTestConfig from @suaveplan/testing.
    • migrations/<engine>/0001-init.sql — empty boilerplate matching the DB engine.
    • README.md — manifest + lifecycle + capability docs filled in for the selected surface.
    • package.json — version 0.0.0, deps for selected capabilities, scripts (test, test:integration, test:coverage, lint, typecheck, build).
    • tsconfig.json — extends @suaveplan/typescript-config/library-node.
    • .gitignore, biome config inheritance.
  • ADDED: Snapshot test of the generated tree — tests/scaffold-output/scaffold-output.test.ts runs the generator against a fixture prompt set and asserts the produced files match a committed snapshot byte-for-byte.
  • ADDED: Error codes (SCAFFOLD_*): INVALID_NAME, DIRECTORY_EXISTS, WRITE_FAILED, UNKNOWN_ENGINE.

Out of scope

  • Publishing the scaffolded plugin to a registry — author's job.
  • Continuous-update flow (re-running scaffold to add a capability later) — separate change.
  • Web UI for the scaffold — CLI only in v1.

Source mapping

Genesis-original. Source of design intent: docs/superpowers/specs/2026-05-13-api-plugin-foundation-design.md.

Requirement Design doc section
create-suaveplan-plugin <name> scaffold §13.7
Generated files compile + bun test green immediately §13.7
Integration test wired with testing-integration-postgres when DB selected §13.7

Verification approach

  • src/prompt/prompt.test.ts — every prompt branch produces the right capability set; invalid names raise SCAFFOLD_INVALID_NAME.
  • src/generator/generator.test.ts — each template file renders with the right substitutions for a given prompt set.
  • tests/scaffold-output/scaffold-output.test.ts — snapshot test: run the generator against three fixture prompt sets (trusted+postgres+full, isolated+sqlite+REST-only, sandboxed+none+REST-only) and assert the produced tree matches tests/scaffold-output/snapshots/<fixture>/** byte-for-byte.
  • tests/scaffold-output/runs-bun-test.test.ts — for each fixture, run bun test against the generated tree AND assert exit code 0 (proves the scaffold is immediately green).
  • tests/dep-graph.test.ts — runtime deps.

Migration impact

None — additive only. The scaffold is published as a separate npm package consumable via bunx create-suaveplan-plugin <name>.