create-win-project 1.3.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +58 -160
- package/checks/check-compatibility.js +95 -0
- package/{scripts/verify-generated.mjs → checks/check-generated-project.js} +28 -4
- package/{scripts/validate-content.mjs → checks/check-library.js} +17 -7
- package/checks/check-package.js +15 -0
- package/checks/classify-changes.js +29 -0
- package/checks/run-compatibility-shard.js +21 -0
- package/docs/README.md +20 -0
- package/docs/capabilities.md +13 -0
- package/docs/compatibility.md +13 -0
- package/docs/generated-project.md +12 -0
- package/docs/getting-started.md +26 -0
- package/docs/maintainers/architecture.md +161 -0
- package/docs/maintainers/ci-strategy.md +46 -0
- package/docs/{CONTENT_MODEL.md → maintainers/content-model.md} +3 -3
- package/docs/maintainers/contributing.md +154 -0
- package/docs/{DEPENDENCY_MAINTENANCE.md → maintainers/dependencies.md} +1 -1
- package/docs/migration-v2.md +13 -0
- package/docs/production-contract.md +24 -0
- package/index.js +2 -429
- package/{playbooks → library}/INDEX.md +5 -5
- package/library/compatibility-impact.json +14 -0
- package/{playbooks/capabilities/ci/github-actions.manifest.json → library/development-tools/ci/definition.json} +1 -0
- package/library/development-tools/devops/makefile/commands.md +11 -0
- package/library/development-tools/devops/makefile/definition.json +11 -0
- package/library/development-tools/devops/makefile/docker.md +9 -0
- package/library/development-tools/devops/makefile/validation.md +5 -0
- package/{playbooks/devops/pr-template.manifest.json → library/development-tools/devops/pr-template/definition.json} +1 -0
- package/library/features/sqlalchemy-alembic.md +17 -0
- package/library/optional-features/concerns/zod/errors.md +5 -0
- package/library/optional-features/concerns/zod/testing.md +5 -0
- package/library/optional-features/concerns/zod/validation.md +21 -0
- package/library/optional-features/styling/css-modules/definition.json +12 -0
- package/library/optional-features/styling/css-modules/responsive.md +5 -0
- package/library/optional-features/styling/css-modules/theme.md +7 -0
- package/{playbooks/platform/mobile.manifest.json → library/platforms/mobile/definition.json} +1 -0
- package/{playbooks/platform/web.manifest.json → library/platforms/web/definition.json} +1 -0
- package/{playbooks/stack/react-native.manifest.json → library/stacks/expo/definition.json} +2 -2
- package/library/stacks/fastapi/architecture.md +40 -0
- package/library/stacks/fastapi/definition.json +39 -0
- package/library/stacks/fastapi/runtime.md +25 -0
- package/library/stacks/fastapi/security.md +26 -0
- package/library/stacks/fastapi/structure.md +27 -0
- package/library/stacks/fastapi/testing.md +23 -0
- package/{playbooks/stack/nextjs.manifest.json → library/stacks/nextjs/definition.json} +2 -2
- package/{playbooks/stack/no-frontend.manifest.json → library/stacks/no-frontend/definition.json} +1 -1
- package/{playbooks/stack/react-vite.manifest.json → library/stacks/react-vite/definition.json} +2 -2
- package/{compatibility/profiles.json → library/tested-versions.json} +46 -2
- package/{playbooks/universal/accessibility.manifest.json → library/universal/accessibility/definition.json} +1 -1
- package/library/universal/coding-rules/definition.json +13 -0
- package/library/universal/coding-rules/hygiene.md +9 -0
- package/library/universal/coding-rules/naming.md +17 -0
- package/{playbooks/universal/error-handling.manifest.json → library/universal/error-handling/definition.json} +1 -0
- package/library/universal/git-conventions/branches.md +5 -0
- package/library/universal/git-conventions/commits.md +7 -0
- package/library/universal/git-conventions/definition.json +13 -0
- package/library/universal/git-conventions/workflow.md +5 -0
- package/{playbooks/universal/observability.manifest.json → library/universal/observability/definition.json} +1 -0
- package/{playbooks/universal/security.manifest.json → library/universal/security/definition.json} +1 -0
- package/library/universal/typescript/boundaries.md +13 -0
- package/library/universal/typescript/definition.json +12 -0
- package/library/universal/typescript/errors.md +5 -0
- package/library/universal/typescript/patterns.md +7 -0
- package/package.json +14 -15
- package/public/logo.svg +19 -0
- package/src/cli/arguments.js +63 -0
- package/src/cli/display.js +220 -0
- package/src/cli/main.js +203 -0
- package/src/cli/navigation.js +156 -0
- package/src/cli/questions.js +188 -0
- package/src/cli/system-check.js +158 -0
- package/src/engine/create-project.js +10 -0
- package/src/engine/install-dependencies.js +13 -0
- package/{lib/catalog.js → src/engine/load-library.js} +8 -8
- package/{lib/files.js → src/engine/project-files.js} +10 -1
- package/{lib/playbooks.js → src/engine/project-guidance.js} +26 -3
- package/{lib/application-shapes.js → src/engine/project-shapes.js} +4 -4
- package/{lib/template.js → src/engine/render-templates.js} +11 -0
- package/{lib/compatibility.js → src/engine/tested-versions.js} +21 -2
- package/src/engine/upgrade-report.js +20 -0
- package/src/engine/write-files.js +34 -0
- package/{lib/stacks/registry.js → src/stacks/available-stacks.js} +25 -1
- package/src/stacks/backends/README.md +5 -0
- package/src/stacks/backends/fastapi/ci.js +3 -0
- package/src/stacks/backends/fastapi/create-files.js +874 -0
- package/src/stacks/backends/fastapi/docker.js +75 -0
- package/src/stacks/backends/fastapi/environment.js +3 -0
- package/src/stacks/backends/fastapi/index.js +32 -0
- package/{lib/stacks → src/stacks/backends}/laravel/architecture.js +1 -0
- package/{lib/stacks → src/stacks/backends}/laravel/auth/oidc.js +1 -0
- package/{lib/stacks → src/stacks/backends}/laravel/auth/public.js +1 -0
- package/{lib/stacks → src/stacks/backends}/laravel/auth/sanctum.js +1 -0
- package/{lib/stacks → src/stacks/backends}/laravel/auth/session.js +1 -0
- package/src/stacks/backends/laravel/ci.js +3 -0
- package/{lib/stacks → src/stacks/backends}/laravel/composer.js +1 -1
- package/{lib/stacks/laravel/generate.js → src/stacks/backends/laravel/create-files.js} +1 -0
- package/src/stacks/backends/laravel/docker.js +14 -0
- package/src/stacks/backends/laravel/environment.js +5 -0
- package/{lib/stacks → src/stacks/backends}/laravel/index.js +11 -3
- package/{lib/stacks → src/stacks/backends}/laravel/ui/blade.js +1 -0
- package/{lib/stacks → src/stacks/backends}/laravel/ui/index.js +1 -0
- package/{lib/stacks → src/stacks/backends}/laravel/ui/inertia-react.js +4 -2
- package/{lib/stacks → src/stacks/backends}/laravel/ui/livewire.js +1 -0
- package/{lib/stacks → src/stacks/backends}/laravel/ui/shared.js +1 -0
- package/src/stacks/backends/none/index.js +23 -0
- package/src/stacks/backends/postgres/ci.js +3 -0
- package/src/stacks/backends/postgres/create-files.js +21 -0
- package/src/stacks/backends/postgres/docker.js +3 -0
- package/src/stacks/backends/postgres/environment.js +3 -0
- package/src/stacks/backends/postgres/index.js +30 -0
- package/src/stacks/backends/springboot/ci.js +3 -0
- package/src/stacks/backends/springboot/create-files.js +91 -0
- package/src/stacks/backends/springboot/docker.js +3 -0
- package/src/stacks/backends/springboot/environment.js +3 -0
- package/src/stacks/backends/springboot/index.js +31 -0
- package/src/stacks/backends/supabase/ci.js +3 -0
- package/src/stacks/backends/supabase/create-files.js +52 -0
- package/src/stacks/backends/supabase/docker.js +3 -0
- package/src/stacks/backends/supabase/environment.js +3 -0
- package/src/stacks/backends/supabase/index.js +31 -0
- package/src/stacks/backends/supabase/native.js +14 -0
- package/src/stacks/compose-files.js +259 -0
- package/{lib/generator.js → src/stacks/create-project.js} +206 -57
- package/src/stacks/frontends/README.md +4 -0
- package/src/stacks/frontends/nextjs/ci.js +3 -0
- package/src/stacks/frontends/nextjs/create-files.js +46 -0
- package/src/stacks/frontends/nextjs/dependencies.js +5 -0
- package/src/stacks/frontends/nextjs/docker.js +3 -0
- package/src/stacks/frontends/nextjs/environment.js +7 -0
- package/src/stacks/frontends/nextjs/index.js +35 -0
- package/src/stacks/frontends/react-native/ci.js +3 -0
- package/src/stacks/frontends/react-native/create-files.js +28 -0
- package/src/stacks/frontends/react-native/dependencies.js +5 -0
- package/src/stacks/frontends/react-native/docker.js +5 -0
- package/src/stacks/frontends/react-native/environment.js +7 -0
- package/src/stacks/frontends/react-native/index.js +30 -0
- package/src/stacks/frontends/react-vite/ci.js +3 -0
- package/src/stacks/frontends/react-vite/create-files.js +27 -0
- package/src/stacks/frontends/react-vite/dependencies.js +5 -0
- package/src/stacks/frontends/react-vite/docker.js +3 -0
- package/src/stacks/frontends/react-vite/environment.js +8 -0
- package/src/stacks/frontends/react-vite/index.js +32 -0
- package/src/stacks/shared/capability-packs.js +31 -0
- package/{lib → src}/stacks/shared/contributions.js +1 -1
- package/src/stacks/shared/environment.js +38 -0
- package/src/stacks/shared/javascript-package.js +117 -0
- package/src/stacks/shared/testing-files.js +16 -0
- package/templates/ci/fastapi.yml +62 -0
- package/templates/docker/compose/postgres.yml +1 -1
- package/templates/docker/compose/springboot.yml +3 -3
- package/templates/docker/compose/supabase.yml +1 -1
- package/templates/docker/compose-prod/fastapi.yml +52 -0
- package/templates/docker/compose-prod/springboot.yml +20 -2
- package/templates/docker/dockerfile/fastapi.dev.dockerfile +9 -0
- package/templates/docker/dockerfile/fastapi.prod.dockerfile +11 -0
- package/templates/docker/dockerfile/nextjs.prod.dockerfile +1 -0
- package/templates/docker/dockerfile/springboot.prod.dockerfile +4 -1
- package/templates/docker/dockerfile/vite.prod.dockerfile +2 -1
- package/templates/makefile/fastapi.mk +97 -0
- package/docs/ARCHITECTURE.md +0 -118
- package/lib/banner.js +0 -45
- package/lib/constants.js +0 -3
- package/lib/doctor.js +0 -45
- package/lib/interview.js +0 -77
- package/lib/laravel-scaffold.js +0 -3
- package/lib/scaffold.js +0 -467
- package/lib/stacks/index.js +0 -8
- package/playbooks/concerns/zod.md +0 -174
- package/playbooks/devops/makefile.manifest.json +0 -10
- package/playbooks/devops/makefile.md +0 -556
- package/playbooks/styling/css-modules-extensions.md +0 -267
- package/playbooks/styling/css-modules.manifest.json +0 -11
- package/playbooks/universal/coding-rules.manifest.json +0 -12
- package/playbooks/universal/coding-rules.md +0 -281
- package/playbooks/universal/git-conventions.manifest.json +0 -10
- package/playbooks/universal/git-conventions.md +0 -186
- package/playbooks/universal/typescript.manifest.json +0 -11
- package/playbooks/universal/typescript.md +0 -272
- package/scripts/compatibility-matrix.mjs +0 -48
- /package/{playbooks/capabilities → library/development-tools}/ci/github-actions.md +0 -0
- /package/{playbooks/devops → library/development-tools/devops/pr-template}/pr-template.md +0 -0
- /package/{playbooks/capabilities/docker/docker.manifest.json → library/development-tools/docker/definition.json} +0 -0
- /package/{playbooks/capabilities → library/development-tools}/docker/overview.md +0 -0
- /package/{playbooks/capabilities → library/features}/auth/oidc-resource-server.md +0 -0
- /package/{playbooks/capabilities → library/features}/auth/spring-session.md +0 -0
- /package/{playbooks/capabilities/flyway/flyway.manifest.json → library/features/flyway/definition.json} +0 -0
- /package/{playbooks/capabilities → library/features}/flyway/environments.md +0 -0
- /package/{playbooks/capabilities → library/features}/flyway/migrations.md +0 -0
- /package/{playbooks/capabilities → library/features}/flyway/testing.md +0 -0
- /package/{playbooks/capabilities → library/features}/laravel/database.md +0 -0
- /package/{playbooks/capabilities → library/features}/laravel/migrations.md +0 -0
- /package/{playbooks/capabilities → library/features}/laravel/observability.md +0 -0
- /package/{playbooks/capabilities → library/features}/laravel/oidc-resource-server.md +0 -0
- /package/{playbooks/capabilities → library/features}/laravel/queues.md +0 -0
- /package/{playbooks/capabilities → library/features}/laravel/sanctum-spa.md +0 -0
- /package/{playbooks/capabilities → library/features}/laravel/scheduler.md +0 -0
- /package/{playbooks/capabilities → library/features}/laravel/session-auth.md +0 -0
- /package/{playbooks/capabilities → library/features}/laravel/storage-uploads.md +0 -0
- /package/{playbooks/capabilities → library/features}/postgresql/architecture.md +0 -0
- /package/{playbooks/capabilities/postgresql/postgresql.manifest.json → library/features/postgresql/definition.json} +0 -0
- /package/{playbooks/capabilities → library/features}/postgresql/migrations.md +0 -0
- /package/{playbooks/capabilities → library/features}/postgresql/schema-design.md +0 -0
- /package/{playbooks/capabilities → library/features}/postgresql/security.md +0 -0
- /package/{playbooks/capabilities → library/features}/postgresql/testing.md +0 -0
- /package/{playbooks/capabilities → library/features}/prisma/architecture.md +0 -0
- /package/{playbooks/capabilities/prisma/prisma.manifest.json → library/features/prisma/definition.json} +0 -0
- /package/{playbooks/capabilities → library/features}/prisma/migrations.md +0 -0
- /package/{playbooks/capabilities → library/features}/prisma/runtime.md +0 -0
- /package/{playbooks/capabilities → library/features}/prisma/schema.md +0 -0
- /package/{playbooks/capabilities → library/features}/prisma/testing.md +0 -0
- /package/{playbooks/capabilities → library/features}/supabase/architecture.md +0 -0
- /package/{playbooks/capabilities → library/features}/supabase/authentication.md +0 -0
- /package/{playbooks/capabilities/supabase/supabase.manifest.json → library/features/supabase/definition.json} +0 -0
- /package/{playbooks/capabilities → library/features}/supabase/expo.md +0 -0
- /package/{playbooks/capabilities → library/features}/supabase/migrations.md +0 -0
- /package/{playbooks/capabilities → library/features}/supabase/nextjs.md +0 -0
- /package/{playbooks/capabilities → library/features}/supabase/rls.md +0 -0
- /package/{playbooks/capabilities → library/features}/supabase/testing.md +0 -0
- /package/{playbooks/capabilities → library/features}/supabase/vite.md +0 -0
- /package/{playbooks → library/optional-features}/concerns/axios.md +0 -0
- /package/{playbooks → library/optional-features}/concerns/next-safe-action.md +0 -0
- /package/{playbooks → library/optional-features}/concerns/next-themes.md +0 -0
- /package/{playbooks → library/optional-features}/concerns/nuqs.md +0 -0
- /package/{playbooks → library/optional-features}/concerns/t3-env.md +0 -0
- /package/{playbooks → library/optional-features}/concerns/tanstack-query.md +0 -0
- /package/{playbooks → library/optional-features}/concerns/zustand.md +0 -0
- /package/{playbooks/styling/native-styles.manifest.json → library/optional-features/styling/native-styles/definition.json} +0 -0
- /package/{playbooks/styling → library/optional-features/styling/native-styles}/native-styles.md +0 -0
- /package/{playbooks/styling/tailwind.manifest.json → library/optional-features/styling/tailwind/definition.json} +0 -0
- /package/{playbooks/styling → library/optional-features/styling/tailwind}/tailwind-extensions.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/blade/architecture.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/blade/runtime.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/blade/security.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/blade/structure.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/blade/testing.md +0 -0
- /package/{playbooks/stack/laravel-ui.manifest.json → library/platforms/laravel-ui/definition.json} +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/inertia-react/architecture.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/inertia-react/runtime.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/inertia-react/security.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/inertia-react/structure.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/inertia-react/testing.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/livewire/architecture.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/livewire/runtime.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/livewire/security.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/livewire/structure.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/livewire/testing.md +0 -0
- /package/{playbooks/platform → library/platforms/mobile}/mobile.md +0 -0
- /package/{playbooks/platform → library/platforms/web}/web.md +0 -0
- /package/{playbooks/stack → library/stacks}/expo/architecture.md +0 -0
- /package/{playbooks/stack → library/stacks}/expo/runtime.md +0 -0
- /package/{playbooks/stack → library/stacks}/expo/security.md +0 -0
- /package/{playbooks/stack → library/stacks}/expo/structure.md +0 -0
- /package/{playbooks/stack → library/stacks}/expo/testing.md +0 -0
- /package/{playbooks/stack → library/stacks}/laravel/architecture.md +0 -0
- /package/{playbooks/stack/laravel.manifest.json → library/stacks/laravel/definition.json} +0 -0
- /package/{playbooks/stack → library/stacks}/laravel/runtime.md +0 -0
- /package/{playbooks/stack → library/stacks}/laravel/security.md +0 -0
- /package/{playbooks/stack → library/stacks}/laravel/structure.md +0 -0
- /package/{playbooks/stack → library/stacks}/laravel/testing.md +0 -0
- /package/{playbooks/stack → library/stacks}/nextjs/architecture.md +0 -0
- /package/{playbooks/stack → library/stacks}/nextjs/runtime.md +0 -0
- /package/{playbooks/stack → library/stacks}/nextjs/security.md +0 -0
- /package/{playbooks/stack → library/stacks}/nextjs/structure.md +0 -0
- /package/{playbooks/stack → library/stacks}/nextjs/testing.md +0 -0
- /package/{playbooks/stack/none.manifest.json → library/stacks/none/definition.json} +0 -0
- /package/{playbooks/stack → library/stacks}/react-vite/architecture.md +0 -0
- /package/{playbooks/stack → library/stacks}/react-vite/runtime.md +0 -0
- /package/{playbooks/stack → library/stacks}/react-vite/security.md +0 -0
- /package/{playbooks/stack → library/stacks}/react-vite/structure.md +0 -0
- /package/{playbooks/stack → library/stacks}/react-vite/testing.md +0 -0
- /package/{playbooks/stack → library/stacks}/springboot/architecture.md +0 -0
- /package/{playbooks/stack/springboot.manifest.json → library/stacks/springboot/definition.json} +0 -0
- /package/{playbooks/stack → library/stacks}/springboot/runtime.md +0 -0
- /package/{playbooks/stack → library/stacks}/springboot/security.md +0 -0
- /package/{playbooks/stack → library/stacks}/springboot/structure.md +0 -0
- /package/{playbooks/stack → library/stacks}/springboot/testing.md +0 -0
- /package/{playbooks/universal → library/universal/accessibility}/accessibility.md +0 -0
- /package/{playbooks/universal → library/universal/error-handling}/error-handling.md +0 -0
- /package/{playbooks/universal → library/universal/observability}/observability.md +0 -0
- /package/{playbooks/universal → library/universal/security}/security.md +0 -0
- /package/{lib → src/engine}/project-location.js +0 -0
- /package/{lib → src}/stacks/context.js +0 -0
- /package/{lib/stacks/contract.js → src/stacks/rules.js} +0 -0
- /package/{ci → templates/ci}/expo.yml +0 -0
- /package/{ci → templates/ci}/laravel.yml +0 -0
- /package/{ci → templates/ci}/nextjs.yml +0 -0
- /package/{ci → templates/ci}/springboot.yml +0 -0
- /package/{ci → templates/ci}/vite.yml +0 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Getting started
|
|
2
|
+
|
|
3
|
+
Run the generator with Node.js 24 LTS or Docker. Generated projects list their own runtime requirements in `docs/guides/setup.md`.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx create-win-project@latest
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
The interview asks for application shape, framework, backend/data boundary, architecture, authentication, and applicable capabilities. It can install dependencies and create lockfiles immediately.
|
|
10
|
+
|
|
11
|
+
For development from a clone:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm ci
|
|
15
|
+
npm run doctor
|
|
16
|
+
npm start
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
For a containerized generator:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
docker compose build
|
|
23
|
+
docker compose run --rm app
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
After generation, enter the new directory and follow its README. The CLI stages files before moving them into place and refuses to overwrite a non-empty destination.
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
`create-win-project` composes a validated project specification into two coordinated outputs:
|
|
4
|
+
|
|
5
|
+
1. a small executable application that establishes the stack's real conventions;
|
|
6
|
+
2. a task-routed documentation layer for humans and coding agents.
|
|
7
|
+
|
|
8
|
+
Executable behavior, tests, and framework configuration are the source of truth. Playbooks explain and extend that behavior; they must not contradict it.
|
|
9
|
+
|
|
10
|
+
## Generation pipeline
|
|
11
|
+
|
|
12
|
+
```text
|
|
13
|
+
CLI interview
|
|
14
|
+
↓
|
|
15
|
+
validated answers
|
|
16
|
+
↓
|
|
17
|
+
available-stacks + resolve-project + load-library + tested-versions
|
|
18
|
+
↓
|
|
19
|
+
resolved stack descriptor
|
|
20
|
+
├── runnable framework files (from src/stacks/*/create-files.js)
|
|
21
|
+
├── optional CI / Docker / Makefile files (from templates/)
|
|
22
|
+
├── project context and documentation
|
|
23
|
+
└── selected playbooks + RULES.md router
|
|
24
|
+
↓
|
|
25
|
+
generated-project contract tests
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Source ownership (completed)
|
|
29
|
+
|
|
30
|
+
Three explicit source boundaries. No `lib/` directory exists — `src/` is canonical.
|
|
31
|
+
|
|
32
|
+
- `src/cli` owns terminal arguments, questions and navigation, display, warnings, summaries, and system checks. It may call the engine and read stack descriptions. It must not contain stack dependency tables or `if (stack === "nextjs")` branches.
|
|
33
|
+
- `src/engine` owns validated project orchestration, tested-version and library loading, safe writes, dependency installation, and template rendering. It must not import terminal code or concrete stack folders. It contains zero `stack.frontendKey` branches — it is stack-agnostic.
|
|
34
|
+
- `src/stacks` owns stack rules, the explicit available-stack list, and stack-specific generated behavior. Stack modules must not import CLI or engine implementation modules. Each `src/stacks/<frontends|backends>/<id>/` owns its files, dependencies (names only), environment names, Docker and CI contributions.
|
|
35
|
+
|
|
36
|
+
During the migration `lib/` provided compatibility shims (`export * from '../src/...'`). After v1.4.0 those shims are deleted. `tests/architecture-boundaries.test.js` enforces dependency direction, and `tests/architecture/no-lib-legacy.test.js` bans `src -> lib` imports and one-line wrapper regressions.
|
|
37
|
+
|
|
38
|
+
Root `index.js` remains the stable executable entry point. Generated-project paths such as `playbooks/`, `RULES.md`, and application folders are user-facing and do not change merely because generator source files move.
|
|
39
|
+
|
|
40
|
+
### CLI boundary
|
|
41
|
+
|
|
42
|
+
Root `index.js` is only the stable executable shim. `src/cli/main.js` coordinates the command, `arguments.js` parses and validates flags, `questions.js` defines the interview, `navigation.js` owns Back behavior, `display.js` owns terminal presentation (`w1nBanner` + `projectLocationNotice`), and `system-check.js` detects runtime support and `collectDiagnostics/printDoctor`. The CLI gathers project identity, frontend, optional backend, styling, one Small/Medium/Large architecture profile, login intent, client audience when relevant, testing depth, and optional operational tooling. Medium is shown first and is the default. CLI modules do not contain stack dependency tables.
|
|
43
|
+
|
|
44
|
+
`generateProject()` in `src/engine/create-project.js` validates the same answers again because it is also an exported programmatic API. A caller cannot bypass destination-name, Java-package, or testing-profile validation by skipping the CLI.
|
|
45
|
+
|
|
46
|
+
### Catalog and resolution
|
|
47
|
+
|
|
48
|
+
`src/engine/load-library.js` walks `library/**/definition.json` and merges manifests into a catalog index. `src/engine/tested-versions.js` validates `library/tested-versions.json` and resolves every package name to an exact version for the selected profile. `src/engine/resolve-project.js` merges selected capabilities into one resolved stack descriptor. No versions live in definitions or scaffold code.
|
|
49
|
+
|
|
50
|
+
Stack-specific behavior crosses into core orchestration through the contract in `src/stacks/rules.js` (`defineStackAdapter`). Every frontend, backend, or data adapter has a stable identity, declares compatible adapters and supported application/authentication/architecture models, and is added to the explicit registry in `src/stacks/available-stacks.js`. Registration is deliberate and explicit — adapters are never discovered by scanning directories; adding a file does not silently activate a stack.
|
|
51
|
+
|
|
52
|
+
Adapters may contribute via `CONTRIBUTION_HOOKS`:
|
|
53
|
+
|
|
54
|
+
- `prompts` in a core-defined prompt slot;
|
|
55
|
+
- `authentication` models;
|
|
56
|
+
- `files` via `create-files.js` (`(answers, context) -> FileMap`);
|
|
57
|
+
- `environment` declarations (semantic names like `API_URL`);
|
|
58
|
+
- `install` steps;
|
|
59
|
+
- `docker` and `ci` fragments;
|
|
60
|
+
- `verification` cases.
|
|
61
|
+
|
|
62
|
+
Example:
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
// src/stacks/frontends/nextjs/index.js
|
|
66
|
+
import { defineStackAdapter } from '../../rules.js'
|
|
67
|
+
export const nextjsAdapter = defineStackAdapter({
|
|
68
|
+
id: 'nextjs', kind: 'frontend', label: 'Next.js',
|
|
69
|
+
compatibleWith: { backend: ['none','postgres','supabase','springboot','laravel'] },
|
|
70
|
+
capabilities: { applicationShapes: ['fullstack','separate'], architectureProfiles: ['small','medium','large'], authenticationModels: ['public','undecided','supabase','session','oidc','sanctum-spa','laravel-oidc'] },
|
|
71
|
+
contributes: {
|
|
72
|
+
environment: ({ backend }) => backend.id === 'none' ? [] : ['API_URL'],
|
|
73
|
+
install: () => [{ cwd: '.', command: 'npm', args: ['install'] }],
|
|
74
|
+
docker: () => [{ template: 'nextjs', developmentPath: 'Dockerfile.dev', productionPath: 'Dockerfile' }],
|
|
75
|
+
ci: () => [{ template: 'nextjs', path: '.github/workflows/ci-frontend.yml' }],
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
- **Next.js** owns route-oriented Small; feature services/actions/queries and owned repositories or remote API clients in Medium; public feature APIs and enforced boundaries in Large — all in `src/stacks/frontends/nextjs/create-files.js`.
|
|
81
|
+
- **React + Vite** owns thin browser features in Small, feature modules in Medium, and public feature APIs plus boundary checks in Large — in `src/stacks/frontends/react-vite/create-files.js`.
|
|
82
|
+
- **React Native** owns Expo shell, mobile architecture profiles, local install and CI contributions in `src/stacks/frontends/react-native/create-files.js`. It deliberately contributes no frontend Docker workflow.
|
|
83
|
+
- **Spring Boot** owns Maven launcher, application and security configuration, package-by-feature variants, migrations, tests, and runtime Docker/CI in `src/stacks/backends/springboot/create-files.js`.
|
|
84
|
+
- **Laravel** owns composer definition, application files, authentication models, and Blade/Livewire/Inertia React UI variants in `src/stacks/backends/laravel/` — `create-files.js` + `composer.js` + `architecture.js` + `auth/{session,sanctum,oidc,public}.js` + `ui/{blade,livewire,inertia-react,shared}.js`. Names `auth/` and `ui/` are kept (not `login/`/`user-interface`) for conciseness; `create-files.js` is used everywhere for consistency with `create-project.js`.
|
|
85
|
+
- **Supabase** owns framework-specific clients, native token lifecycle, local project config, migrations, RLS policies, and verification in `src/stacks/backends/supabase/` (`create-files.js` + `native.js`).
|
|
86
|
+
- **PostgreSQL + Prisma** owns schema, client initialization, migration commands, database environment, Docker contribution in `src/stacks/backends/postgres/create-files.js`.
|
|
87
|
+
- **no-backend** explicitly owns frontend-only compatibility and confirms no server files, install steps, Docker services, credentials, or pretend authentication are contributed.
|
|
88
|
+
|
|
89
|
+
Core code owns prompt order, compatibility-profile resolution, atomic writes, process execution, and final composition. An adapter receives a read-only stack context (`createStackContext`) and returns contributions; it cannot write arbitrary paths or install global tools. Adapter definitions do not accept dependency tables or version fields. Exact versions remain exclusively owned by `library/tested-versions.json`.
|
|
90
|
+
|
|
91
|
+
Manifests declare:
|
|
92
|
+
|
|
93
|
+
- identity and compatibility (`id`, `kind`, `appliesTo`);
|
|
94
|
+
- dependency names and scripts (never dependency versions);
|
|
95
|
+
- semantic environment names and which ones are client-visible;
|
|
96
|
+
- supported architecture profiles, conditional playbooks, and optional templates;
|
|
97
|
+
- constraints shown to the agent;
|
|
98
|
+
- concerns and their playbook sections.
|
|
99
|
+
|
|
100
|
+
Client environment variables are semantic in definitions (`API_URL`) and receive exactly one framework prefix during resolution (`NEXT_PUBLIC_API_URL`, `VITE_API_URL`, or `EXPO_PUBLIC_API_URL`). Public prefixes always mean the value is shipped to the client.
|
|
101
|
+
|
|
102
|
+
### Runnable scaffold (stack-owned vertical)
|
|
103
|
+
|
|
104
|
+
Each `src/stacks/{frontends,backends}/<id>/create-files.js` is a pure function `(answers, stack, shared) -> FileMap` that owns its minimum executable vertical slice. `shared/` contains helpers only when at least two stacks genuinely share behavior—not forced sharing. Core composes stack adapters through their contribution hooks. This intentionally generates a small working example. Domain-specific features are added after product context is known; the generator does not invent business entities.
|
|
105
|
+
|
|
106
|
+
### Repository and operational files
|
|
107
|
+
|
|
108
|
+
`src/engine/create-project.js` coordinates writes and refuses to merge into a non-empty destination. It adds documentation, selected playbooks, CI, Docker, Makefile, environment examples, and repository conventions around the runnable foundation.
|
|
109
|
+
|
|
110
|
+
Engine infrastructure is separated from generated-file decisions. `src/engine/write-files.js` validates destinations, stages writes, removes failed staging trees, and publishes completed trees atomically. `src/engine/render-templates.js` combines rendering with that safe write boundary (`writeRenderedFile` + `render`/`readTemplate`/`buildVars`). `src/engine/install-dependencies.js` is the only engine process runner and stops at the first failed package-manager step. `src/engine/tested-versions.js` and `src/engine/load-library.js` expose version resolution and library loading separately. After the migration `lib/` shims are deleted; `src/` is the sole implementation.
|
|
111
|
+
|
|
112
|
+
The first `npm install` creates the lockfile. Generated CI uses `npm ci`, so the lockfile must be committed before CI is enabled. `create-win-project.profile.json` separately records the compatibility profile, architecture profile, and authentication intent/model/audience; after generation, that project owns its own upgrade lifecycle.
|
|
113
|
+
|
|
114
|
+
### Compatibility profile lifecycle
|
|
115
|
+
|
|
116
|
+
Exactly one profile is `current` and one is `previous`. The current profile is the default. A profile owns exact npm, Spring Boot, runtime, and container versions; definitions and scaffold code may only request names or capabilities. Promotion copies the candidate into a new dated profile, marks the former current profile previous, and happens only after the generated-project matrix passes. Major changes also require migration notes. See `DEPENDENCY_MAINTENANCE.md`.
|
|
117
|
+
|
|
118
|
+
## Documentation model
|
|
119
|
+
|
|
120
|
+
| File | Responsibility |
|
|
121
|
+
|------|----------------|
|
|
122
|
+
| `AGENTS.md` | Small always-on command, workflow, safety, and definition-of-done contract. |
|
|
123
|
+
| `CONTEXT.md` | Product goals, boundaries, decisions, and project-specific facts. |
|
|
124
|
+
| `RULES.md` | Generated concern-to-playbook section router. |
|
|
125
|
+
| `playbooks/` | Reusable standards, recipes, rationale, and stack guidance. |
|
|
126
|
+
| `docs/` | Documentation for the generator (ARCHITECTURE, CONTRIBUTING, etc.), not generic framework teaching. |
|
|
127
|
+
| `docs/maintainers/contributing.md` | How to add a stack and run checks — the workflow, not the design. |
|
|
128
|
+
|
|
129
|
+
Manifest section names are checked against Markdown headings. Numbered headings are normalized for matching, and generated contract tests reject unresolved `RULES.md` entries.
|
|
130
|
+
|
|
131
|
+
## Testing strategy
|
|
132
|
+
|
|
133
|
+
The generator itself has three verification levels:
|
|
134
|
+
|
|
135
|
+
1. unit tests for catalog composition and template rendering;
|
|
136
|
+
2. generated-output contract tests for required files, environment naming, playbook routing, profile-specific boundaries, auth metadata/code, testing profiles, and overwrite safety;
|
|
137
|
+
3. a current-and-previous matrix across every supported stack combination, all three architecture profiles, and every applicable authentication model. It installs and runs lint, typecheck, tests, builds, Expo compatibility checks/web export, Spring MVC/security/Modulith tests and Maven packaging, Compose validation, and current-profile container builds.
|
|
138
|
+
|
|
139
|
+
Additional architecture guards:
|
|
140
|
+
|
|
141
|
+
- `tests/architecture-boundaries.test.js` enforces `src/engine` not importing `cli`/`stacks/frontends|backends` and `src/stacks` not importing `cli`/`engine`.
|
|
142
|
+
- `tests/architecture/no-lib-legacy.test.js` bans `src/**` importing `lib/` and one-line wrapper regressions (`export * from '../../lib/...'`) and bans `lib/` existence after the migration.
|
|
143
|
+
|
|
144
|
+
Tests mirror the production folders: `tests/cli`, `tests/engine`, `tests/stacks/frontends`, `tests/stacks/backends`.
|
|
145
|
+
|
|
146
|
+
Canonical Markdown code examples should progressively move into extracted fixtures so examples compile against the versions they teach.
|
|
147
|
+
|
|
148
|
+
## Extension workflow
|
|
149
|
+
|
|
150
|
+
When adding a stack or capability (see `docs/maintainers/contributing.md` for the full checklist):
|
|
151
|
+
|
|
152
|
+
1. Add its `library/**/definition.json` (names only, no versions), playbooks, and `library/tested-versions.json` entry remains version-free.
|
|
153
|
+
2. Create one new `src/stacks/<frontends|backends>/<id>/` directory with `index.js` (`defineStackAdapter`), `create-files.js`, `dependencies.js`/`environment.js` where needed, and `auth/`+`ui/` subfolders for Laravel-style stacks.
|
|
154
|
+
3. Register it once in `src/stacks/available-stacks.js` (explicit array — no scanning).
|
|
155
|
+
4. Add focused contract tests in `tests/stacks/<id>/` and add the stack's cases to `checks/check-compatibility.js`.
|
|
156
|
+
5. Run `npm test`, `node checks/check-library.js`, and `npm run verify:generated -- --profile=<id> --case=<id>-<backend> --architecture=medium` for every supported arch/auth combo; run `npm run matrix:smoke` before `dev` and `matrix:full` before `main`.
|
|
157
|
+
6. Update this architecture document only if ownership or the generation pipeline changed.
|
|
158
|
+
|
|
159
|
+
Do not advertise a capability solely because a playbook mentions it. A generated capability must have executable configuration and contract coverage.
|
|
160
|
+
|
|
161
|
+
Adding a stack must not require editing the engine or unrelated stacks.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# CI and Branch Protection
|
|
2
|
+
|
|
3
|
+
`dev` is the integration branch and `main` is the protected release-ready branch. Use merge
|
|
4
|
+
commits for feature branches so contribution history remains visible.
|
|
5
|
+
|
|
6
|
+
## Required checks
|
|
7
|
+
|
|
8
|
+
| Pull request | Required checks | Coverage |
|
|
9
|
+
|---|---|---|
|
|
10
|
+
| feature → `dev` | `quality`, `compatibility-gate` | Repository tests plus 10 current-profile smoke projects |
|
|
11
|
+
| `dev` → `main` | `quality`, `compatibility-gate` | Every current/previous contract plus representative native and container lanes |
|
|
12
|
+
|
|
13
|
+
Configure both branches to require pull requests, resolve conversations, reject force pushes and
|
|
14
|
+
deletions, and require branches to be current before merging. Restrict direct pushes to `main`.
|
|
15
|
+
Do not require individual matrix job names; require the stable `compatibility-gate` aggregator.
|
|
16
|
+
|
|
17
|
+
Required workflows intentionally have no path filters. A skipped workflow cannot report its check,
|
|
18
|
+
which can leave a required pull request waiting forever or accidentally encourage bypasses.
|
|
19
|
+
|
|
20
|
+
## Manual verification
|
|
21
|
+
|
|
22
|
+
`Generated compatibility` can be started with `workflow_dispatch`. Choose `full` before changing a
|
|
23
|
+
compatibility default or investigating a release candidate; choose `smoke` for a quick diagnostic.
|
|
24
|
+
The pull-request base branch still determines automatic scope: `dev` gets smoke, `main` gets full.
|
|
25
|
+
|
|
26
|
+
The quality suite runs once per revision. The full matrix generates every supported combination
|
|
27
|
+
and checks its metadata contract. Representative risk-bearing lanes additionally install and run
|
|
28
|
+
native tooling; one current-profile lane per container family builds images. This avoids repeating
|
|
29
|
+
the same expensive installation or image build across hundreds of structurally equivalent cases.
|
|
30
|
+
|
|
31
|
+
## Definition of done for generated behavior
|
|
32
|
+
|
|
33
|
+
Repository unit tests are necessary but are not sufficient evidence for a generator change. For
|
|
34
|
+
each affected stack shape, verification must generate a project in a temporary directory and use
|
|
35
|
+
that project's native tools to exercise the behavior users receive:
|
|
36
|
+
|
|
37
|
+
1. Install the exact profile dependencies without weakening install-script controls.
|
|
38
|
+
2. Run the generated formatter, linter, type checker, and tests.
|
|
39
|
+
3. Apply migrations to the declared database, then check for migration drift.
|
|
40
|
+
4. Build the application and validate Compose; build containers for full verification.
|
|
41
|
+
5. Exercise each affected root layout, architecture profile, and authentication model.
|
|
42
|
+
|
|
43
|
+
A warning may be reported separately, but a failed native command is a failed implementation.
|
|
44
|
+
Do not approve a PR based only on generated file presence, string assertions, fixture hashes, or
|
|
45
|
+
the agent's completion statement. The stable `compatibility-gate` is the executable acceptance
|
|
46
|
+
boundary.
|
|
@@ -6,16 +6,16 @@ The project separates always-loaded instructions, task-routed standards, generat
|
|
|
6
6
|
|---|---|---|
|
|
7
7
|
| Agent commands, workflow, authority limits, definition of done | `templates/agents/*.md` → generated `AGENTS.md` | Every project; keep short |
|
|
8
8
|
| Product goal, scope, decisions, unknowns | generated `CONTEXT.md` | Every project; project-specific |
|
|
9
|
-
| Concern routing |
|
|
9
|
+
| Concern routing | definitions → generated `RULES.md` | Selected stack/capability only |
|
|
10
10
|
| Reusable engineering policy and rationale | `playbooks/**/*.md` | A task touches that concern |
|
|
11
11
|
| Setup, API, architecture, deployment for this product | generated `docs/` | Every project, then maintained with code |
|
|
12
|
-
| Framework configuration and canonical patterns | `
|
|
12
|
+
| Framework configuration and canonical patterns | `src/stacks/` file contributions plus tests | The capability is selected |
|
|
13
13
|
|
|
14
14
|
## Authoring rules
|
|
15
15
|
|
|
16
16
|
1. Put a rule in the narrowest applicable playbook. Do not repeat it in `AGENTS.md`, `README.md`, and stack guides.
|
|
17
17
|
2. Write normative language only for behavior the generator configures or tests. Label uninstalled libraries and alternative architectures as optional.
|
|
18
|
-
3. Route concerns to exact Markdown headings from their
|
|
18
|
+
3. Route concerns to exact Markdown headings from their definition. Heading changes and definition changes belong in the same commit.
|
|
19
19
|
4. Prefer a compact rule, a reason, and one canonical example. Remove tutorial-length alternatives that compete with the default.
|
|
20
20
|
5. Keep secrets, authentication, authorization, validation, accessibility, and failure behavior at explicit trust boundaries.
|
|
21
21
|
6. Product docs describe the generated application. Playbooks teach reusable practices; they must not invent product endpoints or entities.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
See `docs/maintainers/architecture.md` for source ownership and `docs/maintainers/dependencies.md` for profile promotion. This file is the workflow, not the design.
|
|
4
|
+
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
1. Fork and create a feature branch from `dev`.
|
|
8
|
+
2. `npm ci` — Node 22.14+ with npm 11.19+ required (tested on Node 24).
|
|
9
|
+
3. `npm test` must stay green. No global `prettier`/`eslint`/`typescript` needed — they are generated inside your project.
|
|
10
|
+
|
|
11
|
+
## Adding a stack — plan first, then declare, then build
|
|
12
|
+
|
|
13
|
+
A stack is **planned content first, then a declaration in `library/`, then executable code in `src/stacks/`**. `library/` never contains business entities — it declares *what* the stack supports; `src/stacks/<id>/create-files.js` implements *how* those files are generated. Do not start with code; start with the content model.
|
|
14
|
+
|
|
15
|
+
### 0. Plan your stack's content (before touching `library/`)
|
|
16
|
+
|
|
17
|
+
Answer these 5 questions and write them down (a short RFC or issue is enough). If you can't answer them, you can't write a `definition.json` yet.
|
|
18
|
+
|
|
19
|
+
**a. Identity & compatibility:** What `id` (`django`, `nuxt`), `kind` (`frontend`|`backend`|`data`), `label` (`Django (Python)`), and which existing stacks can it pair with? Example: `nextjs` pairs with `none,postgres,supabase,springboot,laravel`; `react-native` pairs with `none,supabase,springboot,laravel`; `laravel` pairs with `nextjs,react,react-native,no-frontend,laravel-ui`.
|
|
20
|
+
|
|
21
|
+
**b. Shapes:** Which **applicationShapes** does it enable? Shapes are the *deployment layout*, not the framework. They determine valid `frontend + backend` combos via `lib/application-shapes.js` → `src/engine/project-shapes.js`:
|
|
22
|
+
|
|
23
|
+
| Shape | Meaning | Example combos |
|
|
24
|
+
|-------|---------|---------------|
|
|
25
|
+
| `fullstack` | One project owns website + server | `nextjs+none`, `nextjs+postgres`, `laravel-ui+laravel` |
|
|
26
|
+
| `separate` | Two apps via API: frontend + backend API | `nextjs+springboot`, `react+supabase`, `react+laravel` |
|
|
27
|
+
| `api` | Backend API only, no generated website | `no-frontend+springboot`, `no-frontend+laravel` |
|
|
28
|
+
| `mobile` | Expo app + API/managed data | `react-native+supabase`, `react-native+springboot` |
|
|
29
|
+
| `frontend` | Browser-only, no generated server | `react+none` |
|
|
30
|
+
|
|
31
|
+
You don't invent a new shape — you pick from these 5. If `nextjs+django` should be fullstack, add `django` to `fullstack`'s `VALID_COMBINATIONS`. `inferApplicationShape({frontend,backend})` will then infer it; `validateApplicationShape` rejects invalid pairings.
|
|
32
|
+
|
|
33
|
+
**c. Architecture & auth:** Which `architectureProfiles` (`small,medium,large` — all 3 required for frontends/backends) and which `authenticationModels` (`public,undecided,supabase,session,oidc,laravel-session,sanctum-spa,laravel-oidc`)? Example: `supabase` → `supabase`, `springboot` website → `session`, `springboot` multi-client → `oidc`.
|
|
34
|
+
|
|
35
|
+
**d. Playbooks & concerns:** Which 5 facets does the stack need? Every stack needs `architecture.md, structure.md, runtime.md, security.md, testing.md` under `playbooks/stack/<id>/`. Which optional concerns (validation `zod`, state `zustand`, etc.) will it surface? Each concern has one home — don't duplicate prose in `AGENTS.md`.
|
|
36
|
+
|
|
37
|
+
**e. Dependencies & env:** Which npm/composer package *names* and *scripts* will this stack generate, and which env var *names* (semantic, no prefix)? Example: `deps: ["next","react"]`, `env: ["DATABASE_URL"]`, `clientEnv: ["API_URL"]` — the engine will prefix `API_URL` once (`NEXT_PUBLIC_API_URL`). Never put a version here.
|
|
38
|
+
|
|
39
|
+
If a new stack needs a runtime (`node`, `java`, `php`), add its version to `library/tested-versions.json` (current profile), not to the definition.
|
|
40
|
+
|
|
41
|
+
### 1. Declare capability in `library/` (no executable logic yet)
|
|
42
|
+
|
|
43
|
+
- Add `library/stacks/<id>/definition.json`:
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"id": "django",
|
|
48
|
+
"kind": "backend",
|
|
49
|
+
"label": "Django (Python)",
|
|
50
|
+
"appliesTo": { "frontend": ["nextjs","react","no-frontend"] },
|
|
51
|
+
"architectureProfiles": ["small","medium","large"],
|
|
52
|
+
"playbooks": ["stack/django/architecture.md","stack/django/structure.md","stack/django/runtime.md","stack/django/security.md","stack/django/testing.md"],
|
|
53
|
+
"deps": ["django"],
|
|
54
|
+
"env": ["DATABASE_URL"],
|
|
55
|
+
"clientEnv": [],
|
|
56
|
+
"concerns": [{ "id": "validation", "required": false, "when": "runtime validation needed", "sections": ["Zod for Runtime Validation"] }]
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
- `deps`/`devDeps` are **names only** — never versions or ranges. Exact versions live only in `library/tested-versions.json`.
|
|
61
|
+
- `env` are semantic names (`DATABASE_URL`); `clientEnv` subset gets the frontend prefix (`NEXT_PUBLIC_`, `VITE_`, `EXPO_PUBLIC_`).
|
|
62
|
+
|
|
63
|
+
- Add `playbooks/stack/<id>/{architecture,structure,runtime,security,testing}.md` — the five facets. Keep each file focused; route concerns via definition `concerns[]`, not duplication. Check `docs/maintainers/content-model.md` — every concern section must match a Markdown heading (numbered headings normalized).
|
|
64
|
+
|
|
65
|
+
- Run: `node checks/check-library.js` — catches duplicate ids, unknown dep names, `clientEnv` not in `env`, missing labels, heading mismatches.
|
|
66
|
+
|
|
67
|
+
### 2. Create stack directory (one place, owns everything specific to that stack)
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
src/stacks/<frontends|backends>/<id>/
|
|
71
|
+
index.js # defineStackAdapter({ id, kind, label, compatibleWith, capabilities, contributes })
|
|
72
|
+
create-files.js # (answers, context) -> FileMap — ALL files this stack generates (pure function)
|
|
73
|
+
dependencies.js # optional: { deps: [], devDeps: [], scripts: {} } — names/scripts only
|
|
74
|
+
environment.js # optional: ["API_URL","DATABASE_URL"] — semantic env names
|
|
75
|
+
auth/ # for Laravel-style stacks: session.js, sanctum.js, oidc.js, public.js
|
|
76
|
+
ui/ # for Laravel-style stacks: blade.js, livewire.js, inertia-react.js, shared.js
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Use `src/stacks/backends/laravel/` as the reference (13 files, 363-line `create-files.js` + `auth/` + `ui/` + `composer.js` + `architecture.js`). `src/stacks/frontends/nextjs/` is the minimal vertical.
|
|
80
|
+
|
|
81
|
+
`create-files.js` receives a read-only context from `src/stacks/available-stacks.js` + `src/engine/load-library.js` — it returns contributions, it never writes files or installs tools directly.
|
|
82
|
+
|
|
83
|
+
```js
|
|
84
|
+
// src/stacks/backends/django/index.js
|
|
85
|
+
import { defineStackAdapter } from '../../rules.js'
|
|
86
|
+
export const djangoAdapter = defineStackAdapter({
|
|
87
|
+
id: 'django', kind: 'backend', label: 'Django (Python)',
|
|
88
|
+
compatibleWith: { frontend: ['nextjs','react','no-frontend'] },
|
|
89
|
+
capabilities: { applicationShapes: ['fullstack','api'], architectureProfiles: ['small','medium','large'], authenticationModels: ['public','undecided','session'] },
|
|
90
|
+
contributes: {
|
|
91
|
+
environment: () => ['DATABASE_URL'],
|
|
92
|
+
install: () => [{ cwd: 'backend', command: 'pip', args: ['install','-r','requirements.txt'] }],
|
|
93
|
+
docker: () => [{ template: 'django', developmentPath: 'Dockerfile.dev' }],
|
|
94
|
+
ci: () => [{ template: 'django', path: '.github/workflows/ci-backend.yml' }],
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 3. Register once (explicit, no scanning)
|
|
100
|
+
|
|
101
|
+
`src/stacks/available-stacks.js` — add one import and one array entry:
|
|
102
|
+
|
|
103
|
+
```js
|
|
104
|
+
import { djangoAdapter } from './backends/django/index.js'
|
|
105
|
+
export const stackRegistry = createStackRegistry([..., djangoAdapter])
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
This is the **only** list of available adapters. Adding a file never silently activates a stack.
|
|
109
|
+
|
|
110
|
+
### 4. Add tests and matrix entries
|
|
111
|
+
|
|
112
|
+
- `tests/stacks/<id>/` — at least: files exist, env prefix, large-arch boundary, auth metadata.
|
|
113
|
+
- `checks/check-compatibility.js` — add `'<frontend>-<backend>'` to `cases[]` and to `smokeSelections[]`.
|
|
114
|
+
- `templates/` — add `docker/dockerfile/django.dev.dockerfile`, `templates/ci/django.yml` etc. as static templates.
|
|
115
|
+
|
|
116
|
+
### 5. Verify (focused, not full matrix every time)
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
npm test
|
|
120
|
+
node checks/check-library.js
|
|
121
|
+
node checks/check-compatibility.js --scope=stack --stack=<id> | head
|
|
122
|
+
npm run verify:generated -- --profile=$(jq -r .defaultProfile library/tested-versions.json) --case=<frontend>-<backend> --architecture=medium --authentication=yes
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
- `verify:generated` compares byte-identical output via `generateProject` vs legacy shim for your new stack.
|
|
126
|
+
- Run `npm run matrix:smoke` (10 smoke projects) before any `feature -> dev` PR.
|
|
127
|
+
- Full matrix `npm run matrix:full` (every profile x stack x arch x auth, with install/build/Maven/Expo/Compose checks) is only required on `dev -> main` promotion per `docs/maintainers/ci-strategy.md`.
|
|
128
|
+
|
|
129
|
+
### 6. Docs (only if ownership changed)
|
|
130
|
+
|
|
131
|
+
Update `docs/maintainers/architecture.md` only if source ownership or the generation pipeline changed — not for every stack. If you added concerns/playbooks, verify `docs/maintainers/content-model.md` checklist (concern has one home, `RULES.md` sections resolve).
|
|
132
|
+
|
|
133
|
+
## Testing and PRs
|
|
134
|
+
|
|
135
|
+
- Required checks per `docs/maintainers/ci-strategy.md`:
|
|
136
|
+
- `feature -> dev`: `quality` + `compatibility-gate` (repository tests + 10 smoke projects)
|
|
137
|
+
- `dev -> main`: `quality` + `compatibility-gate` (every profile x stack x arch x applicable auth)
|
|
138
|
+
|
|
139
|
+
- Contribution history: use merge commits for feature branches so history remains visible. Do not require individual matrix job names; require the stable `compatibility-gate` aggregator.
|
|
140
|
+
|
|
141
|
+
- `tests/architecture-boundaries.test.js` enforces `src/engine` not importing `cli`/`stacks/frontends|backends` and `src/stacks` not importing `cli`/`engine` (except `shared/scaffold` allowlist). `tests/architecture/no-lib-legacy.test.js` bans `src/** -> lib/**` imports and one-line wrapper regressions (no `lib/` exists).
|
|
142
|
+
|
|
143
|
+
## Version ownership
|
|
144
|
+
|
|
145
|
+
Exact versions belong only to `library/tested-versions.json`. Never add a version to a `definition.json` or a `create-files.js`. `packageVersion(profile, name, capability)` and `composerPackageVersion(profile, name)` are the only version sources; they reject ranges and unknown package requests. See `docs/maintainers/dependencies.md` for current/previous profile promotion and Renovate flow.
|
|
146
|
+
|
|
147
|
+
## Docs workflow
|
|
148
|
+
|
|
149
|
+
- `AGENTS.md` — tiny always-on contract; keep short.
|
|
150
|
+
- `RULES.md` — lazy index `concern -> playbook §`; generated per project, read only what you touch.
|
|
151
|
+
- `playbooks/` — reusable standards; add the five facets per stack (`architecture.md`, `structure.md`, `runtime.md`, `security.md`, `testing.md`).
|
|
152
|
+
- `docs/guides/` inside generated projects — architecture, API, setup, deployment for *this* product.
|
|
153
|
+
|
|
154
|
+
Do not advertise a capability solely because a playbook mentions it. A generated capability must have executable configuration and contract coverage. For questions, read `docs/maintainers/architecture.md` first, then this file.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Dependency maintenance
|
|
2
2
|
|
|
3
|
-
`
|
|
3
|
+
`library/tested-versions.json` is the only owner of versions emitted into generated applications. Stack and concern definitions declare package names and capabilities, never ranges or versions. Direct npm dependencies are generated as exact versions, and consumers commit the lockfile created by their first install.
|
|
4
4
|
|
|
5
5
|
## Profile policy
|
|
6
6
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Migrating from 1.x to 2.0
|
|
2
|
+
|
|
3
|
+
Version 2 never overwrites or automatically upgrades an existing project. Commit or back up the project first, generate a new version-2 project with equivalent stack choices, and compare it with the existing application.
|
|
4
|
+
|
|
5
|
+
1. Run `create-win-project upgrade-report .` when a profile exists; otherwise inventory runtimes, direct dependencies, authentication, CI, deployment, and operations manually.
|
|
6
|
+
2. Adopt `create-win-project.profile.json` schema 2 and record the stack, dated compatibility profile, production baseline, and capabilities.
|
|
7
|
+
3. Replace optional/no-test paths with the stack default: full web coverage (including Playwright) or Jest plus React Native Testing Library for Expo.
|
|
8
|
+
4. Install exact direct versions in a clean working tree and commit the package-manager lockfile. Review resolved transitive and peer changes.
|
|
9
|
+
5. Port hardened production artifacts and operations guidance. Keep development Docker optional.
|
|
10
|
+
6. Select uploads, queues, or mobile offline behavior only when required; do not infer them from 1.x advisory concerns.
|
|
11
|
+
7. Run lint, typecheck, tests, production builds/exports, Compose parsing, and relevant container/database/capability checks before replacing the old baseline.
|
|
12
|
+
|
|
13
|
+
Treat generated files as reference implementations during migration. Merge application-specific behavior deliberately and record approved architecture, provider, authentication, data, or major dependency deviations in `CONTEXT.md`.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Version 2 production contract
|
|
2
|
+
|
|
3
|
+
Version 2 generates a tested, stack-appropriate production baseline. It guarantees deterministic files for the recorded schema-v2 profile, exact tested direct dependency requests, standard tests and CI, production builds, security rules, operations guidance, and cloud-neutral Docker artifacts for deployable web stacks. Expo projects receive an EAS-ready baseline, not automatic store submission.
|
|
4
|
+
|
|
5
|
+
The guarantee is a starting contract, not a claim that an unfinished product is safe to launch. Teams still own domain authorization, infrastructure sizing, secrets, observability targets, data classification, compliance, external-provider configuration, device verification, deployment, backups, and restore drills.
|
|
6
|
+
|
|
7
|
+
## Dependency ownership
|
|
8
|
+
|
|
9
|
+
`library/tested-versions.json` owns exact direct npm and Composer versions for current and retained profiles. npm and Composer validate peer ranges, resolve transitive packages, and create lockfiles during installation. Generated projects own and commit those lockfiles; the generator does not freeze or silently upgrade their transitive graph.
|
|
10
|
+
|
|
11
|
+
## Standard baseline
|
|
12
|
+
|
|
13
|
+
- Tests, lint/type checks, production builds, CI, security rules, environment validation, and operations documentation are standard.
|
|
14
|
+
- Vite production uses non-root nginx with SPA fallback, security headers, safe cache policy, and API `no-store`; Next.js retains framework-native caching.
|
|
15
|
+
- Server/database stacks document readiness, graceful shutdown, pooling, migration preflight, encrypted backups, restore verification, retention, deployment, and rollback.
|
|
16
|
+
- Development Docker remains optional. Shared Redis caching, queues, object storage, offline synchronization, and malware scanning appear only for a supported explicit requirement.
|
|
17
|
+
|
|
18
|
+
## Conditional capabilities
|
|
19
|
+
|
|
20
|
+
Private uploads define authorization, size/signature checks, generated names, quarantine/scanning, cleanup, and rejection tests. Queues define bounded retry, idempotency, timeouts, failed-job handling, correlation, and replay. Mobile cache/sync defines ownership, key namespaces, TTL, invalidation, privacy, reconnect states, and conflict handling. Unsupported combinations fail before any destination is written.
|
|
21
|
+
|
|
22
|
+
## Support and recovery
|
|
23
|
+
|
|
24
|
+
The current and previous dated profiles are supported through their catalog dates. Run `create-win-project upgrade-report [path]` for a read-only comparison; it never modifies an existing project. Major deviations require approval and a decision record in generated `CONTEXT.md`.
|