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

116 lines
4.9 KiB
Markdown

<!-- markdownlint-disable MD024 -->
# Capability Spec Delta: create-suaveplan-plugin (create-suaveplan-plugin)
**Package**: `create-suaveplan-plugin`
**Status**: PROPOSED
> Every requirement below carries a `**Verified by:**` line at authoring time.
## ADDED Requirements
### Requirement: Scaffold emits a known file tree per prompt branch
The scaffold SHALL emit a deterministic file tree given a prompt set. The tree SHALL include:
- `plugin.json`
- `src/index.ts`
- `src/index.test.ts`
- `tests/integration/example.integration.test.ts` (when a DB engine is selected)
- `vitest.config.ts`
- `vitest.integration.config.ts` (when a DB engine is selected)
- `migrations/<engine>/0001-init.sql` (when a DB engine is selected)
- `README.md`
- `package.json`
- `tsconfig.json`
- `.gitignore`
The exact file set MUST match the committed snapshot for each fixture prompt set.
#### Scenario: trusted+postgres+full prompt set
- WHEN the scaffold runs with the `trusted+postgres+full` fixture prompts
- THEN the produced tree matches `tests/scaffold-output/snapshots/trusted-postgres-full/**` byte-for-byte
#### Scenario: isolated+sqlite+REST-only prompt set
- WHEN the scaffold runs with the `isolated+sqlite+rest-only` fixture prompts
- THEN the produced tree matches `tests/scaffold-output/snapshots/isolated-sqlite-rest-only/**` byte-for-byte
#### Scenario: sandboxed+none+REST-only prompt set
- WHEN the scaffold runs with the `sandboxed-none-rest-only` fixture prompts
- THEN the produced tree matches `tests/scaffold-output/snapshots/sandboxed-none-rest-only/**` byte-for-byte AND does NOT emit `tests/integration/` or `migrations/` directories
**Verified by:** `tests/scaffold-output/scaffold-output.test.ts::"trusted+postgres+full snapshot match"` AND `tests/scaffold-output/scaffold-output.test.ts::"isolated+sqlite+rest-only snapshot match"` AND `tests/scaffold-output/scaffold-output.test.ts::"sandboxed-none-rest-only snapshot match"`
---
### Requirement: Generated tree passes `bun test` immediately
For every fixture prompt set, running `bun test` against the freshly-generated tree SHALL exit 0 (proving the scaffold is immediately green).
#### Scenario: generated tree is green on first run
- WHEN the scaffold runs the `trusted+postgres+full` fixture AND `bun test` is invoked in the produced directory
- THEN the exit code is 0 AND every `it(...)` in `src/index.test.ts` passes
**Verified by:** `tests/scaffold-output/runs-bun-test.test.ts::"every fixture passes bun test on first run"`
---
### Requirement: Invalid name handling
The scaffold SHALL validate the supplied name (npm-package-name rules) AND raise `SCAFFOLD_INVALID_NAME` on a non-conforming value. The validation MUST run before any directory is created.
#### Scenario: uppercase name rejected
- WHEN the scaffold runs with name `"Foo"`
- THEN it raises `SCAFFOLD_INVALID_NAME` AND no directory is created
**Verified by:** `src/prompt/prompt.test.ts::"uppercase name raises SCAFFOLD_INVALID_NAME"`
---
### Requirement: Existing directory refuses overwrite
The scaffold SHALL refuse to write into an existing non-empty directory unless `--force` is passed. The refusal raises `SCAFFOLD_DIRECTORY_EXISTS`.
#### Scenario: pre-existing directory raises
- WHEN the target directory contains files AND `--force` is not given
- THEN the scaffold raises `SCAFFOLD_DIRECTORY_EXISTS` AND writes nothing
#### Scenario: force flag overwrites
- WHEN `--force` is given
- THEN the scaffold writes the tree, overwriting prior files
**Verified by:** `tests/scaffold-output/scaffold-output.test.ts::"pre-existing directory raises without force"` AND `tests/scaffold-output/scaffold-output.test.ts::"--force overwrites prior files"`
---
### Requirement: vitest configs use `createTestConfig`
The generated `vitest.config.ts` AND `vitest.integration.config.ts` SHALL use `createTestConfig` from `@suaveplan/testing/config` (no `mergeConfig`-with-base pattern that breaks polyfills).
#### Scenario: generated vitest configs use createTestConfig
- WHEN the scaffold runs any fixture
- THEN the produced `vitest.config.ts` imports `createTestConfig` from `@suaveplan/testing/config` AND does not import `baseVitestConfig`
**Verified by:** `tests/scaffold-output/scaffold-output.test.ts::"generated vitest configs use createTestConfig"`
---
### Requirement: Integration test wired with `testing-integration-postgres` (or sibling) when DB selected
When the prompt selects a DB engine, the generated `tests/integration/example.integration.test.ts` SHALL import the matching `testing-integration-{postgres,sqlite,surrealdb}` fixture AND gate execution on `INTEGRATION=1`.
#### Scenario: postgres selection wires testing-integration-postgres
- WHEN the prompt selects `database.engine = "postgres"`
- THEN the produced integration test imports `@suaveplan/testing-integration-postgres` AND wraps `describe(...)` in an `INTEGRATION === "1"` gate
**Verified by:** `tests/scaffold-output/scaffold-output.test.ts::"postgres selection wires testing-integration-postgres"`