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
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
# Styling: CSS Modules — Extensions
|
|
2
|
-
|
|
3
|
-
Extends your existing CSS Modules playbook with missing patterns.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Dark Mode with CSS Variables
|
|
8
|
-
```css
|
|
9
|
-
/* styles/tokens.css — single source of truth */
|
|
10
|
-
:root {
|
|
11
|
-
/* Colors */
|
|
12
|
-
--color-background: #ffffff;
|
|
13
|
-
--color-foreground: #0a0a0a;
|
|
14
|
-
--color-primary: #1a1a2e;
|
|
15
|
-
--color-primary-foreground: #f0f0f0;
|
|
16
|
-
--color-muted: #f5f5f5;
|
|
17
|
-
--color-muted-foreground: #737373;
|
|
18
|
-
--color-border: #e5e5e5;
|
|
19
|
-
--color-error: #dc2626;
|
|
20
|
-
--color-success: #16a34a;
|
|
21
|
-
|
|
22
|
-
/* Typography */
|
|
23
|
-
--font-size-sm: 0.875rem;
|
|
24
|
-
--font-size-base: 1rem;
|
|
25
|
-
--font-size-lg: 1.125rem;
|
|
26
|
-
--font-size-xl: 1.25rem;
|
|
27
|
-
--font-size-2xl: 1.5rem;
|
|
28
|
-
|
|
29
|
-
/* Spacing */
|
|
30
|
-
--space-1: 0.25rem;
|
|
31
|
-
--space-2: 0.5rem;
|
|
32
|
-
--space-3: 0.75rem;
|
|
33
|
-
--space-4: 1rem;
|
|
34
|
-
--space-6: 1.5rem;
|
|
35
|
-
--space-8: 2rem;
|
|
36
|
-
|
|
37
|
-
/* Radius */
|
|
38
|
-
--radius-sm: 0.25rem;
|
|
39
|
-
--radius-md: 0.375rem;
|
|
40
|
-
--radius-lg: 0.5rem;
|
|
41
|
-
|
|
42
|
-
/* Transitions */
|
|
43
|
-
--transition-fast: 100ms ease;
|
|
44
|
-
--transition-base: 200ms ease;
|
|
45
|
-
--transition-slow: 500ms ease;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
[data-theme="dark"] {
|
|
49
|
-
--color-background: #0a0a0a;
|
|
50
|
-
--color-foreground: #f0f0f0;
|
|
51
|
-
--color-primary: #e0e0f0;
|
|
52
|
-
--color-primary-foreground: #1a1a2e;
|
|
53
|
-
--color-muted: #1a1a1a;
|
|
54
|
-
--color-muted-foreground: #a3a3a3;
|
|
55
|
-
--color-border: #262626;
|
|
56
|
-
}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
// app/providers.tsx — apply theme to root
|
|
61
|
-
import { useEffect, useState } from 'react'
|
|
62
|
-
|
|
63
|
-
export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
|
64
|
-
const [theme, setTheme] = useState<'light' | 'dark'>('light')
|
|
65
|
-
|
|
66
|
-
useEffect(() => {
|
|
67
|
-
document.documentElement.setAttribute('data-theme', theme)
|
|
68
|
-
}, [theme])
|
|
69
|
-
|
|
70
|
-
return <>{children}</>
|
|
71
|
-
}
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
---
|
|
75
|
-
|
|
76
|
-
## Component Pattern with Tokens
|
|
77
|
-
```css
|
|
78
|
-
/* components/ui/Button/Button.module.css */
|
|
79
|
-
.button {
|
|
80
|
-
display: inline-flex;
|
|
81
|
-
align-items: center;
|
|
82
|
-
justify-content: center;
|
|
83
|
-
padding: var(--space-2) var(--space-4);
|
|
84
|
-
font-size: var(--font-size-base);
|
|
85
|
-
border-radius: var(--radius-md);
|
|
86
|
-
transition: background-color var(--transition-base);
|
|
87
|
-
cursor: pointer;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
.primary {
|
|
91
|
-
background-color: var(--color-primary);
|
|
92
|
-
color: var(--color-primary-foreground);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
.primary:hover {
|
|
96
|
-
opacity: 0.9;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
.ghost {
|
|
100
|
-
background-color: transparent;
|
|
101
|
-
color: var(--color-foreground);
|
|
102
|
-
border: 1px solid var(--color-border);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.ghost:hover {
|
|
106
|
-
background-color: var(--color-muted);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
.disabled {
|
|
110
|
-
opacity: 0.5;
|
|
111
|
-
cursor: not-allowed;
|
|
112
|
-
pointer-events: none;
|
|
113
|
-
}
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
---
|
|
117
|
-
|
|
118
|
-
## clsx for Class Composition
|
|
119
|
-
```typescript
|
|
120
|
-
// Install: npm install clsx
|
|
121
|
-
import clsx from 'clsx'
|
|
122
|
-
import styles from './Button.module.css'
|
|
123
|
-
|
|
124
|
-
export function Button({ variant = 'primary', disabled, className }: ButtonProps) {
|
|
125
|
-
return (
|
|
126
|
-
<button
|
|
127
|
-
className={clsx(
|
|
128
|
-
styles.button,
|
|
129
|
-
styles[variant],
|
|
130
|
-
disabled && styles.disabled,
|
|
131
|
-
className // allow external class override
|
|
132
|
-
)}
|
|
133
|
-
disabled={disabled}
|
|
134
|
-
>
|
|
135
|
-
{children}
|
|
136
|
-
</button>
|
|
137
|
-
)
|
|
138
|
-
}
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
---
|
|
142
|
-
|
|
143
|
-
## Responsive in Module File
|
|
144
|
-
```css
|
|
145
|
-
/* UserCard.module.css */
|
|
146
|
-
.card {
|
|
147
|
-
display: flex;
|
|
148
|
-
flex-direction: column;
|
|
149
|
-
padding: var(--space-4);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/* Responsive stays in the component's own module file */
|
|
153
|
-
@media (min-width: 768px) {
|
|
154
|
-
.card {
|
|
155
|
-
flex-direction: row;
|
|
156
|
-
padding: var(--space-6);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
@media (min-width: 1024px) {
|
|
161
|
-
.card {
|
|
162
|
-
max-width: 800px;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
---
|
|
168
|
-
|
|
169
|
-
## Animation
|
|
170
|
-
```css
|
|
171
|
-
/* Define @keyframes in component module if component-specific */
|
|
172
|
-
/* Define in global.css if reused across components */
|
|
173
|
-
|
|
174
|
-
/* Component-specific */
|
|
175
|
-
@keyframes fadeIn {
|
|
176
|
-
from { opacity: 0; transform: translateY(-8px); }
|
|
177
|
-
to { opacity: 1; transform: translateY(0); }
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
.dropdown {
|
|
181
|
-
animation: fadeIn var(--transition-base);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/* Reused animation → globals.css */
|
|
185
|
-
@keyframes spin {
|
|
186
|
-
to { transform: rotate(360deg); }
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
---
|
|
191
|
-
|
|
192
|
-
## Never Mix Tailwind + CSS Modules on Same Element
|
|
193
|
-
```typescript
|
|
194
|
-
// ❌ mixing both on same element
|
|
195
|
-
<div className={clsx(styles.card, 'flex items-center')} />
|
|
196
|
-
|
|
197
|
-
// ✅ pick one strategy per project (defined at init)
|
|
198
|
-
// CSS Modules project → all styling via modules
|
|
199
|
-
<div className={styles.card} />
|
|
200
|
-
|
|
201
|
-
// Tailwind project → all styling via Tailwind
|
|
202
|
-
<div className="flex items-center gap-4 rounded-md" />
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
---
|
|
206
|
-
|
|
207
|
-
## Global Styles Structure
|
|
208
|
-
```
|
|
209
|
-
src/styles/
|
|
210
|
-
tokens.css → CSS variables (colors, space, type, radius)
|
|
211
|
-
globals.css → reset, base elements, @import tokens
|
|
212
|
-
animations.css → reusable @keyframes (optional)
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
```css
|
|
216
|
-
/* globals.css */
|
|
217
|
-
@import './tokens.css';
|
|
218
|
-
|
|
219
|
-
*, *::before, *::after {
|
|
220
|
-
box-sizing: border-box;
|
|
221
|
-
margin: 0;
|
|
222
|
-
padding: 0;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
body {
|
|
226
|
-
background-color: var(--color-background);
|
|
227
|
-
color: var(--color-foreground);
|
|
228
|
-
font-size: var(--font-size-base);
|
|
229
|
-
line-height: 1.5;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
a {
|
|
233
|
-
color: inherit;
|
|
234
|
-
text-decoration: none;
|
|
235
|
-
}
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
---
|
|
239
|
-
|
|
240
|
-
## Agent Quick Reference (Extended)
|
|
241
|
-
```
|
|
242
|
-
Dark mode?
|
|
243
|
-
→ [data-theme="dark"] on html element
|
|
244
|
-
→ CSS variables in tokens.css, overrides in [data-theme="dark"]
|
|
245
|
-
→ Toggle via data-theme attribute, not class swap
|
|
246
|
-
|
|
247
|
-
Conditional classes?
|
|
248
|
-
→ clsx(styles.base, condition && styles.variant)
|
|
249
|
-
→ Never string template literals
|
|
250
|
-
|
|
251
|
-
Responsive?
|
|
252
|
-
→ @media queries in component's own .module.css
|
|
253
|
-
→ Mobile styles first (no query), then @media (min-width: ...)
|
|
254
|
-
|
|
255
|
-
Animation?
|
|
256
|
-
→ Component-specific: @keyframes in component module
|
|
257
|
-
→ Reused: @keyframes in globals.css or animations.css
|
|
258
|
-
→ Duration: always use --transition-* tokens
|
|
259
|
-
|
|
260
|
-
New token needed?
|
|
261
|
-
→ Add to tokens.css under correct section
|
|
262
|
-
→ Never hardcode values in component modules
|
|
263
|
-
|
|
264
|
-
External class override allowed?
|
|
265
|
-
→ Accept className prop, pass to clsx as last arg
|
|
266
|
-
→ Allows parent to extend without modifying component
|
|
267
|
-
```
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "css-modules",
|
|
3
|
-
"kind": "styling",
|
|
4
|
-
"label": "CSS Modules",
|
|
5
|
-
"file": "styling/css-modules-extensions.md",
|
|
6
|
-
"required": false,
|
|
7
|
-
"folders": [],
|
|
8
|
-
"concerns": [
|
|
9
|
-
{ "id": "styling", "required": true, "sections": ["Dark Mode with CSS Variables", "Responsive in Module File"] }
|
|
10
|
-
]
|
|
11
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "coding-rules",
|
|
3
|
-
"kind": "universal",
|
|
4
|
-
"label": "Coding Rules",
|
|
5
|
-
"required": true,
|
|
6
|
-
"folders": [],
|
|
7
|
-
"devDeps": ["prettier"],
|
|
8
|
-
"concerns": [
|
|
9
|
-
{ "id": "naming", "required": true, "sections": ["Naming", "Functions", "Imports", "Constants"] },
|
|
10
|
-
{ "id": "no-debug", "required": true, "sections": ["No Debug Code in Commits", "One Thing Per File"] }
|
|
11
|
-
]
|
|
12
|
-
}
|
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
# Coding Rules (Universal)
|
|
2
|
-
|
|
3
|
-
Applies to every project regardless of stack.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Core Principle
|
|
8
|
-
```
|
|
9
|
-
simple + explicit + consistent
|
|
10
|
-
over
|
|
11
|
-
complex + abstract + theoretically pure
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
Complexity must earn abstraction. Start simple. Add layers only when justified.
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
## Naming
|
|
19
|
-
|
|
20
|
-
### Files
|
|
21
|
-
```
|
|
22
|
-
React components: PascalCase UserCard.tsx
|
|
23
|
-
Hooks: camelCase useUserData.ts
|
|
24
|
-
Utilities: camelCase formatDate.ts
|
|
25
|
-
Constants: camelCase apiEndpoints.ts
|
|
26
|
-
Types: camelCase userTypes.ts
|
|
27
|
-
CSS Modules: PascalCase UserCard.module.css
|
|
28
|
-
Java classes: PascalCase UserService.java
|
|
29
|
-
SQL migrations: snake_case V1__create_users_table.sql
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### Variables and Functions
|
|
33
|
-
```
|
|
34
|
-
Variables: camelCase userName, isLoading, hasError
|
|
35
|
-
Functions: camelCase getUser(), createOrder(), formatDate()
|
|
36
|
-
Constants: SCREAMING MAX_RETRIES, API_BASE_URL
|
|
37
|
-
React components: PascalCase UserCard, LoginForm
|
|
38
|
-
Types/Interfaces: PascalCase UserResponse, ApiError
|
|
39
|
-
Enums: PascalCase UserRole, OrderStatus
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### Name for what it does, not what it is
|
|
43
|
-
```
|
|
44
|
-
❌ getData(), handleThing(), doStuff(), temp, x
|
|
45
|
-
✅ getUserById(), handleLoginSubmit(), formatCurrency()
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### Boolean naming
|
|
49
|
-
```
|
|
50
|
-
❌ user, loading, error
|
|
51
|
-
✅ isLoading, hasError, isAuthenticated, canEdit
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
---
|
|
55
|
-
|
|
56
|
-
## Functions
|
|
57
|
-
- One responsibility per function
|
|
58
|
-
- Max 3 parameters — if more, use an options object
|
|
59
|
-
- Return early to avoid deep nesting
|
|
60
|
-
|
|
61
|
-
```typescript
|
|
62
|
-
// ❌
|
|
63
|
-
function processUser(user, role, permissions, sendEmail, notify) { ... }
|
|
64
|
-
|
|
65
|
-
// ✅
|
|
66
|
-
function processUser(user: User, options: ProcessUserOptions) { ... }
|
|
67
|
-
|
|
68
|
-
// ❌ deep nesting
|
|
69
|
-
function getUser(id) {
|
|
70
|
-
if (id) {
|
|
71
|
-
if (isValid(id)) {
|
|
72
|
-
// logic
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// ✅ early return
|
|
78
|
-
function getUser(id) {
|
|
79
|
-
if (!id) return null
|
|
80
|
-
if (!isValid(id)) return null
|
|
81
|
-
// logic
|
|
82
|
-
}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
---
|
|
86
|
-
|
|
87
|
-
## Imports
|
|
88
|
-
|
|
89
|
-
### Frontend
|
|
90
|
-
- Always use absolute imports with `@/` prefix
|
|
91
|
-
- Never use relative `../../` imports
|
|
92
|
-
- Barrel exports (`index.ts`) for public API of a feature only
|
|
93
|
-
|
|
94
|
-
```typescript
|
|
95
|
-
// ❌
|
|
96
|
-
import { UserCard } from '../../../components/ui/UserCard'
|
|
97
|
-
|
|
98
|
-
// ✅
|
|
99
|
-
import { UserCard } from '@/components/ui/UserCard'
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### Import Order (enforced by ESLint)
|
|
103
|
-
```
|
|
104
|
-
1. External libraries
|
|
105
|
-
2. Internal absolute (@/)
|
|
106
|
-
3. Types
|
|
107
|
-
4. Styles / assets
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
---
|
|
111
|
-
|
|
112
|
-
## Constants
|
|
113
|
-
- No magic numbers or strings in logic
|
|
114
|
-
- All constants in `src/constants/index.ts` or feature-level constants file
|
|
115
|
-
|
|
116
|
-
```typescript
|
|
117
|
-
// ❌
|
|
118
|
-
if (role === 'ADMIN') { ... }
|
|
119
|
-
setTimeout(fn, 900000)
|
|
120
|
-
|
|
121
|
-
// ✅
|
|
122
|
-
import { ROLES, TOKEN_EXPIRY } from '@/constants'
|
|
123
|
-
if (role === ROLES.ADMIN) { ... }
|
|
124
|
-
setTimeout(fn, TOKEN_EXPIRY.ACCESS)
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
---
|
|
128
|
-
|
|
129
|
-
## Async / Error Handling
|
|
130
|
-
|
|
131
|
-
### Frontend
|
|
132
|
-
- Always async/await — never `.then()` chains
|
|
133
|
-
- Always handle errors at the hook level, not component level
|
|
134
|
-
- Never swallow errors silently
|
|
135
|
-
|
|
136
|
-
```typescript
|
|
137
|
-
// ❌
|
|
138
|
-
fetchUser().then(data => setUser(data)).catch(e => console.log(e))
|
|
139
|
-
|
|
140
|
-
// ✅
|
|
141
|
-
try {
|
|
142
|
-
const user = await fetchUser()
|
|
143
|
-
setUser(user)
|
|
144
|
-
} catch (error) {
|
|
145
|
-
logger.error('fetchUser failed:', error)
|
|
146
|
-
throw error
|
|
147
|
-
}
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### Backend
|
|
151
|
-
- Always throw `AppException` — never raw `RuntimeException`
|
|
152
|
-
- Never expose stack traces in API responses
|
|
153
|
-
- Always catch at the `GlobalExceptionHandler` level
|
|
154
|
-
|
|
155
|
-
```java
|
|
156
|
-
// ❌
|
|
157
|
-
throw new RuntimeException("User not found");
|
|
158
|
-
|
|
159
|
-
// ✅
|
|
160
|
-
throw new AppException("USER_NOT_FOUND", HttpStatus.NOT_FOUND);
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
---
|
|
164
|
-
|
|
165
|
-
## Logging
|
|
166
|
-
- NEVER use `console.log` directly
|
|
167
|
-
- Always use `lib/logger.ts` on frontend
|
|
168
|
-
- Always use SLF4J logger on backend
|
|
169
|
-
|
|
170
|
-
```typescript
|
|
171
|
-
// ❌
|
|
172
|
-
console.log('user:', user)
|
|
173
|
-
console.error('error:', error)
|
|
174
|
-
|
|
175
|
-
// ✅
|
|
176
|
-
import { logger } from '@/lib/logger'
|
|
177
|
-
logger.info('user fetched:', user)
|
|
178
|
-
logger.error('fetch failed:', error)
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
```java
|
|
182
|
-
// ❌
|
|
183
|
-
System.out.println("user: " + user);
|
|
184
|
-
|
|
185
|
-
// ✅
|
|
186
|
-
private static final Logger log = LoggerFactory.getLogger(UserService.class);
|
|
187
|
-
log.info("user fetched: {}", userId);
|
|
188
|
-
log.error("fetch failed for userId: {}", userId, e);
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
---
|
|
192
|
-
|
|
193
|
-
## Comments
|
|
194
|
-
- Comment WHY, not WHAT
|
|
195
|
-
- Code should be readable enough to not need WHAT comments
|
|
196
|
-
- Remove all debug/TODO comments before committing
|
|
197
|
-
|
|
198
|
-
```typescript
|
|
199
|
-
// ❌ explains what (obvious from code)
|
|
200
|
-
// increment counter
|
|
201
|
-
count++
|
|
202
|
-
|
|
203
|
-
// ✅ explains why (not obvious from code)
|
|
204
|
-
// Retry once — server returns 503 on cold start for ~200ms
|
|
205
|
-
await retry(fetchUser, { times: 1, delay: 300 })
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
---
|
|
209
|
-
|
|
210
|
-
## No Debug Code in Commits
|
|
211
|
-
```
|
|
212
|
-
❌ console.log
|
|
213
|
-
❌ debugger
|
|
214
|
-
❌ TODO comments
|
|
215
|
-
❌ hardcoded test values
|
|
216
|
-
❌ commented-out code blocks
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
ESLint and Husky enforce this — build fails if present.
|
|
220
|
-
|
|
221
|
-
---
|
|
222
|
-
|
|
223
|
-
## One Thing Per File
|
|
224
|
-
```
|
|
225
|
-
❌ UserCardAndForm.tsx — two components in one file
|
|
226
|
-
❌ userUtils.ts — 30 unrelated utility functions
|
|
227
|
-
|
|
228
|
-
✅ UserCard.tsx
|
|
229
|
-
✅ UserForm.tsx
|
|
230
|
-
✅ formatDate.ts
|
|
231
|
-
✅ formatCurrency.ts
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
Exception: small helper types or constants directly related to the file.
|
|
235
|
-
|
|
236
|
-
---
|
|
237
|
-
|
|
238
|
-
## Exports
|
|
239
|
-
|
|
240
|
-
### Frontend
|
|
241
|
-
- Named exports everywhere except page/route components
|
|
242
|
-
- Page components use default export (Next.js / React Router requirement)
|
|
243
|
-
|
|
244
|
-
```typescript
|
|
245
|
-
// ❌ default export for reusable components
|
|
246
|
-
export default function UserCard() { ... }
|
|
247
|
-
|
|
248
|
-
// ✅ named export
|
|
249
|
-
export function UserCard() { ... }
|
|
250
|
-
|
|
251
|
-
// ✅ default export for pages only
|
|
252
|
-
export default function UserPage() { ... }
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
### Backend
|
|
256
|
-
- Spring-managed beans: `@Service`, `@Repository`, `@RestController` — Spring handles export
|
|
257
|
-
- Utility classes: `public static` methods
|
|
258
|
-
|
|
259
|
-
---
|
|
260
|
-
|
|
261
|
-
## Agent Rules
|
|
262
|
-
```
|
|
263
|
-
Before writing any code:
|
|
264
|
-
1. Check if the functionality already exists
|
|
265
|
-
2. Check which layer owns this responsibility
|
|
266
|
-
3. Choose the simplest correct implementation
|
|
267
|
-
4. Follow existing patterns in the codebase — don't introduce new ones
|
|
268
|
-
|
|
269
|
-
Before creating a new file:
|
|
270
|
-
1. Check if an existing file should be extended instead
|
|
271
|
-
2. Follow the selected stack's structure playbook and current feature ownership
|
|
272
|
-
|
|
273
|
-
Before adding a dependency:
|
|
274
|
-
1. Check if existing tools already solve it
|
|
275
|
-
2. Prefer what the playbook recommends over personal preference
|
|
276
|
-
|
|
277
|
-
Naming:
|
|
278
|
-
1. Name things for what they do
|
|
279
|
-
2. Booleans start with is/has/can
|
|
280
|
-
3. No abbreviations unless universally understood (id, url, dto)
|
|
281
|
-
```
|