@glxmart/boss-cli 1.0.0 → 1.2.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 (317) hide show
  1. package/README.md +0 -1
  2. package/assets/claude-md/docs/conductor.md +139 -0
  3. package/assets/claude-md/docs/initialization.md +2 -2
  4. package/assets/claude-md/docs/workers.md +33 -54
  5. package/assets/claude-md/docs/workflow.md +23 -59
  6. package/assets/claude-md/template.md +198 -756
  7. package/assets/git-hooks/commit-msg.sh +4 -8
  8. package/assets/git-hooks/pre-commit.sh +0 -4
  9. package/assets/git-hooks/pre-push.sh +21 -0
  10. package/assets/github-workflows/CODEOWNERS +21 -2
  11. package/assets/github-workflows/boss-ci.yml +163 -23
  12. package/assets/github-workflows/boss-gates.yml +100 -13
  13. package/assets/template-docs/nextjs-app-turbo.md +412 -61
  14. package/assets/template-loader/gitignore +14 -0
  15. package/assets/worker-configs/architect/.claude/skills/conductor-orchestration.md +635 -0
  16. package/assets/worker-configs/architect/.claude/skills/spec-kit-workflow.md +827 -0
  17. package/assets/worker-configs/architect/CLAUDE.md +99 -38
  18. package/assets/worker-configs/clarifier/.claude/skills/conductor-orchestration.md +635 -0
  19. package/assets/worker-configs/clarifier/.claude/skills/spec-kit-workflow.md +827 -0
  20. package/assets/worker-configs/clarifier/CLAUDE.md +81 -40
  21. package/assets/worker-configs/code-reviewer/.claude/skills/nextjs-turbo-stack.md +1017 -0
  22. package/assets/worker-configs/code-reviewer/.claude/skills/spec-kit-workflow.md +827 -0
  23. package/assets/worker-configs/code-reviewer/.claude/skills/test-first-methodology.md +745 -0
  24. package/assets/worker-configs/code-reviewer/CLAUDE.md +85 -79
  25. package/assets/worker-configs/consolidator/.claude/skills/conductor-orchestration.md +635 -0
  26. package/assets/worker-configs/consolidator/.claude/skills/spec-kit-workflow.md +827 -0
  27. package/assets/worker-configs/consolidator/CLAUDE.md +94 -88
  28. package/assets/worker-configs/developer-backend/.claude/skills/nextjs-turbo-stack.md +1017 -0
  29. package/assets/worker-configs/developer-backend/.claude/skills/spec-kit-workflow.md +827 -0
  30. package/assets/worker-configs/developer-backend/.claude/skills/test-first-methodology.md +745 -0
  31. package/assets/worker-configs/developer-backend/CLAUDE.md +156 -56
  32. package/assets/worker-configs/developer-frontend/.claude/skills/nextjs-turbo-stack.md +1017 -0
  33. package/assets/worker-configs/developer-frontend/.claude/skills/spec-kit-workflow.md +827 -0
  34. package/assets/worker-configs/developer-frontend/.claude/skills/test-first-methodology.md +745 -0
  35. package/assets/worker-configs/developer-frontend/CLAUDE.md +152 -54
  36. package/assets/worker-configs/developer-fullstack/.claude/skills/nextjs-turbo-stack.md +1017 -0
  37. package/assets/worker-configs/developer-fullstack/.claude/skills/spec-kit-workflow.md +827 -0
  38. package/assets/worker-configs/developer-fullstack/.claude/skills/test-first-methodology.md +745 -0
  39. package/assets/worker-configs/developer-fullstack/CLAUDE.md +155 -57
  40. package/assets/worker-configs/devops-engineer/.claude/skills/infrastructure-as-code.md +794 -0
  41. package/assets/worker-configs/devops-engineer/.claude/skills/spec-kit-workflow.md +827 -0
  42. package/assets/worker-configs/devops-engineer/CLAUDE.md +92 -85
  43. package/assets/worker-configs/planner/.claude/skills/conductor-orchestration.md +635 -0
  44. package/assets/worker-configs/planner/.claude/skills/spec-kit-workflow.md +827 -0
  45. package/assets/worker-configs/planner/CLAUDE.md +143 -46
  46. package/assets/worker-configs/product-owner/CLAUDE.md +72 -82
  47. package/assets/worker-configs/reviewer/.claude/skills/conductor-orchestration.md +635 -0
  48. package/assets/worker-configs/reviewer/.claude/skills/spec-kit-workflow.md +827 -0
  49. package/assets/worker-configs/reviewer/CLAUDE.md +108 -50
  50. package/assets/worker-configs/security-engineer/.claude/skills/spec-kit-workflow.md +827 -0
  51. package/assets/worker-configs/security-engineer/CLAUDE.md +83 -83
  52. package/assets/worker-configs/spec-writer/.claude/skills/conductor-orchestration.md +635 -0
  53. package/assets/worker-configs/spec-writer/.claude/skills/spec-kit-workflow.md +827 -0
  54. package/assets/worker-configs/spec-writer/CLAUDE.md +107 -48
  55. package/assets/worker-configs/technical-writer/.claude/skills/nextjs-turbo-stack.md +1017 -0
  56. package/assets/worker-configs/technical-writer/.claude/skills/spec-kit-workflow.md +827 -0
  57. package/assets/worker-configs/technical-writer/CLAUDE.md +91 -81
  58. package/assets/worker-configs/tester/.claude/skills/nextjs-turbo-stack.md +1017 -0
  59. package/assets/worker-configs/tester/.claude/skills/spec-kit-workflow.md +827 -0
  60. package/assets/worker-configs/tester/.claude/skills/test-first-methodology.md +745 -0
  61. package/assets/worker-configs/tester/CLAUDE.md +141 -52
  62. package/dist/assets/claude-md/docs/conductor.md +139 -0
  63. package/dist/assets/claude-md/docs/initialization.md +2 -2
  64. package/dist/assets/claude-md/docs/workers.md +33 -54
  65. package/dist/assets/claude-md/docs/workflow.md +23 -59
  66. package/dist/assets/claude-md/template.md +198 -756
  67. package/dist/assets/git-hooks/commit-msg.sh +4 -8
  68. package/dist/assets/git-hooks/pre-commit.sh +0 -4
  69. package/dist/assets/git-hooks/pre-push.sh +21 -0
  70. package/dist/assets/github-workflows/CODEOWNERS +21 -2
  71. package/dist/assets/github-workflows/boss-ci.yml +163 -23
  72. package/dist/assets/github-workflows/boss-gates.yml +100 -13
  73. package/dist/assets/template-docs/nextjs-app-turbo.md +412 -61
  74. package/dist/assets/template-loader/gitignore +14 -0
  75. package/dist/assets/worker-configs/architect/.claude/skills/conductor-orchestration.md +635 -0
  76. package/dist/assets/worker-configs/architect/.claude/skills/spec-kit-workflow.md +827 -0
  77. package/dist/assets/worker-configs/architect/CLAUDE.md +99 -38
  78. package/dist/assets/worker-configs/clarifier/.claude/skills/conductor-orchestration.md +635 -0
  79. package/dist/assets/worker-configs/clarifier/.claude/skills/spec-kit-workflow.md +827 -0
  80. package/dist/assets/worker-configs/clarifier/CLAUDE.md +81 -40
  81. package/dist/assets/worker-configs/code-reviewer/.claude/skills/nextjs-turbo-stack.md +1017 -0
  82. package/dist/assets/worker-configs/code-reviewer/.claude/skills/spec-kit-workflow.md +827 -0
  83. package/dist/assets/worker-configs/code-reviewer/.claude/skills/test-first-methodology.md +745 -0
  84. package/dist/assets/worker-configs/code-reviewer/CLAUDE.md +85 -79
  85. package/dist/assets/worker-configs/consolidator/.claude/skills/conductor-orchestration.md +635 -0
  86. package/dist/assets/worker-configs/consolidator/.claude/skills/spec-kit-workflow.md +827 -0
  87. package/dist/assets/worker-configs/consolidator/CLAUDE.md +94 -88
  88. package/dist/assets/worker-configs/developer-backend/.claude/skills/nextjs-turbo-stack.md +1017 -0
  89. package/dist/assets/worker-configs/developer-backend/.claude/skills/spec-kit-workflow.md +827 -0
  90. package/dist/assets/worker-configs/developer-backend/.claude/skills/test-first-methodology.md +745 -0
  91. package/dist/assets/worker-configs/developer-backend/CLAUDE.md +156 -56
  92. package/dist/assets/worker-configs/developer-frontend/.claude/skills/nextjs-turbo-stack.md +1017 -0
  93. package/dist/assets/worker-configs/developer-frontend/.claude/skills/spec-kit-workflow.md +827 -0
  94. package/dist/assets/worker-configs/developer-frontend/.claude/skills/test-first-methodology.md +745 -0
  95. package/dist/assets/worker-configs/developer-frontend/CLAUDE.md +152 -54
  96. package/dist/assets/worker-configs/developer-fullstack/.claude/skills/nextjs-turbo-stack.md +1017 -0
  97. package/dist/assets/worker-configs/developer-fullstack/.claude/skills/spec-kit-workflow.md +827 -0
  98. package/dist/assets/worker-configs/developer-fullstack/.claude/skills/test-first-methodology.md +745 -0
  99. package/dist/assets/worker-configs/developer-fullstack/CLAUDE.md +155 -57
  100. package/dist/assets/worker-configs/devops-engineer/.claude/skills/infrastructure-as-code.md +794 -0
  101. package/dist/assets/worker-configs/devops-engineer/.claude/skills/spec-kit-workflow.md +827 -0
  102. package/dist/assets/worker-configs/devops-engineer/CLAUDE.md +92 -85
  103. package/dist/assets/worker-configs/planner/.claude/skills/conductor-orchestration.md +635 -0
  104. package/dist/assets/worker-configs/planner/.claude/skills/spec-kit-workflow.md +827 -0
  105. package/dist/assets/worker-configs/planner/CLAUDE.md +143 -46
  106. package/dist/assets/worker-configs/product-owner/CLAUDE.md +72 -82
  107. package/dist/assets/worker-configs/reviewer/.claude/skills/conductor-orchestration.md +635 -0
  108. package/dist/assets/worker-configs/reviewer/.claude/skills/spec-kit-workflow.md +827 -0
  109. package/dist/assets/worker-configs/reviewer/CLAUDE.md +108 -50
  110. package/dist/assets/worker-configs/security-engineer/.claude/skills/spec-kit-workflow.md +827 -0
  111. package/dist/assets/worker-configs/security-engineer/CLAUDE.md +83 -83
  112. package/dist/assets/worker-configs/spec-writer/.claude/skills/conductor-orchestration.md +635 -0
  113. package/dist/assets/worker-configs/spec-writer/.claude/skills/spec-kit-workflow.md +827 -0
  114. package/dist/assets/worker-configs/spec-writer/CLAUDE.md +107 -48
  115. package/dist/assets/worker-configs/technical-writer/.claude/skills/nextjs-turbo-stack.md +1017 -0
  116. package/dist/assets/worker-configs/technical-writer/.claude/skills/spec-kit-workflow.md +827 -0
  117. package/dist/assets/worker-configs/technical-writer/CLAUDE.md +91 -81
  118. package/dist/assets/worker-configs/tester/.claude/skills/nextjs-turbo-stack.md +1017 -0
  119. package/dist/assets/worker-configs/tester/.claude/skills/spec-kit-workflow.md +827 -0
  120. package/dist/assets/worker-configs/tester/.claude/skills/test-first-methodology.md +745 -0
  121. package/dist/assets/worker-configs/tester/CLAUDE.md +141 -52
  122. package/dist/commands/__tests__/bootstrap.test.js +51 -51
  123. package/dist/commands/__tests__/bootstrap.test.js.map +1 -1
  124. package/dist/commands/bootstrap.d.ts.map +1 -1
  125. package/dist/commands/bootstrap.js +23 -20
  126. package/dist/commands/bootstrap.js.map +1 -1
  127. package/dist/commands/doctor.js +33 -9
  128. package/dist/commands/doctor.js.map +1 -1
  129. package/dist/commands/templates.d.ts +1 -1
  130. package/dist/commands/templates.d.ts.map +1 -1
  131. package/dist/commands/templates.js +1 -1
  132. package/dist/commands/templates.js.map +1 -1
  133. package/dist/constants.d.ts +2 -2
  134. package/dist/constants.d.ts.map +1 -1
  135. package/dist/constants.js +1 -1
  136. package/dist/constants.js.map +1 -1
  137. package/dist/generators/__tests__/boss-config.test.js +4 -4
  138. package/dist/generators/__tests__/boss-config.test.js.map +1 -1
  139. package/dist/generators/__tests__/claude-folder.test.js +8 -8
  140. package/dist/generators/__tests__/claude-folder.test.js.map +1 -1
  141. package/dist/generators/__tests__/claude-md.test.js +25 -16
  142. package/dist/generators/__tests__/claude-md.test.js.map +1 -1
  143. package/dist/generators/__tests__/container-use-config.test.js +2 -2
  144. package/dist/generators/__tests__/container-use-config.test.js.map +1 -1
  145. package/dist/generators/__tests__/git-hooks.test.js.map +1 -1
  146. package/dist/generators/__tests__/github-workflows.test.js +10 -6
  147. package/dist/generators/__tests__/github-workflows.test.js.map +1 -1
  148. package/dist/generators/__tests__/mcp-config.test.js +6 -6
  149. package/dist/generators/__tests__/project-structure.test.js +2 -2
  150. package/dist/generators/__tests__/quality-gates.test.js +11 -3
  151. package/dist/generators/__tests__/quality-gates.test.js.map +1 -1
  152. package/dist/generators/__tests__/specify-structure.test.js +1 -1
  153. package/dist/generators/__tests__/specify-structure.test.js.map +1 -1
  154. package/dist/generators/__tests__/template-docs.test.js +1 -1
  155. package/dist/generators/__tests__/template-docs.test.js.map +1 -1
  156. package/dist/generators/__tests__/template-loader.test.js +209 -59
  157. package/dist/generators/__tests__/template-loader.test.js.map +1 -1
  158. package/dist/generators/__tests__/worker-configs.test.js +7 -7
  159. package/dist/generators/boss-config.d.ts.map +1 -1
  160. package/dist/generators/boss-config.js +46 -51
  161. package/dist/generators/boss-config.js.map +1 -1
  162. package/dist/generators/claude-folder.d.ts +1 -1
  163. package/dist/generators/claude-folder.d.ts.map +1 -1
  164. package/dist/generators/claude-folder.js +5 -5
  165. package/dist/generators/claude-folder.js.map +1 -1
  166. package/dist/generators/claude-md.d.ts.map +1 -1
  167. package/dist/generators/claude-md.js +83 -42
  168. package/dist/generators/claude-md.js.map +1 -1
  169. package/dist/generators/container-use-config.d.ts.map +1 -1
  170. package/dist/generators/container-use-config.js +5 -7
  171. package/dist/generators/container-use-config.js.map +1 -1
  172. package/dist/generators/docker-compose.d.ts.map +1 -1
  173. package/dist/generators/docker-compose.js.map +1 -1
  174. package/dist/generators/git-hooks.d.ts.map +1 -1
  175. package/dist/generators/git-hooks.js +2 -2
  176. package/dist/generators/git-hooks.js.map +1 -1
  177. package/dist/generators/github-workflows.js +3 -3
  178. package/dist/generators/github-workflows.js.map +1 -1
  179. package/dist/generators/mcp-config.d.ts.map +1 -1
  180. package/dist/generators/mcp-config.js +18 -16
  181. package/dist/generators/mcp-config.js.map +1 -1
  182. package/dist/generators/project-structure.d.ts +1 -1
  183. package/dist/generators/project-structure.d.ts.map +1 -1
  184. package/dist/generators/project-structure.js +2 -2
  185. package/dist/generators/project-structure.js.map +1 -1
  186. package/dist/generators/quality-gates.d.ts.map +1 -1
  187. package/dist/generators/quality-gates.js +13 -5
  188. package/dist/generators/quality-gates.js.map +1 -1
  189. package/dist/generators/specify-structure.d.ts.map +1 -1
  190. package/dist/generators/specify-structure.js +1 -2
  191. package/dist/generators/specify-structure.js.map +1 -1
  192. package/dist/generators/template-docs.js +2 -2
  193. package/dist/generators/template-docs.js.map +1 -1
  194. package/dist/generators/template-loader.d.ts.map +1 -1
  195. package/dist/generators/template-loader.js +259 -143
  196. package/dist/generators/template-loader.js.map +1 -1
  197. package/dist/generators/worker-configs.d.ts.map +1 -1
  198. package/dist/generators/worker-configs.js +7 -5
  199. package/dist/generators/worker-configs.js.map +1 -1
  200. package/dist/index.js +2 -2
  201. package/dist/index.js.map +1 -1
  202. package/dist/presets/__tests__/quality-presets.test.js +9 -5
  203. package/dist/presets/__tests__/quality-presets.test.js.map +1 -1
  204. package/dist/presets/quality-presets.d.ts.map +1 -1
  205. package/dist/presets/quality-presets.js +11 -11
  206. package/dist/presets/quality-presets.js.map +1 -1
  207. package/dist/types/index.d.ts +1 -0
  208. package/dist/types/index.d.ts.map +1 -1
  209. package/dist/types/index.js +2 -1
  210. package/dist/types/index.js.map +1 -1
  211. package/dist/types/internal.d.ts +69 -0
  212. package/dist/types/internal.d.ts.map +1 -0
  213. package/dist/types/internal.js +4 -0
  214. package/dist/types/internal.js.map +1 -0
  215. package/dist/utils/__tests__/file-system.test.js +1 -1
  216. package/dist/utils/__tests__/file-system.test.js.map +1 -1
  217. package/dist/utils/__tests__/git.test.js.map +1 -1
  218. package/dist/utils/__tests__/template-loader.test.js.map +1 -1
  219. package/dist/utils/__tests__/validators.test.js +1 -1
  220. package/dist/utils/__tests__/validators.test.js.map +1 -1
  221. package/dist/utils/file-system.d.ts.map +1 -1
  222. package/dist/utils/file-system.js +1 -4
  223. package/dist/utils/file-system.js.map +1 -1
  224. package/dist/utils/git.d.ts.map +1 -1
  225. package/dist/utils/git.js +17 -11
  226. package/dist/utils/git.js.map +1 -1
  227. package/dist/utils/prompts.d.ts.map +1 -1
  228. package/dist/utils/prompts.js +51 -39
  229. package/dist/utils/prompts.js.map +1 -1
  230. package/dist/utils/template-loader.d.ts +2 -1
  231. package/dist/utils/template-loader.d.ts.map +1 -1
  232. package/dist/utils/template-loader.js +11 -5
  233. package/dist/utils/template-loader.js.map +1 -1
  234. package/dist/utils/validators.d.ts.map +1 -1
  235. package/dist/utils/validators.js +16 -4
  236. package/dist/utils/validators.js.map +1 -1
  237. package/package.json +2 -2
  238. package/templates/nextjs-turbo-monorepo/base/README.md +167 -0
  239. package/templates/nextjs-turbo-monorepo/base/_gitignore +71 -0
  240. package/templates/nextjs-turbo-monorepo/base/_npmrc +12 -0
  241. package/templates/nextjs-turbo-monorepo/base/apps/admin/app/layout.tsx +19 -0
  242. package/templates/nextjs-turbo-monorepo/base/apps/admin/app/page.tsx +34 -0
  243. package/templates/nextjs-turbo-monorepo/base/apps/admin/next.config.ts +20 -0
  244. package/templates/nextjs-turbo-monorepo/base/apps/admin/package.json +42 -0
  245. package/templates/nextjs-turbo-monorepo/base/apps/admin/tsconfig.json +16 -0
  246. package/templates/nextjs-turbo-monorepo/base/apps/web/app/globals.css +59 -0
  247. package/templates/nextjs-turbo-monorepo/base/apps/web/app/layout.tsx +20 -0
  248. package/templates/nextjs-turbo-monorepo/base/apps/web/app/page.tsx +17 -0
  249. package/templates/nextjs-turbo-monorepo/base/apps/web/components.json +18 -0
  250. package/templates/nextjs-turbo-monorepo/base/apps/web/env.ts +45 -0
  251. package/templates/nextjs-turbo-monorepo/base/apps/web/next.config.ts +38 -0
  252. package/templates/nextjs-turbo-monorepo/base/apps/web/package.json +45 -0
  253. package/templates/nextjs-turbo-monorepo/base/apps/web/tsconfig.json +19 -0
  254. package/templates/nextjs-turbo-monorepo/base/apps/web/vitest.config.ts +28 -0
  255. package/templates/nextjs-turbo-monorepo/base/docker/Dockerfile.admin +76 -0
  256. package/templates/nextjs-turbo-monorepo/base/docker/Dockerfile.web +76 -0
  257. package/templates/nextjs-turbo-monorepo/base/docker/_dockerignore +48 -0
  258. package/templates/nextjs-turbo-monorepo/base/docker/docker-compose.yml +39 -0
  259. package/templates/nextjs-turbo-monorepo/base/package.json +62 -0
  260. package/templates/nextjs-turbo-monorepo/base/packages/auth/package.json +26 -0
  261. package/templates/nextjs-turbo-monorepo/base/packages/auth/src/config.ts +88 -0
  262. package/templates/nextjs-turbo-monorepo/base/packages/auth/src/index.ts +11 -0
  263. package/templates/nextjs-turbo-monorepo/base/packages/auth/src/types.ts +28 -0
  264. package/templates/nextjs-turbo-monorepo/base/packages/auth/tsconfig.json +9 -0
  265. package/templates/nextjs-turbo-monorepo/base/packages/config/eslint/library.js +35 -0
  266. package/templates/nextjs-turbo-monorepo/base/packages/config/eslint/nextjs.js +51 -0
  267. package/templates/nextjs-turbo-monorepo/base/packages/config/eslint/react-library.js +45 -0
  268. package/templates/nextjs-turbo-monorepo/base/packages/config/package.json +19 -0
  269. package/templates/nextjs-turbo-monorepo/base/packages/config/tailwind/base.ts +50 -0
  270. package/templates/nextjs-turbo-monorepo/base/packages/config/typescript/base.json +23 -0
  271. package/templates/nextjs-turbo-monorepo/base/packages/config/typescript/nextjs.json +17 -0
  272. package/templates/nextjs-turbo-monorepo/base/packages/config/typescript/react-library.json +11 -0
  273. package/templates/nextjs-turbo-monorepo/base/packages/database/package.json +32 -0
  274. package/templates/nextjs-turbo-monorepo/base/packages/database/prisma/schema.prisma +84 -0
  275. package/templates/nextjs-turbo-monorepo/base/packages/database/src/client.ts +16 -0
  276. package/templates/nextjs-turbo-monorepo/base/packages/database/src/index.ts +2 -0
  277. package/templates/nextjs-turbo-monorepo/base/packages/database/tsconfig.json +9 -0
  278. package/templates/nextjs-turbo-monorepo/base/packages/trpc/package.json +32 -0
  279. package/templates/nextjs-turbo-monorepo/base/packages/trpc/src/context.ts +17 -0
  280. package/templates/nextjs-turbo-monorepo/base/packages/trpc/src/index.ts +3 -0
  281. package/templates/nextjs-turbo-monorepo/base/packages/trpc/src/init.ts +34 -0
  282. package/templates/nextjs-turbo-monorepo/base/packages/trpc/src/routers/_app.ts +8 -0
  283. package/templates/nextjs-turbo-monorepo/base/packages/trpc/src/routers/user.ts +36 -0
  284. package/templates/nextjs-turbo-monorepo/base/packages/trpc/tsconfig.json +9 -0
  285. package/templates/nextjs-turbo-monorepo/base/packages/ui/.storybook/main.ts +19 -0
  286. package/templates/nextjs-turbo-monorepo/base/packages/ui/.storybook/preview.ts +15 -0
  287. package/templates/nextjs-turbo-monorepo/base/packages/ui/components.json +17 -0
  288. package/templates/nextjs-turbo-monorepo/base/packages/ui/package.json +62 -0
  289. package/templates/nextjs-turbo-monorepo/base/packages/ui/postcss.config.js +6 -0
  290. package/templates/nextjs-turbo-monorepo/base/packages/ui/src/components/index.ts +2 -0
  291. package/templates/nextjs-turbo-monorepo/base/packages/ui/src/components/ui/button.tsx +57 -0
  292. package/templates/nextjs-turbo-monorepo/base/packages/ui/src/components/ui/card.tsx +76 -0
  293. package/templates/nextjs-turbo-monorepo/base/packages/ui/src/hooks/index.ts +2 -0
  294. package/templates/nextjs-turbo-monorepo/base/packages/ui/src/lib/utils.ts +6 -0
  295. package/templates/nextjs-turbo-monorepo/base/packages/ui/src/styles/globals.css +59 -0
  296. package/templates/nextjs-turbo-monorepo/base/packages/ui/tailwind.config.ts +15 -0
  297. package/templates/nextjs-turbo-monorepo/base/packages/ui/tsconfig.json +12 -0
  298. package/templates/nextjs-turbo-monorepo/base/packages/ui/vitest.config.ts +28 -0
  299. package/templates/nextjs-turbo-monorepo/base/packages/utils/package.json +24 -0
  300. package/templates/nextjs-turbo-monorepo/base/packages/utils/src/date.ts +117 -0
  301. package/templates/nextjs-turbo-monorepo/base/packages/utils/src/index.ts +2 -0
  302. package/templates/nextjs-turbo-monorepo/base/packages/utils/src/string.ts +59 -0
  303. package/templates/nextjs-turbo-monorepo/base/packages/utils/tsconfig.json +9 -0
  304. package/templates/nextjs-turbo-monorepo/base/packages/utils/vitest.config.ts +13 -0
  305. package/templates/nextjs-turbo-monorepo/base/pnpm-workspace.yaml +3 -0
  306. package/templates/nextjs-turbo-monorepo/base/tsconfig.json +19 -0
  307. package/templates/nextjs-turbo-monorepo/base/turbo.json +47 -0
  308. package/templates/nextjs-turbo-monorepo/extras/boss-cli/assets/claude-md/template.md +0 -0
  309. package/templates/nextjs-turbo-monorepo/extras/boss-cli/assets/github-workflows/CODEOWNERS +0 -0
  310. package/templates/nextjs-turbo-monorepo/extras/boss-cli/assets/github-workflows/boss-ci.yml +139 -0
  311. package/templates/nextjs-turbo-monorepo/extras/boss-cli/assets/github-workflows/boss-gates.yml +116 -0
  312. package/templates/nextjs-turbo-monorepo/extras/config/kamal/_env +18 -0
  313. package/templates/nextjs-turbo-monorepo/extras/config/kamal/deploy.yml +92 -0
  314. package/templates/nextjs-turbo-monorepo/extras/scripts/deploy.sh +38 -0
  315. package/templates/nextjs-turbo-monorepo/extras/scripts/setup-db.sh +29 -0
  316. package/assets/claude-md/docs/container-use.md +0 -140
  317. package/dist/assets/claude-md/docs/container-use.md +0 -140
@@ -0,0 +1,1017 @@
1
+ # Next.js Turbo Stack
2
+
3
+ ## Description
4
+
5
+ Create, modify, and review applications built with the Next.js Turbo monorepo stack. Use when working with Next.js 15, React 19, tRPC 11, Prisma 5.24, Tailwind CSS, Storybook, Vitest, Turbo, NextAuth v5, and pnpm workspaces.
6
+
7
+ ## Overview
8
+
9
+ The BOSS nextjs-turbo-monorepo template provides a production-ready stack optimized for rapid development with type safety, testing, and scalability.
10
+
11
+ **Core Stack**:
12
+ - **Next.js 15** - React framework with App Router, server components, server actions
13
+ - **React 19** - UI library with new use hook, server components, concurrent features
14
+ - **tRPC 11** - Type-safe APIs without code generation
15
+ - **Prisma 5.24** - Type-safe database ORM with migrations
16
+ - **Tailwind CSS v4** - Utility-first CSS with shadcn/ui components
17
+ - **Storybook** - Component development and documentation
18
+ - **Vitest** - Fast unit testing with React Testing Library
19
+ - **Turbo** - High-performance monorepo build system
20
+ - **NextAuth v5** - Authentication with providers and sessions
21
+ - **pnpm** - Fast, disk-efficient package manager
22
+
23
+ ## Monorepo Structure
24
+
25
+ ```
26
+ project/
27
+ ├── apps/
28
+ │ ├── web/ # Main Next.js app
29
+ │ │ ├── app/ # App Router (Next.js 15)
30
+ │ │ ├── components/ # React components
31
+ │ │ ├── lib/ # Utilities
32
+ │ │ └── public/ # Static assets
33
+ │ └── admin/ # Admin dashboard (optional)
34
+ ├── packages/
35
+ │ ├── ui/ # Shared React component library
36
+ │ │ ├── src/ # Component source
37
+ │ │ ├── .storybook/ # Storybook config
38
+ │ │ └── stories/ # Component stories
39
+ │ ├── database/ # Prisma ORM
40
+ │ │ ├── prisma/ # Schema and migrations
41
+ │ │ └── src/ # Prisma Client exports
42
+ │ ├── auth/ # NextAuth configuration
43
+ │ │ └── src/ # Auth helpers and config
44
+ │ ├── trpc/ # tRPC routers
45
+ │ │ └── src/ # API routers and procedures
46
+ │ ├── utils/ # Shared utilities
47
+ │ └── config/ # Shared configs
48
+ │ ├── eslint/ # ESLint config
49
+ │ ├── typescript/ # TypeScript config
50
+ │ └── tailwind/ # Tailwind config
51
+ ├── turbo.json # Turbo pipeline config
52
+ ├── pnpm-workspace.yaml # pnpm workspace config
53
+ └── package.json # Root package.json
54
+ ```
55
+
56
+ ## Next.js 15 (App Router)
57
+
58
+ ### File-Based Routing
59
+
60
+ ```
61
+ app/
62
+ ├── layout.tsx # Root layout (wraps all pages)
63
+ ├── page.tsx # Home page (/)
64
+ ├── loading.tsx # Loading UI
65
+ ├── error.tsx # Error boundary
66
+ ├── not-found.tsx # 404 page
67
+ ├── dashboard/
68
+ │ ├── layout.tsx # Dashboard layout
69
+ │ ├── page.tsx # /dashboard
70
+ │ └── settings/
71
+ │ └── page.tsx # /dashboard/settings
72
+ └── api/
73
+ └── webhooks/
74
+ └── route.ts # API route
75
+ ```
76
+
77
+ ### Server Components (Default)
78
+
79
+ ```tsx
80
+ // app/dashboard/page.tsx - Server Component (default)
81
+ import { prisma } from '@repo/database';
82
+
83
+ export default async function DashboardPage() {
84
+ // Fetch data directly in server component
85
+ const users = await prisma.user.findMany();
86
+
87
+ return (
88
+ <div>
89
+ <h1>Dashboard</h1>
90
+ <UserList users={users} />
91
+ </div>
92
+ );
93
+ }
94
+
95
+ // No need for useEffect or useState for data fetching!
96
+ ```
97
+
98
+ ### Client Components
99
+
100
+ ```tsx
101
+ 'use client'; // Required for client-side interactivity
102
+
103
+ import { useState } from 'react';
104
+
105
+ export function Counter() {
106
+ const [count, setCount] = useState(0);
107
+
108
+ return (
109
+ <button onClick={() => setCount(count + 1)}>
110
+ Count: {count}
111
+ </button>
112
+ );
113
+ }
114
+
115
+ // Use client components for:
116
+ // - useState, useEffect, event handlers
117
+ // - Browser-only APIs (localStorage, window)
118
+ // - Interactive UI components
119
+ ```
120
+
121
+ ### Server Actions
122
+
123
+ ```tsx
124
+ // app/actions/user.ts
125
+ 'use server';
126
+
127
+ import { prisma } from '@repo/database';
128
+ import { revalidatePath } from 'next/cache';
129
+
130
+ export async function createUser(formData: FormData) {
131
+ const name = formData.get('name') as string;
132
+ const email = formData.get('email') as string;
133
+
134
+ const user = await prisma.user.create({
135
+ data: { name, email }
136
+ });
137
+
138
+ revalidatePath('/users');
139
+ return user;
140
+ }
141
+
142
+ // Call from client component:
143
+ // <form action={createUser}>...</form>
144
+ ```
145
+
146
+ ### Metadata API
147
+
148
+ ```tsx
149
+ // app/dashboard/layout.tsx
150
+ import type { Metadata } from 'next';
151
+
152
+ export const metadata: Metadata = {
153
+ title: 'Dashboard',
154
+ description: 'User dashboard',
155
+ };
156
+
157
+ // Or dynamic metadata:
158
+ export async function generateMetadata({ params }): Promise<Metadata> {
159
+ const user = await getUser(params.id);
160
+ return {
161
+ title: user.name,
162
+ };
163
+ }
164
+ ```
165
+
166
+ ### Middleware
167
+
168
+ ```typescript
169
+ // middleware.ts (root level)
170
+ import { NextRequest, NextResponse } from 'next/server';
171
+
172
+ export function middleware(request: NextRequest) {
173
+ // Auth check
174
+ const token = request.cookies.get('session');
175
+
176
+ if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
177
+ return NextResponse.redirect(new URL('/login', request.url));
178
+ }
179
+
180
+ return NextResponse.next();
181
+ }
182
+
183
+ export const config = {
184
+ matcher: ['/dashboard/:path*', '/admin/:path*'],
185
+ };
186
+ ```
187
+
188
+ ## React 19
189
+
190
+ ### New `use` Hook
191
+
192
+ ```tsx
193
+ import { use } from 'react';
194
+
195
+ function UserProfile({ userPromise }: { userPromise: Promise<User> }) {
196
+ // `use` hook unwraps promises (React 19)
197
+ const user = use(userPromise);
198
+
199
+ return <div>{user.name}</div>;
200
+ }
201
+
202
+ // Call from server component:
203
+ // <UserProfile userPromise={fetchUser()} />
204
+ ```
205
+
206
+ ### Transitions
207
+
208
+ ```tsx
209
+ 'use client';
210
+
211
+ import { useTransition } from 'react';
212
+
213
+ export function SearchForm() {
214
+ const [isPending, startTransition] = useTransition();
215
+
216
+ const handleSearch = (query: string) => {
217
+ startTransition(() => {
218
+ // Non-urgent update
219
+ setSearchResults(query);
220
+ });
221
+ };
222
+
223
+ return (
224
+ <input
225
+ onChange={(e) => handleSearch(e.target.value)}
226
+ placeholder={isPending ? 'Searching...' : 'Search'}
227
+ />
228
+ );
229
+ }
230
+ ```
231
+
232
+ ### Server Components Best Practices
233
+
234
+ ```tsx
235
+ // ✅ Good - fetch data in server component
236
+ async function UserDashboard() {
237
+ const users = await prisma.user.findMany();
238
+ return <UserList users={users} />;
239
+ }
240
+
241
+ // ✅ Good - pass data to client component as props
242
+ 'use client';
243
+ function UserList({ users }: { users: User[] }) {
244
+ const [selected, setSelected] = useState<User | null>(null);
245
+ return <div>...</div>;
246
+ }
247
+
248
+ // ❌ Bad - fetch in client component (old pattern)
249
+ 'use client';
250
+ function UserDashboard() {
251
+ const [users, setUsers] = useState([]);
252
+ useEffect(() => {
253
+ fetch('/api/users').then(r => r.json()).then(setUsers);
254
+ }, []);
255
+ return <div>...</div>;
256
+ }
257
+ ```
258
+
259
+ ## tRPC 11
260
+
261
+ ### Router Setup
262
+
263
+ ```typescript
264
+ // packages/trpc/src/router.ts
265
+ import { initTRPC } from '@trpc/server';
266
+ import { prisma } from '@repo/database';
267
+
268
+ const t = initTRPC.create();
269
+
270
+ export const appRouter = t.router({
271
+ user: {
272
+ list: t.procedure.query(async () => {
273
+ return prisma.user.findMany();
274
+ }),
275
+
276
+ create: t.procedure
277
+ .input(z.object({ name: z.string(), email: z.string().email() }))
278
+ .mutation(async ({ input }) => {
279
+ return prisma.user.create({ data: input });
280
+ }),
281
+
282
+ getById: t.procedure
283
+ .input(z.string())
284
+ .query(async ({ input }) => {
285
+ return prisma.user.findUnique({ where: { id: input } });
286
+ }),
287
+ },
288
+ });
289
+
290
+ export type AppRouter = typeof appRouter;
291
+ ```
292
+
293
+ ### Client Usage (Server Component)
294
+
295
+ ```tsx
296
+ // app/users/page.tsx
297
+ import { api } from '@/lib/trpc/server';
298
+
299
+ export default async function UsersPage() {
300
+ const users = await api.user.list();
301
+
302
+ return (
303
+ <div>
304
+ {users.map(user => (
305
+ <div key={user.id}>{user.name}</div>
306
+ ))}
307
+ </div>
308
+ );
309
+ }
310
+ ```
311
+
312
+ ### Client Usage (Client Component)
313
+
314
+ ```tsx
315
+ 'use client';
316
+
317
+ import { api } from '@/lib/trpc/client';
318
+
319
+ export function UserForm() {
320
+ const utils = api.useUtils();
321
+ const createUser = api.user.create.useMutation({
322
+ onSuccess: () => {
323
+ utils.user.list.invalidate();
324
+ },
325
+ });
326
+
327
+ const handleSubmit = (data: { name: string; email: string }) => {
328
+ createUser.mutate(data);
329
+ };
330
+
331
+ return <form>...</form>;
332
+ }
333
+ ```
334
+
335
+ ### tRPC Best Practices
336
+
337
+ ```typescript
338
+ // ✅ Good - type-safe inputs with Zod
339
+ .input(z.object({ email: z.string().email() }))
340
+
341
+ // ✅ Good - structured routers
342
+ export const appRouter = t.router({
343
+ user: userRouter,
344
+ post: postRouter,
345
+ comment: commentRouter,
346
+ });
347
+
348
+ // ✅ Good - error handling
349
+ .mutation(async ({ input }) => {
350
+ try {
351
+ return await prisma.user.create({ data: input });
352
+ } catch (error) {
353
+ throw new TRPCError({ code: 'INTERNAL_SERVER_ERROR', message: 'Failed to create user' });
354
+ }
355
+ })
356
+
357
+ // ❌ Bad - no input validation
358
+ .mutation(async ({ input }) => {
359
+ return prisma.user.create({ data: input as any });
360
+ })
361
+ ```
362
+
363
+ ## Prisma 5.24
364
+
365
+ ### Schema Design
366
+
367
+ ```prisma
368
+ // packages/database/prisma/schema.prisma
369
+ generator client {
370
+ provider = "prisma-client-js"
371
+ }
372
+
373
+ datasource db {
374
+ provider = "postgresql"
375
+ url = env("DATABASE_URL")
376
+ }
377
+
378
+ model User {
379
+ id String @id @default(cuid())
380
+ email String @unique
381
+ name String?
382
+ createdAt DateTime @default(now())
383
+ updatedAt DateTime @updatedAt
384
+
385
+ posts Post[]
386
+ profile Profile?
387
+
388
+ @@index([email])
389
+ @@map("users")
390
+ }
391
+
392
+ model Post {
393
+ id String @id @default(cuid())
394
+ title String
395
+ content String?
396
+ published Boolean @default(false)
397
+ authorId String
398
+
399
+ author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
400
+
401
+ @@index([authorId])
402
+ @@map("posts")
403
+ }
404
+
405
+ model Profile {
406
+ id String @id @default(cuid())
407
+ bio String?
408
+ userId String @unique
409
+
410
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
411
+
412
+ @@map("profiles")
413
+ }
414
+ ```
415
+
416
+ ### Migrations
417
+
418
+ ```bash
419
+ # Create migration
420
+ pnpm --filter database prisma migrate dev --name add_user_model
421
+
422
+ # Apply migrations in production
423
+ pnpm --filter database prisma migrate deploy
424
+
425
+ # Reset database (development only!)
426
+ pnpm --filter database prisma migrate reset
427
+
428
+ # Generate Prisma Client
429
+ pnpm --filter database prisma generate
430
+ ```
431
+
432
+ ### Prisma Client Usage
433
+
434
+ ```typescript
435
+ // packages/database/src/index.ts
436
+ import { PrismaClient } from '@prisma/client';
437
+
438
+ export const prisma = new PrismaClient();
439
+
440
+ // CRUD operations
441
+ export async function createUser(data: { email: string; name: string }) {
442
+ return prisma.user.create({ data });
443
+ }
444
+
445
+ export async function getUsers() {
446
+ return prisma.user.findMany({
447
+ include: {
448
+ posts: true,
449
+ profile: true,
450
+ },
451
+ });
452
+ }
453
+
454
+ export async function updateUser(id: string, data: { name?: string }) {
455
+ return prisma.user.update({
456
+ where: { id },
457
+ data,
458
+ });
459
+ }
460
+
461
+ export async function deleteUser(id: string) {
462
+ return prisma.user.delete({ where: { id } });
463
+ }
464
+ ```
465
+
466
+ ### Transactions
467
+
468
+ ```typescript
469
+ const [user, profile] = await prisma.$transaction([
470
+ prisma.user.create({ data: { email: 'test@example.com' } }),
471
+ prisma.profile.create({ data: { bio: 'Hello', userId: '...' } }),
472
+ ]);
473
+
474
+ // Or interactive transactions
475
+ await prisma.$transaction(async (tx) => {
476
+ const user = await tx.user.create({ data: { email: 'test@example.com' } });
477
+ await tx.profile.create({ data: { bio: 'Hello', userId: user.id } });
478
+ });
479
+ ```
480
+
481
+ ## Tailwind CSS v4
482
+
483
+ ### Configuration
484
+
485
+ ```javascript
486
+ // packages/config/tailwind/tailwind.config.js
487
+ export default {
488
+ content: [
489
+ './app/**/*.{ts,tsx}',
490
+ './components/**/*.{ts,tsx}',
491
+ '../../packages/ui/src/**/*.{ts,tsx}',
492
+ ],
493
+ theme: {
494
+ extend: {
495
+ colors: {
496
+ brand: {
497
+ 50: '#f0f9ff',
498
+ 500: '#0ea5e9',
499
+ 900: '#0c4a6e',
500
+ },
501
+ },
502
+ },
503
+ },
504
+ plugins: [],
505
+ };
506
+ ```
507
+
508
+ ### Usage with shadcn/ui
509
+
510
+ ```tsx
511
+ import { Button } from '@repo/ui/button';
512
+ import { Card, CardContent, CardHeader, CardTitle } from '@repo/ui/card';
513
+
514
+ export function UserCard({ user }: { user: User }) {
515
+ return (
516
+ <Card>
517
+ <CardHeader>
518
+ <CardTitle>{user.name}</CardTitle>
519
+ </CardHeader>
520
+ <CardContent>
521
+ <p className="text-sm text-muted-foreground">{user.email}</p>
522
+ <Button variant="outline" className="mt-4">
523
+ Edit Profile
524
+ </Button>
525
+ </CardContent>
526
+ </Card>
527
+ );
528
+ }
529
+ ```
530
+
531
+ ### Custom Classes
532
+
533
+ ```tsx
534
+ // ✅ Good - utility classes
535
+ <div className="flex items-center gap-4 p-4 rounded-lg bg-slate-100">
536
+ <Avatar src={user.avatar} />
537
+ <div className="flex-1">
538
+ <h3 className="font-semibold text-lg">{user.name}</h3>
539
+ <p className="text-sm text-gray-600">{user.bio}</p>
540
+ </div>
541
+ </div>
542
+
543
+ // ✅ Good - responsive design
544
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
545
+ {items.map(item => <Card key={item.id}>{item.name}</Card>)}
546
+ </div>
547
+
548
+ // ❌ Bad - inline styles (defeats Tailwind's purpose)
549
+ <div style={{ display: 'flex', padding: '16px' }}>...</div>
550
+ ```
551
+
552
+ ## Storybook
553
+
554
+ ### Story Structure
555
+
556
+ ```tsx
557
+ // packages/ui/stories/Button.stories.tsx
558
+ import type { Meta, StoryObj } from '@storybook/react';
559
+ import { Button } from '../src/button';
560
+
561
+ const meta: Meta<typeof Button> = {
562
+ title: 'Components/Button',
563
+ component: Button,
564
+ tags: ['autodocs'],
565
+ argTypes: {
566
+ variant: {
567
+ control: 'select',
568
+ options: ['default', 'outline', 'ghost'],
569
+ },
570
+ },
571
+ };
572
+
573
+ export default meta;
574
+ type Story = StoryObj<typeof Button>;
575
+
576
+ export const Default: Story = {
577
+ args: {
578
+ children: 'Click me',
579
+ },
580
+ };
581
+
582
+ export const Outline: Story = {
583
+ args: {
584
+ variant: 'outline',
585
+ children: 'Outline button',
586
+ },
587
+ };
588
+
589
+ export const WithIcon: Story = {
590
+ args: {
591
+ children: (
592
+ <>
593
+ <Icon /> Send
594
+ </>
595
+ ),
596
+ },
597
+ };
598
+ ```
599
+
600
+ ### Running Storybook
601
+
602
+ ```bash
603
+ # Start Storybook dev server
604
+ pnpm --filter ui storybook
605
+
606
+ # Build static Storybook
607
+ pnpm --filter ui build-storybook
608
+ ```
609
+
610
+ ## Vitest
611
+
612
+ ### Test Setup
613
+
614
+ ```typescript
615
+ // packages/ui/vitest.config.ts
616
+ import { defineConfig } from 'vitest/config';
617
+ import react from '@vitejs/plugin-react';
618
+
619
+ export default defineConfig({
620
+ plugins: [react()],
621
+ test: {
622
+ environment: 'jsdom',
623
+ globals: true,
624
+ setupFiles: './tests/setup.ts',
625
+ coverage: {
626
+ provider: 'v8',
627
+ reporter: ['text', 'json', 'html'],
628
+ exclude: ['**/*.stories.tsx', '**/*.config.*'],
629
+ },
630
+ },
631
+ });
632
+ ```
633
+
634
+ ### Component Tests
635
+
636
+ ```typescript
637
+ // packages/ui/src/button.test.tsx
638
+ import { render, screen } from '@testing-library/react';
639
+ import { userEvent } from '@testing-library/user-event';
640
+ import { describe, it, expect, vi } from 'vitest';
641
+ import { Button } from './button';
642
+
643
+ describe('Button', () => {
644
+ it('renders with text', () => {
645
+ render(<Button>Click me</Button>);
646
+ expect(screen.getByRole('button')).toHaveTextContent('Click me');
647
+ });
648
+
649
+ it('calls onClick when clicked', async () => {
650
+ const handleClick = vi.fn();
651
+ render(<Button onClick={handleClick}>Click</Button>);
652
+
653
+ await userEvent.click(screen.getByRole('button'));
654
+ expect(handleClick).toHaveBeenCalledOnce();
655
+ });
656
+
657
+ it('applies variant class', () => {
658
+ const { container } = render(<Button variant="outline">Button</Button>);
659
+ expect(container.firstChild).toHaveClass('btn-outline');
660
+ });
661
+ });
662
+ ```
663
+
664
+ ### Running Tests
665
+
666
+ ```bash
667
+ # Run all tests
668
+ pnpm test
669
+
670
+ # Run tests in watch mode
671
+ pnpm test:watch
672
+
673
+ # Run tests with coverage
674
+ pnpm test:coverage
675
+
676
+ # Run specific package tests
677
+ pnpm --filter ui test
678
+ ```
679
+
680
+ ## Turbo
681
+
682
+ ### Pipeline Configuration
683
+
684
+ ```json
685
+ // turbo.json
686
+ {
687
+ "pipeline": {
688
+ "build": {
689
+ "dependsOn": ["^build"],
690
+ "outputs": [".next/**", "dist/**", "build/**"]
691
+ },
692
+ "test": {
693
+ "dependsOn": ["build"],
694
+ "outputs": ["coverage/**"]
695
+ },
696
+ "lint": {
697
+ "outputs": []
698
+ },
699
+ "dev": {
700
+ "cache": false,
701
+ "persistent": true
702
+ }
703
+ }
704
+ }
705
+ ```
706
+
707
+ ### Running Tasks
708
+
709
+ ```bash
710
+ # Build all packages
711
+ turbo build
712
+
713
+ # Build with dependencies
714
+ turbo build --filter=web...
715
+
716
+ # Run in parallel
717
+ turbo build test lint
718
+
719
+ # Clear cache
720
+ turbo build --force
721
+
722
+ # See what would run
723
+ turbo build --dry-run
724
+ ```
725
+
726
+ ### Task Dependencies
727
+
728
+ ```json
729
+ {
730
+ "scripts": {
731
+ "build": "turbo build",
732
+ "dev": "turbo dev",
733
+ "test": "turbo test",
734
+ "lint": "turbo lint"
735
+ }
736
+ }
737
+
738
+ // turbo automatically:
739
+ // - Builds dependencies first (^build)
740
+ // - Caches outputs
741
+ // - Runs tasks in parallel when possible
742
+ ```
743
+
744
+ ## NextAuth v5
745
+
746
+ ### Configuration
747
+
748
+ ```typescript
749
+ // packages/auth/src/index.ts
750
+ import NextAuth from 'next-auth';
751
+ import { PrismaAdapter } from '@auth/prisma-adapter';
752
+ import { prisma } from '@repo/database';
753
+ import Credentials from 'next-auth/providers/credentials';
754
+
755
+ export const { handlers, auth, signIn, signOut } = NextAuth({
756
+ adapter: PrismaAdapter(prisma),
757
+ providers: [
758
+ Credentials({
759
+ credentials: {
760
+ email: { label: 'Email', type: 'email' },
761
+ password: { label: 'Password', type: 'password' },
762
+ },
763
+ authorize: async (credentials) => {
764
+ const user = await prisma.user.findUnique({
765
+ where: { email: credentials.email },
766
+ });
767
+
768
+ if (user && await verifyPassword(credentials.password, user.password)) {
769
+ return user;
770
+ }
771
+ return null;
772
+ },
773
+ }),
774
+ ],
775
+ session: {
776
+ strategy: 'jwt',
777
+ },
778
+ pages: {
779
+ signIn: '/login',
780
+ },
781
+ });
782
+ ```
783
+
784
+ ### Usage in App Router
785
+
786
+ ```tsx
787
+ // app/api/auth/[...nextauth]/route.ts
788
+ export { handlers as GET, handlers as POST } from '@repo/auth';
789
+
790
+ // app/dashboard/page.tsx
791
+ import { auth } from '@repo/auth';
792
+ import { redirect } from 'next/navigation';
793
+
794
+ export default async function DashboardPage() {
795
+ const session = await auth();
796
+
797
+ if (!session) {
798
+ redirect('/login');
799
+ }
800
+
801
+ return <div>Welcome, {session.user.name}</div>;
802
+ }
803
+ ```
804
+
805
+ ### Client-Side Session
806
+
807
+ ```tsx
808
+ 'use client';
809
+
810
+ import { useSession } from 'next-auth/react';
811
+
812
+ export function UserNav() {
813
+ const { data: session, status } = useSession();
814
+
815
+ if (status === 'loading') {
816
+ return <div>Loading...</div>;
817
+ }
818
+
819
+ if (!session) {
820
+ return <a href="/login">Sign in</a>;
821
+ }
822
+
823
+ return <div>Hello, {session.user.name}</div>;
824
+ }
825
+ ```
826
+
827
+ ## pnpm Workspaces
828
+
829
+ ### Workspace Configuration
830
+
831
+ ```yaml
832
+ # pnpm-workspace.yaml
833
+ packages:
834
+ - 'apps/*'
835
+ - 'packages/*'
836
+ ```
837
+
838
+ ### Package Dependencies
839
+
840
+ ```json
841
+ // apps/web/package.json
842
+ {
843
+ "name": "web",
844
+ "dependencies": {
845
+ "@repo/ui": "workspace:*",
846
+ "@repo/database": "workspace:*",
847
+ "@repo/trpc": "workspace:*",
848
+ "next": "15.0.0"
849
+ }
850
+ }
851
+ ```
852
+
853
+ ### pnpm Commands
854
+
855
+ ```bash
856
+ # Install all dependencies
857
+ pnpm install
858
+
859
+ # Add dependency to specific package
860
+ pnpm --filter web add react-query
861
+
862
+ # Add dependency to all packages
863
+ pnpm --filter "**" add -D typescript
864
+
865
+ # Run command in specific package
866
+ pnpm --filter database prisma generate
867
+
868
+ # Run command in all packages
869
+ pnpm --recursive test
870
+
871
+ # Update dependencies
872
+ pnpm update --latest
873
+ ```
874
+
875
+ ## Common Patterns
876
+
877
+ ### Data Fetching Pattern
878
+
879
+ ```tsx
880
+ // Server Component (app/users/page.tsx)
881
+ import { api } from '@/lib/trpc/server';
882
+
883
+ export default async function UsersPage() {
884
+ const users = await api.user.list();
885
+
886
+ return <UserList initialUsers={users} />;
887
+ }
888
+
889
+ // Client Component (components/UserList.tsx)
890
+ 'use client';
891
+
892
+ export function UserList({ initialUsers }: { initialUsers: User[] }) {
893
+ const { data: users } = api.user.list.useQuery(undefined, {
894
+ initialData: initialUsers,
895
+ refetchOnMount: false,
896
+ });
897
+
898
+ return <div>{users.map(u => <UserCard key={u.id} user={u} />)}</div>;
899
+ }
900
+ ```
901
+
902
+ ### Form Handling
903
+
904
+ ```tsx
905
+ 'use client';
906
+
907
+ import { useForm } from 'react-hook-form';
908
+ import { zodResolver } from '@hookform/resolvers/zod';
909
+ import { z } from 'zod';
910
+ import { api } from '@/lib/trpc/client';
911
+
912
+ const schema = z.object({
913
+ name: z.string().min(2),
914
+ email: z.string().email(),
915
+ });
916
+
917
+ export function UserForm() {
918
+ const form = useForm({
919
+ resolver: zodResolver(schema),
920
+ });
921
+
922
+ const createUser = api.user.create.useMutation();
923
+
924
+ const onSubmit = form.handleSubmit((data) => {
925
+ createUser.mutate(data);
926
+ });
927
+
928
+ return <form onSubmit={onSubmit}>...</form>;
929
+ }
930
+ ```
931
+
932
+ ### Protected Routes
933
+
934
+ ```tsx
935
+ // middleware.ts
936
+ import { auth } from '@repo/auth';
937
+ import { NextResponse } from 'next/server';
938
+
939
+ export default auth((req) => {
940
+ const isAuthenticated = !!req.auth;
941
+ const isProtectedRoute = req.nextUrl.pathname.startsWith('/dashboard');
942
+
943
+ if (isProtectedRoute && !isAuthenticated) {
944
+ return NextResponse.redirect(new URL('/login', req.url));
945
+ }
946
+ });
947
+ ```
948
+
949
+ ## Performance Optimization
950
+
951
+ ### Code Splitting
952
+
953
+ ```tsx
954
+ // Lazy load heavy components
955
+ import dynamic from 'next/dynamic';
956
+
957
+ const HeavyChart = dynamic(() => import('@/components/Chart'), {
958
+ loading: () => <div>Loading chart...</div>,
959
+ ssr: false, // Don't render on server
960
+ });
961
+ ```
962
+
963
+ ### Image Optimization
964
+
965
+ ```tsx
966
+ import Image from 'next/image';
967
+
968
+ <Image
969
+ src="/avatar.jpg"
970
+ width={200}
971
+ height={200}
972
+ alt="User avatar"
973
+ priority // Load immediately
974
+ />
975
+ ```
976
+
977
+ ### Caching
978
+
979
+ ```tsx
980
+ // Static rendering (default for server components)
981
+ export default async function Page() {
982
+ const data = await fetch('https://api.example.com/data', {
983
+ next: { revalidate: 3600 }, // Revalidate every hour
984
+ });
985
+ return <div>{data}</div>;
986
+ }
987
+
988
+ // Dynamic rendering
989
+ export const dynamic = 'force-dynamic';
990
+ ```
991
+
992
+ ## When to Use This Skill
993
+
994
+ - Building features in Next.js + tRPC + Prisma stack
995
+ - Setting up monorepo packages and dependencies
996
+ - Writing type-safe APIs with tRPC
997
+ - Designing database schemas with Prisma
998
+ - Creating reusable UI components with Storybook
999
+ - Testing React components with Vitest
1000
+ - Configuring Turbo pipelines
1001
+ - Implementing authentication with NextAuth
1002
+
1003
+ ## Related Skills
1004
+
1005
+ - `test-first-methodology.md` - TDD/BDD with Vitest
1006
+ - `api-design-patterns.md` - tRPC router design
1007
+ - `component-architecture.md` - React patterns
1008
+ - `security-best-practices.md` - NextAuth security
1009
+
1010
+ ## Key Takeaways
1011
+
1012
+ 1. **Server Components First** - Use server components by default, client components when needed
1013
+ 2. **Type Safety Everywhere** - tRPC + Prisma + TypeScript = end-to-end type safety
1014
+ 3. **Monorepo Benefits** - Shared packages, consistent tooling, faster builds with Turbo
1015
+ 4. **Test Before Deploy** - Vitest + React Testing Library for comprehensive coverage
1016
+ 5. **Performance by Default** - Next.js optimizations (images, fonts, code splitting)
1017
+ 6. **Database Type Safety** - Prisma generates types from schema automatically