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.
Files changed (289) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +58 -160
  3. package/checks/check-compatibility.js +95 -0
  4. package/{scripts/verify-generated.mjs → checks/check-generated-project.js} +28 -4
  5. package/{scripts/validate-content.mjs → checks/check-library.js} +17 -7
  6. package/checks/check-package.js +15 -0
  7. package/checks/classify-changes.js +29 -0
  8. package/checks/run-compatibility-shard.js +21 -0
  9. package/docs/README.md +20 -0
  10. package/docs/capabilities.md +13 -0
  11. package/docs/compatibility.md +13 -0
  12. package/docs/generated-project.md +12 -0
  13. package/docs/getting-started.md +26 -0
  14. package/docs/maintainers/architecture.md +161 -0
  15. package/docs/maintainers/ci-strategy.md +46 -0
  16. package/docs/{CONTENT_MODEL.md → maintainers/content-model.md} +3 -3
  17. package/docs/maintainers/contributing.md +154 -0
  18. package/docs/{DEPENDENCY_MAINTENANCE.md → maintainers/dependencies.md} +1 -1
  19. package/docs/migration-v2.md +13 -0
  20. package/docs/production-contract.md +24 -0
  21. package/index.js +2 -429
  22. package/{playbooks → library}/INDEX.md +5 -5
  23. package/library/compatibility-impact.json +14 -0
  24. package/{playbooks/capabilities/ci/github-actions.manifest.json → library/development-tools/ci/definition.json} +1 -0
  25. package/library/development-tools/devops/makefile/commands.md +11 -0
  26. package/library/development-tools/devops/makefile/definition.json +11 -0
  27. package/library/development-tools/devops/makefile/docker.md +9 -0
  28. package/library/development-tools/devops/makefile/validation.md +5 -0
  29. package/{playbooks/devops/pr-template.manifest.json → library/development-tools/devops/pr-template/definition.json} +1 -0
  30. package/library/features/sqlalchemy-alembic.md +17 -0
  31. package/library/optional-features/concerns/zod/errors.md +5 -0
  32. package/library/optional-features/concerns/zod/testing.md +5 -0
  33. package/library/optional-features/concerns/zod/validation.md +21 -0
  34. package/library/optional-features/styling/css-modules/definition.json +12 -0
  35. package/library/optional-features/styling/css-modules/responsive.md +5 -0
  36. package/library/optional-features/styling/css-modules/theme.md +7 -0
  37. package/{playbooks/platform/mobile.manifest.json → library/platforms/mobile/definition.json} +1 -0
  38. package/{playbooks/platform/web.manifest.json → library/platforms/web/definition.json} +1 -0
  39. package/{playbooks/stack/react-native.manifest.json → library/stacks/expo/definition.json} +2 -2
  40. package/library/stacks/fastapi/architecture.md +40 -0
  41. package/library/stacks/fastapi/definition.json +39 -0
  42. package/library/stacks/fastapi/runtime.md +25 -0
  43. package/library/stacks/fastapi/security.md +26 -0
  44. package/library/stacks/fastapi/structure.md +27 -0
  45. package/library/stacks/fastapi/testing.md +23 -0
  46. package/{playbooks/stack/nextjs.manifest.json → library/stacks/nextjs/definition.json} +2 -2
  47. package/{playbooks/stack/no-frontend.manifest.json → library/stacks/no-frontend/definition.json} +1 -1
  48. package/{playbooks/stack/react-vite.manifest.json → library/stacks/react-vite/definition.json} +2 -2
  49. package/{compatibility/profiles.json → library/tested-versions.json} +46 -2
  50. package/{playbooks/universal/accessibility.manifest.json → library/universal/accessibility/definition.json} +1 -1
  51. package/library/universal/coding-rules/definition.json +13 -0
  52. package/library/universal/coding-rules/hygiene.md +9 -0
  53. package/library/universal/coding-rules/naming.md +17 -0
  54. package/{playbooks/universal/error-handling.manifest.json → library/universal/error-handling/definition.json} +1 -0
  55. package/library/universal/git-conventions/branches.md +5 -0
  56. package/library/universal/git-conventions/commits.md +7 -0
  57. package/library/universal/git-conventions/definition.json +13 -0
  58. package/library/universal/git-conventions/workflow.md +5 -0
  59. package/{playbooks/universal/observability.manifest.json → library/universal/observability/definition.json} +1 -0
  60. package/{playbooks/universal/security.manifest.json → library/universal/security/definition.json} +1 -0
  61. package/library/universal/typescript/boundaries.md +13 -0
  62. package/library/universal/typescript/definition.json +12 -0
  63. package/library/universal/typescript/errors.md +5 -0
  64. package/library/universal/typescript/patterns.md +7 -0
  65. package/package.json +14 -15
  66. package/public/logo.svg +19 -0
  67. package/src/cli/arguments.js +63 -0
  68. package/src/cli/display.js +220 -0
  69. package/src/cli/main.js +203 -0
  70. package/src/cli/navigation.js +156 -0
  71. package/src/cli/questions.js +188 -0
  72. package/src/cli/system-check.js +158 -0
  73. package/src/engine/create-project.js +10 -0
  74. package/src/engine/install-dependencies.js +13 -0
  75. package/{lib/catalog.js → src/engine/load-library.js} +8 -8
  76. package/{lib/files.js → src/engine/project-files.js} +10 -1
  77. package/{lib/playbooks.js → src/engine/project-guidance.js} +26 -3
  78. package/{lib/application-shapes.js → src/engine/project-shapes.js} +4 -4
  79. package/{lib/template.js → src/engine/render-templates.js} +11 -0
  80. package/{lib/compatibility.js → src/engine/tested-versions.js} +21 -2
  81. package/src/engine/upgrade-report.js +20 -0
  82. package/src/engine/write-files.js +34 -0
  83. package/{lib/stacks/registry.js → src/stacks/available-stacks.js} +25 -1
  84. package/src/stacks/backends/README.md +5 -0
  85. package/src/stacks/backends/fastapi/ci.js +3 -0
  86. package/src/stacks/backends/fastapi/create-files.js +874 -0
  87. package/src/stacks/backends/fastapi/docker.js +75 -0
  88. package/src/stacks/backends/fastapi/environment.js +3 -0
  89. package/src/stacks/backends/fastapi/index.js +32 -0
  90. package/{lib/stacks → src/stacks/backends}/laravel/architecture.js +1 -0
  91. package/{lib/stacks → src/stacks/backends}/laravel/auth/oidc.js +1 -0
  92. package/{lib/stacks → src/stacks/backends}/laravel/auth/public.js +1 -0
  93. package/{lib/stacks → src/stacks/backends}/laravel/auth/sanctum.js +1 -0
  94. package/{lib/stacks → src/stacks/backends}/laravel/auth/session.js +1 -0
  95. package/src/stacks/backends/laravel/ci.js +3 -0
  96. package/{lib/stacks → src/stacks/backends}/laravel/composer.js +1 -1
  97. package/{lib/stacks/laravel/generate.js → src/stacks/backends/laravel/create-files.js} +1 -0
  98. package/src/stacks/backends/laravel/docker.js +14 -0
  99. package/src/stacks/backends/laravel/environment.js +5 -0
  100. package/{lib/stacks → src/stacks/backends}/laravel/index.js +11 -3
  101. package/{lib/stacks → src/stacks/backends}/laravel/ui/blade.js +1 -0
  102. package/{lib/stacks → src/stacks/backends}/laravel/ui/index.js +1 -0
  103. package/{lib/stacks → src/stacks/backends}/laravel/ui/inertia-react.js +4 -2
  104. package/{lib/stacks → src/stacks/backends}/laravel/ui/livewire.js +1 -0
  105. package/{lib/stacks → src/stacks/backends}/laravel/ui/shared.js +1 -0
  106. package/src/stacks/backends/none/index.js +23 -0
  107. package/src/stacks/backends/postgres/ci.js +3 -0
  108. package/src/stacks/backends/postgres/create-files.js +21 -0
  109. package/src/stacks/backends/postgres/docker.js +3 -0
  110. package/src/stacks/backends/postgres/environment.js +3 -0
  111. package/src/stacks/backends/postgres/index.js +30 -0
  112. package/src/stacks/backends/springboot/ci.js +3 -0
  113. package/src/stacks/backends/springboot/create-files.js +91 -0
  114. package/src/stacks/backends/springboot/docker.js +3 -0
  115. package/src/stacks/backends/springboot/environment.js +3 -0
  116. package/src/stacks/backends/springboot/index.js +31 -0
  117. package/src/stacks/backends/supabase/ci.js +3 -0
  118. package/src/stacks/backends/supabase/create-files.js +52 -0
  119. package/src/stacks/backends/supabase/docker.js +3 -0
  120. package/src/stacks/backends/supabase/environment.js +3 -0
  121. package/src/stacks/backends/supabase/index.js +31 -0
  122. package/src/stacks/backends/supabase/native.js +14 -0
  123. package/src/stacks/compose-files.js +259 -0
  124. package/{lib/generator.js → src/stacks/create-project.js} +206 -57
  125. package/src/stacks/frontends/README.md +4 -0
  126. package/src/stacks/frontends/nextjs/ci.js +3 -0
  127. package/src/stacks/frontends/nextjs/create-files.js +46 -0
  128. package/src/stacks/frontends/nextjs/dependencies.js +5 -0
  129. package/src/stacks/frontends/nextjs/docker.js +3 -0
  130. package/src/stacks/frontends/nextjs/environment.js +7 -0
  131. package/src/stacks/frontends/nextjs/index.js +35 -0
  132. package/src/stacks/frontends/react-native/ci.js +3 -0
  133. package/src/stacks/frontends/react-native/create-files.js +28 -0
  134. package/src/stacks/frontends/react-native/dependencies.js +5 -0
  135. package/src/stacks/frontends/react-native/docker.js +5 -0
  136. package/src/stacks/frontends/react-native/environment.js +7 -0
  137. package/src/stacks/frontends/react-native/index.js +30 -0
  138. package/src/stacks/frontends/react-vite/ci.js +3 -0
  139. package/src/stacks/frontends/react-vite/create-files.js +27 -0
  140. package/src/stacks/frontends/react-vite/dependencies.js +5 -0
  141. package/src/stacks/frontends/react-vite/docker.js +3 -0
  142. package/src/stacks/frontends/react-vite/environment.js +8 -0
  143. package/src/stacks/frontends/react-vite/index.js +32 -0
  144. package/src/stacks/shared/capability-packs.js +31 -0
  145. package/{lib → src}/stacks/shared/contributions.js +1 -1
  146. package/src/stacks/shared/environment.js +38 -0
  147. package/src/stacks/shared/javascript-package.js +117 -0
  148. package/src/stacks/shared/testing-files.js +16 -0
  149. package/templates/ci/fastapi.yml +62 -0
  150. package/templates/docker/compose/postgres.yml +1 -1
  151. package/templates/docker/compose/springboot.yml +3 -3
  152. package/templates/docker/compose/supabase.yml +1 -1
  153. package/templates/docker/compose-prod/fastapi.yml +52 -0
  154. package/templates/docker/compose-prod/springboot.yml +20 -2
  155. package/templates/docker/dockerfile/fastapi.dev.dockerfile +9 -0
  156. package/templates/docker/dockerfile/fastapi.prod.dockerfile +11 -0
  157. package/templates/docker/dockerfile/nextjs.prod.dockerfile +1 -0
  158. package/templates/docker/dockerfile/springboot.prod.dockerfile +4 -1
  159. package/templates/docker/dockerfile/vite.prod.dockerfile +2 -1
  160. package/templates/makefile/fastapi.mk +97 -0
  161. package/docs/ARCHITECTURE.md +0 -118
  162. package/lib/banner.js +0 -45
  163. package/lib/constants.js +0 -3
  164. package/lib/doctor.js +0 -45
  165. package/lib/interview.js +0 -77
  166. package/lib/laravel-scaffold.js +0 -3
  167. package/lib/scaffold.js +0 -467
  168. package/lib/stacks/index.js +0 -8
  169. package/playbooks/concerns/zod.md +0 -174
  170. package/playbooks/devops/makefile.manifest.json +0 -10
  171. package/playbooks/devops/makefile.md +0 -556
  172. package/playbooks/styling/css-modules-extensions.md +0 -267
  173. package/playbooks/styling/css-modules.manifest.json +0 -11
  174. package/playbooks/universal/coding-rules.manifest.json +0 -12
  175. package/playbooks/universal/coding-rules.md +0 -281
  176. package/playbooks/universal/git-conventions.manifest.json +0 -10
  177. package/playbooks/universal/git-conventions.md +0 -186
  178. package/playbooks/universal/typescript.manifest.json +0 -11
  179. package/playbooks/universal/typescript.md +0 -272
  180. package/scripts/compatibility-matrix.mjs +0 -48
  181. /package/{playbooks/capabilities → library/development-tools}/ci/github-actions.md +0 -0
  182. /package/{playbooks/devops → library/development-tools/devops/pr-template}/pr-template.md +0 -0
  183. /package/{playbooks/capabilities/docker/docker.manifest.json → library/development-tools/docker/definition.json} +0 -0
  184. /package/{playbooks/capabilities → library/development-tools}/docker/overview.md +0 -0
  185. /package/{playbooks/capabilities → library/features}/auth/oidc-resource-server.md +0 -0
  186. /package/{playbooks/capabilities → library/features}/auth/spring-session.md +0 -0
  187. /package/{playbooks/capabilities/flyway/flyway.manifest.json → library/features/flyway/definition.json} +0 -0
  188. /package/{playbooks/capabilities → library/features}/flyway/environments.md +0 -0
  189. /package/{playbooks/capabilities → library/features}/flyway/migrations.md +0 -0
  190. /package/{playbooks/capabilities → library/features}/flyway/testing.md +0 -0
  191. /package/{playbooks/capabilities → library/features}/laravel/database.md +0 -0
  192. /package/{playbooks/capabilities → library/features}/laravel/migrations.md +0 -0
  193. /package/{playbooks/capabilities → library/features}/laravel/observability.md +0 -0
  194. /package/{playbooks/capabilities → library/features}/laravel/oidc-resource-server.md +0 -0
  195. /package/{playbooks/capabilities → library/features}/laravel/queues.md +0 -0
  196. /package/{playbooks/capabilities → library/features}/laravel/sanctum-spa.md +0 -0
  197. /package/{playbooks/capabilities → library/features}/laravel/scheduler.md +0 -0
  198. /package/{playbooks/capabilities → library/features}/laravel/session-auth.md +0 -0
  199. /package/{playbooks/capabilities → library/features}/laravel/storage-uploads.md +0 -0
  200. /package/{playbooks/capabilities → library/features}/postgresql/architecture.md +0 -0
  201. /package/{playbooks/capabilities/postgresql/postgresql.manifest.json → library/features/postgresql/definition.json} +0 -0
  202. /package/{playbooks/capabilities → library/features}/postgresql/migrations.md +0 -0
  203. /package/{playbooks/capabilities → library/features}/postgresql/schema-design.md +0 -0
  204. /package/{playbooks/capabilities → library/features}/postgresql/security.md +0 -0
  205. /package/{playbooks/capabilities → library/features}/postgresql/testing.md +0 -0
  206. /package/{playbooks/capabilities → library/features}/prisma/architecture.md +0 -0
  207. /package/{playbooks/capabilities/prisma/prisma.manifest.json → library/features/prisma/definition.json} +0 -0
  208. /package/{playbooks/capabilities → library/features}/prisma/migrations.md +0 -0
  209. /package/{playbooks/capabilities → library/features}/prisma/runtime.md +0 -0
  210. /package/{playbooks/capabilities → library/features}/prisma/schema.md +0 -0
  211. /package/{playbooks/capabilities → library/features}/prisma/testing.md +0 -0
  212. /package/{playbooks/capabilities → library/features}/supabase/architecture.md +0 -0
  213. /package/{playbooks/capabilities → library/features}/supabase/authentication.md +0 -0
  214. /package/{playbooks/capabilities/supabase/supabase.manifest.json → library/features/supabase/definition.json} +0 -0
  215. /package/{playbooks/capabilities → library/features}/supabase/expo.md +0 -0
  216. /package/{playbooks/capabilities → library/features}/supabase/migrations.md +0 -0
  217. /package/{playbooks/capabilities → library/features}/supabase/nextjs.md +0 -0
  218. /package/{playbooks/capabilities → library/features}/supabase/rls.md +0 -0
  219. /package/{playbooks/capabilities → library/features}/supabase/testing.md +0 -0
  220. /package/{playbooks/capabilities → library/features}/supabase/vite.md +0 -0
  221. /package/{playbooks → library/optional-features}/concerns/axios.md +0 -0
  222. /package/{playbooks → library/optional-features}/concerns/next-safe-action.md +0 -0
  223. /package/{playbooks → library/optional-features}/concerns/next-themes.md +0 -0
  224. /package/{playbooks → library/optional-features}/concerns/nuqs.md +0 -0
  225. /package/{playbooks → library/optional-features}/concerns/t3-env.md +0 -0
  226. /package/{playbooks → library/optional-features}/concerns/tanstack-query.md +0 -0
  227. /package/{playbooks → library/optional-features}/concerns/zustand.md +0 -0
  228. /package/{playbooks/styling/native-styles.manifest.json → library/optional-features/styling/native-styles/definition.json} +0 -0
  229. /package/{playbooks/styling → library/optional-features/styling/native-styles}/native-styles.md +0 -0
  230. /package/{playbooks/styling/tailwind.manifest.json → library/optional-features/styling/tailwind/definition.json} +0 -0
  231. /package/{playbooks/styling → library/optional-features/styling/tailwind}/tailwind-extensions.md +0 -0
  232. /package/{playbooks/platform → library/platforms}/laravel-ui/blade/architecture.md +0 -0
  233. /package/{playbooks/platform → library/platforms}/laravel-ui/blade/runtime.md +0 -0
  234. /package/{playbooks/platform → library/platforms}/laravel-ui/blade/security.md +0 -0
  235. /package/{playbooks/platform → library/platforms}/laravel-ui/blade/structure.md +0 -0
  236. /package/{playbooks/platform → library/platforms}/laravel-ui/blade/testing.md +0 -0
  237. /package/{playbooks/stack/laravel-ui.manifest.json → library/platforms/laravel-ui/definition.json} +0 -0
  238. /package/{playbooks/platform → library/platforms}/laravel-ui/inertia-react/architecture.md +0 -0
  239. /package/{playbooks/platform → library/platforms}/laravel-ui/inertia-react/runtime.md +0 -0
  240. /package/{playbooks/platform → library/platforms}/laravel-ui/inertia-react/security.md +0 -0
  241. /package/{playbooks/platform → library/platforms}/laravel-ui/inertia-react/structure.md +0 -0
  242. /package/{playbooks/platform → library/platforms}/laravel-ui/inertia-react/testing.md +0 -0
  243. /package/{playbooks/platform → library/platforms}/laravel-ui/livewire/architecture.md +0 -0
  244. /package/{playbooks/platform → library/platforms}/laravel-ui/livewire/runtime.md +0 -0
  245. /package/{playbooks/platform → library/platforms}/laravel-ui/livewire/security.md +0 -0
  246. /package/{playbooks/platform → library/platforms}/laravel-ui/livewire/structure.md +0 -0
  247. /package/{playbooks/platform → library/platforms}/laravel-ui/livewire/testing.md +0 -0
  248. /package/{playbooks/platform → library/platforms/mobile}/mobile.md +0 -0
  249. /package/{playbooks/platform → library/platforms/web}/web.md +0 -0
  250. /package/{playbooks/stack → library/stacks}/expo/architecture.md +0 -0
  251. /package/{playbooks/stack → library/stacks}/expo/runtime.md +0 -0
  252. /package/{playbooks/stack → library/stacks}/expo/security.md +0 -0
  253. /package/{playbooks/stack → library/stacks}/expo/structure.md +0 -0
  254. /package/{playbooks/stack → library/stacks}/expo/testing.md +0 -0
  255. /package/{playbooks/stack → library/stacks}/laravel/architecture.md +0 -0
  256. /package/{playbooks/stack/laravel.manifest.json → library/stacks/laravel/definition.json} +0 -0
  257. /package/{playbooks/stack → library/stacks}/laravel/runtime.md +0 -0
  258. /package/{playbooks/stack → library/stacks}/laravel/security.md +0 -0
  259. /package/{playbooks/stack → library/stacks}/laravel/structure.md +0 -0
  260. /package/{playbooks/stack → library/stacks}/laravel/testing.md +0 -0
  261. /package/{playbooks/stack → library/stacks}/nextjs/architecture.md +0 -0
  262. /package/{playbooks/stack → library/stacks}/nextjs/runtime.md +0 -0
  263. /package/{playbooks/stack → library/stacks}/nextjs/security.md +0 -0
  264. /package/{playbooks/stack → library/stacks}/nextjs/structure.md +0 -0
  265. /package/{playbooks/stack → library/stacks}/nextjs/testing.md +0 -0
  266. /package/{playbooks/stack/none.manifest.json → library/stacks/none/definition.json} +0 -0
  267. /package/{playbooks/stack → library/stacks}/react-vite/architecture.md +0 -0
  268. /package/{playbooks/stack → library/stacks}/react-vite/runtime.md +0 -0
  269. /package/{playbooks/stack → library/stacks}/react-vite/security.md +0 -0
  270. /package/{playbooks/stack → library/stacks}/react-vite/structure.md +0 -0
  271. /package/{playbooks/stack → library/stacks}/react-vite/testing.md +0 -0
  272. /package/{playbooks/stack → library/stacks}/springboot/architecture.md +0 -0
  273. /package/{playbooks/stack/springboot.manifest.json → library/stacks/springboot/definition.json} +0 -0
  274. /package/{playbooks/stack → library/stacks}/springboot/runtime.md +0 -0
  275. /package/{playbooks/stack → library/stacks}/springboot/security.md +0 -0
  276. /package/{playbooks/stack → library/stacks}/springboot/structure.md +0 -0
  277. /package/{playbooks/stack → library/stacks}/springboot/testing.md +0 -0
  278. /package/{playbooks/universal → library/universal/accessibility}/accessibility.md +0 -0
  279. /package/{playbooks/universal → library/universal/error-handling}/error-handling.md +0 -0
  280. /package/{playbooks/universal → library/universal/observability}/observability.md +0 -0
  281. /package/{playbooks/universal → library/universal/security}/security.md +0 -0
  282. /package/{lib → src/engine}/project-location.js +0 -0
  283. /package/{lib → src}/stacks/context.js +0 -0
  284. /package/{lib/stacks/contract.js → src/stacks/rules.js} +0 -0
  285. /package/{ci → templates/ci}/expo.yml +0 -0
  286. /package/{ci → templates/ci}/laravel.yml +0 -0
  287. /package/{ci → templates/ci}/nextjs.yml +0 -0
  288. /package/{ci → templates/ci}/springboot.yml +0 -0
  289. /package/{ci → templates/ci}/vite.yml +0 -0
@@ -1,186 +0,0 @@
1
- # Git Conventions (Universal)
2
-
3
- Applies to every project regardless of stack.
4
-
5
- ---
6
-
7
- ## Branch Structure
8
- | Branch | Purpose |
9
- |--------------|-----------------------------------------------|
10
- | `main` | Production — always stable, always deployable |
11
- | `dev` | Integration — all features merge here first |
12
- | `feature/*` | New capability |
13
- | `fix/*` | Bug fix |
14
- | `refactor/*` | Restructure without behavior change |
15
- | `chore/*` | Dependencies, config, tooling |
16
- | `docs/*` | Documentation only |
17
- | `test/*` | Adding or updating tests only |
18
-
19
- ## Branch Rules
20
- - NEVER commit directly to `main` or `dev`
21
- - ALWAYS branch off `dev` — never off `main`
22
- - NEVER merge or create PRs unless explicitly asked
23
- - NEVER push to remote unless explicitly asked
24
- - One logical change per branch — keep branches small and focused
25
-
26
- ## Starting a Branch
27
- ```bash
28
- git checkout dev
29
- git pull origin dev
30
- git checkout -b <type>/<short-description>
31
- ```
32
-
33
- ### Examples
34
- ```bash
35
- git checkout -b feature/user-profile-page
36
- git checkout -b fix/token-expiry-race
37
- git checkout -b refactor/auth-feature-module
38
- git checkout -b chore/update-dependencies
39
- git checkout -b docs/update-api-endpoints
40
- ```
41
-
42
- ---
43
-
44
- ## Commit Convention
45
-
46
- ### Format
47
- ```
48
- type(scope): short description
49
- ```
50
-
51
- ### Rules
52
- - Lowercase only — no uppercase anywhere
53
- - No period at the end
54
- - Present tense — "add" not "added", "fix" not "fixed"
55
- - Under 72 characters
56
- - One logical change per commit
57
-
58
- ### Types
59
- | Type | When to use |
60
- |------------|---------------------------------------------------|
61
- | `feat` | New feature or capability |
62
- | `fix` | Bug fix |
63
- | `refactor` | Restructure without behavior change |
64
- | `chore` | Deps, config, tooling — no production code change |
65
- | `docs` | Documentation only |
66
- | `test` | Adding or updating tests |
67
- | `ci` | GitHub Actions or CI/CD workflow changes |
68
- | `style` | Formatting, whitespace — no logic change |
69
-
70
- ### Scopes (React + Spring Boot)
71
- | Scope | When to use |
72
- |------------|------------------------------------|
73
- | `frontend` | Anything inside /frontend |
74
- | `backend` | Anything inside /backend |
75
- | `docker` | Dockerfile or docker-compose |
76
- | `ci` | GitHub Actions workflows |
77
- | `docs` | Anything inside /docs |
78
- | `deps` | Dependency updates (either side) |
79
-
80
- ### Scopes (Next.js projects)
81
- | Scope | When to use |
82
- |------------|------------------------------------|
83
- | `app` | Next.js app router, pages, layouts |
84
- | `api` | API routes or server actions |
85
- | `db` | Database schema, migrations |
86
- | `auth` | Authentication logic |
87
- | `ci` | GitHub Actions workflows |
88
- | `docs` | Anything inside /docs |
89
- | `deps` | Dependency updates |
90
-
91
- ### Examples
92
- ```bash
93
- feat(frontend): add user profile page
94
- feat(backend): add paper download endpoint
95
- fix(backend): resolve token expiry race condition
96
- fix(frontend): correct redirect after logout
97
- refactor(backend): move auth logic into feature module
98
- refactor(frontend): restructure features folder
99
- chore(deps): update spring boot to 3.5.1
100
- chore(docker): add maven cache volume
101
- docs(api): update error contract with traceId field
102
- test(backend): add unit tests for auth service
103
- test(frontend): add vitest tests for useAuth hook
104
- ci(backend): add postgresql service to ci workflow
105
- ```
106
-
107
- ---
108
-
109
- ## Daily Workflow
110
- ```bash
111
- # 1. Always start from updated dev
112
- git checkout dev
113
- git pull origin dev
114
-
115
- # 2. Create your branch
116
- git checkout -b <type>/<description>
117
-
118
- # 3. Work in small, logical commits
119
- git add .
120
- git commit -m "type(scope): description"
121
-
122
- # 4. Push your branch
123
- git push origin <branch-name>
124
-
125
- # 5. Open PR → dev (only when explicitly asked)
126
- # 6. Merge dev → main (only when explicitly asked)
127
- ```
128
-
129
- ---
130
-
131
- ## .gitignore — Always Include
132
- ```
133
- # Environment
134
- .env
135
- .env.local
136
- .env.production
137
-
138
- # Dependencies
139
- node_modules/
140
- .mvn/
141
-
142
- # Build outputs
143
- dist/
144
- build/
145
- target/
146
- .next/
147
-
148
- # IDE
149
- .idea/
150
- .vscode/
151
- *.iml
152
-
153
- # OS
154
- .DS_Store
155
- Thumbs.db
156
-
157
- # Logs
158
- *.log
159
- logs/
160
-
161
- # Docker volumes (if local)
162
- postgres-data/
163
- ```
164
-
165
- ---
166
-
167
- ## Agent Rules
168
- ```
169
- Never:
170
- → commit directly to main or dev
171
- → branch off main
172
- → push or create PRs unless explicitly asked
173
- → put multiple logical changes in one commit
174
- → use vague commit messages ("fix stuff", "update code")
175
-
176
- Always:
177
- → branch off dev
178
- → one logical change per commit
179
- → follow type(scope): description format
180
- → present tense in commit messages
181
-
182
- When asked to commit:
183
- → Stage only files relevant to the current task
184
- → Write a precise commit message following the convention
185
- → Do not push unless explicitly asked
186
- ```
@@ -1,11 +0,0 @@
1
- {
2
- "id": "typescript",
3
- "kind": "universal",
4
- "label": "TypeScript",
5
- "required": true,
6
- "folders": [],
7
- "concerns": [
8
- { "id": "typescript-strict", "required": true, "sections": ["Strict Mode — Always On", "No any", "Type vs Interface"] },
9
- { "id": "validation", "required": false, "when": "Project validates external/runtime input", "sections": ["Zod for Runtime Validation"] }
10
- ]
11
- }
@@ -1,272 +0,0 @@
1
- # TypeScript Rules (Universal)
2
-
3
- Applies to every TypeScript project.
4
-
5
- ---
6
-
7
- ## Strict Mode — Always On
8
- ```json
9
- // tsconfig.json
10
- {
11
- "compilerOptions": {
12
- "strict": true,
13
- "noUncheckedIndexedAccess": true,
14
- "noImplicitReturns": true,
15
- "noFallthroughCasesInSwitch": true,
16
- "exactOptionalPropertyTypes": true
17
- }
18
- }
19
- ```
20
-
21
- These flags catch real bugs. Never disable them.
22
-
23
- ---
24
-
25
- ## No `any`
26
- - Never use `any` unless absolutely unavoidable
27
- - When unavoidable: add `// reason:` comment explaining why
28
-
29
- ```typescript
30
- // ❌
31
- const data: any = fetchUser()
32
- function process(input: any) { ... }
33
-
34
- // ✅
35
- const data: unknown = fetchUser()
36
- function process(input: UserInput) { ... }
37
-
38
- // ✅ justified any with comment
39
- // reason: third-party library has no types and @types package doesn't exist
40
- const chart = new (window as any).ChartLib()
41
- ```
42
-
43
- ### Alternatives to `any`
44
- | Instead of `any` | Use |
45
- |------------------|-------------------------|
46
- | Unknown data | `unknown` |
47
- | Flexible object | `Record<string, unknown>` |
48
- | Multiple types | Union `string \| number` |
49
- | Optional | `T \| undefined` |
50
- | Nullable | `T \| null` |
51
-
52
- ---
53
-
54
- ## Type vs Interface
55
- ```typescript
56
- // Interface — for objects that may be extended or implemented
57
- interface User {
58
- id: string
59
- name: string
60
- email: string
61
- }
62
-
63
- // Type — for unions, intersections, primitives, tuples
64
- type UserId = string
65
- type UserRole = 'ADMIN' | 'USER' | 'MODERATOR'
66
- type Result<T, E> = { ok: true; value: T } | { ok: false; error: E }
67
- type UserWithRole = User & { role: UserRole }
68
- ```
69
-
70
- ### Rule
71
- - Objects → `interface` (extends naturally, better error messages)
72
- - Everything else → `type`
73
- - Never use `I` prefix for interfaces (`IUser` → `User`)
74
-
75
- ---
76
-
77
- ## Discriminated Unions for State
78
- ```typescript
79
- // ❌ scattered boolean flags
80
- type State = {
81
- isLoading: boolean
82
- isError: boolean
83
- isSuccess: boolean
84
- data?: User
85
- error?: Error
86
- }
87
-
88
- // ✅ discriminated union — mutually exclusive states
89
- type State =
90
- | { status: 'idle' }
91
- | { status: 'loading' }
92
- | { status: 'success'; data: User }
93
- | { status: 'error'; error: Error }
94
- ```
95
-
96
- ---
97
-
98
- ## Unknown Over Any for Errors
99
- ```typescript
100
- // ❌
101
- } catch (error: any) {
102
- console.log(error.message)
103
- }
104
-
105
- // ✅
106
- } catch (error: unknown) {
107
- const message = error instanceof Error ? error.message : 'Unknown error'
108
- logger.error(message)
109
- }
110
- ```
111
-
112
- ---
113
-
114
- ## Generics
115
- Use when genuinely reusable — not for ceremony.
116
-
117
- ```typescript
118
- // ✅ genuinely reusable
119
- function first<T>(array: T[]): T | undefined {
120
- return array[0]
121
- }
122
-
123
- // ✅ reusable operation result inside the application
124
- type Result<T, E> = { ok: true; value: T } | { ok: false; error: E }
125
-
126
- // ❌ unnecessary generic
127
- function getUserName<T extends User>(user: T): string {
128
- return user.name
129
- // just use: function getUserName(user: User): string
130
- }
131
- ```
132
-
133
- ---
134
-
135
- ## Zod for Runtime Validation
136
-
137
- Use Zod for runtime validation **when** this project has runtime validation needs (form input, API responses, external data). If the project has no such need, this section does not apply — the rules are optional.
138
-
139
- TypeScript types are compile-time only. Use Zod at runtime boundaries.
140
-
141
- ```typescript
142
- // Define schema
143
- const UserSchema = z.object({
144
- id: z.string().uuid(),
145
- name: z.string().min(1),
146
- email: z.string().email(),
147
- role: z.enum(['ADMIN', 'USER']),
148
- })
149
-
150
- // Infer type from schema — single source of truth
151
- type User = z.infer<typeof UserSchema>
152
-
153
- // Validate at runtime
154
- const user = UserSchema.parse(apiResponse.data)
155
- ```
156
-
157
- ### When to use Zod
158
- - Form validation (via React Hook Form resolver)
159
- - API response parsing
160
- - Environment variable validation (t3-env)
161
- - Any external data entering the system
162
-
163
- ---
164
-
165
- ## Where Types Live
166
-
167
- ### Decision tree
168
- ```
169
- Is this type used across multiple features?
170
- → src/types/[name].ts
171
-
172
- Is this type specific to one feature?
173
- → src/features/[name]/types/index.ts
174
-
175
- Is this type a Zod schema + inferred type?
176
- → src/features/[name]/schemas/[name].schema.ts
177
-
178
- Is this type shared by several transport clients?
179
- → src/types/transport.ts
180
- ```
181
-
182
- ### Global types (src/types/)
183
- ```typescript
184
- // src/types/transport.ts
185
- // Successful endpoints return their normal DTO. Model only genuinely shared shapes.
186
- export type ProblemDetails = { type: string; title: string; status: number; detail?: string; traceId?: string }
187
-
188
- // src/types/pagination.ts
189
- export type PaginatedResponse<T> = {
190
- data: T[]
191
- total: number
192
- page: number
193
- limit: number
194
- }
195
- ```
196
-
197
- ---
198
-
199
- ## Type Assertions
200
- Avoid `as` unless justified.
201
-
202
- ```typescript
203
- // ❌ lying to TypeScript
204
- const user = data as User
205
-
206
- // ✅ validate first, then trust
207
- const user = UserSchema.parse(data)
208
-
209
- // ✅ justified assertion with comment
210
- // reason: DOM ref is always set before this handler fires
211
- const input = inputRef.current as HTMLInputElement
212
- ```
213
-
214
- ---
215
-
216
- ## Enums vs Union Types
217
- Prefer union types over enums for most cases.
218
-
219
- ```typescript
220
- // ❌ enum (compiles to weird JS, harder to iterate)
221
- enum UserRole {
222
- ADMIN = 'ADMIN',
223
- USER = 'USER',
224
- }
225
-
226
- // ✅ const object + union type (tree-shakeable, readable compiled output)
227
- export const ROLES = {
228
- ADMIN: 'ADMIN',
229
- USER: 'USER',
230
- } as const
231
-
232
- export type UserRole = typeof ROLES[keyof typeof ROLES]
233
- // → 'ADMIN' | 'USER'
234
- ```
235
-
236
- ---
237
-
238
- ## Null vs Undefined
239
- ```typescript
240
- // Use null: explicitly absent (API returns null, user cleared a field)
241
- type User = { avatar: string | null }
242
-
243
- // Use undefined: optionally present (optional function param, optional object key)
244
- type Options = { timeout?: number }
245
-
246
- // Never mix without reason — pick one for each case and be consistent
247
- ```
248
-
249
- ---
250
-
251
- ## Agent Rules
252
- ```
253
- strict: true — never disable, never add ts-ignore without // reason:
254
-
255
- Type a new variable?
256
- → Use the most specific type possible
257
- → Infer from Zod schema if validating external data
258
- → Use unknown for error catch blocks
259
-
260
- New shared type?
261
- → If used in 2+ features → src/types/
262
- → If feature-specific → features/[name]/types/
263
-
264
- New form?
265
- → Zod schema first → infer type → pass to React Hook Form
266
-
267
- Avoid:
268
- → any (use unknown)
269
- → type assertions without reason comment
270
- → enums (use const object + union type)
271
- → I prefix on interfaces
272
- ```
@@ -1,48 +0,0 @@
1
- import fs from 'fs-extra'
2
-
3
- const catalog = await fs.readJson(new URL('../compatibility/profiles.json', import.meta.url))
4
- const scope = process.argv.find((arg) => arg.startsWith('--scope='))?.split('=')[1] || 'smoke'
5
- if (!['smoke', 'full'].includes(scope)) throw new Error('--scope must be smoke or full')
6
-
7
- const cases = [
8
- 'nextjs-none', 'nextjs-supabase', 'nextjs-springboot', 'nextjs-postgres', 'nextjs-laravel',
9
- 'react-none', 'react-supabase', 'react-springboot', 'react-laravel',
10
- 'react-native-none', 'react-native-supabase', 'react-native-springboot', 'react-native-laravel',
11
- 'laravel-api', 'laravel-blade', 'laravel-livewire', 'laravel-inertia-react',
12
- ]
13
-
14
- function authChoices(caseName) {
15
- const mobile = caseName.startsWith('react-native')
16
- const nonBrowser = mobile || caseName === 'laravel-api'
17
- const base = ['not-yet', 'none'].map((authentication) => ({ authentication, audience: nonBrowser ? 'multi-client' : 'website' }))
18
- if (caseName.includes('supabase')) base.push({ authentication: 'yes', audience: mobile ? 'multi-client' : 'website' })
19
- if (caseName.includes('springboot') || caseName.includes('laravel')) {
20
- if (caseName.startsWith('laravel-') && caseName !== 'laravel-api') base.push({ authentication: 'yes', audience: 'website' })
21
- else if (mobile || caseName === 'laravel-api') base.push({ authentication: 'yes', audience: 'multi-client' })
22
- else base.push({ authentication: 'yes', audience: 'website' }, { authentication: 'yes', audience: 'multi-client' })
23
- }
24
- return base
25
- }
26
-
27
- const current = catalog.defaultProfile
28
- const full = Object.entries(catalog.profiles).filter(([profile]) => profile === current).flatMap(([profile, versions]) =>
29
- cases.flatMap((caseName) => ['small', 'medium', 'large'].flatMap((architecture) =>
30
- authChoices(caseName).map((auth) => ({ profile, case: caseName, architecture, ...auth, node: versions.runtimes.node, java: versions.runtimes.java, php: versions.runtimes.php })))),
31
- )
32
-
33
- const smokeSelections = [
34
- ['nextjs-none', 'small', 'not-yet', 'website'],
35
- ['nextjs-supabase', 'medium', 'yes', 'website'],
36
- ['react-springboot', 'large', 'yes', 'website'],
37
- ['react-native-supabase', 'medium', 'yes', 'multi-client'],
38
- ['react-native-springboot', 'small', 'yes', 'multi-client'],
39
- ['laravel-api', 'medium', 'not-yet', 'multi-client'],
40
- ['laravel-blade', 'small', 'yes', 'website'],
41
- ['laravel-livewire', 'medium', 'none', 'website'],
42
- ['laravel-inertia-react', 'large', 'yes', 'website'],
43
- ['react-laravel', 'medium', 'yes', 'website'],
44
- ]
45
- const smoke = full.filter((entry) => entry.profile === current && smokeSelections.some(([caseName, architecture, authentication, audience]) =>
46
- entry.case === caseName && entry.architecture === architecture && entry.authentication === authentication && entry.audience === audience))
47
-
48
- process.stdout.write(JSON.stringify(scope === 'full' ? full : smoke))