@mars-stack/core 0.4.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 (192) hide show
  1. package/README.md +32 -0
  2. package/cursor/manifest.json +304 -0
  3. package/cursor/rules/mars-composition-patterns.mdc +186 -0
  4. package/cursor/rules/mars-data-access.mdc +26 -0
  5. package/cursor/rules/mars-project-structure.mdc +34 -0
  6. package/cursor/rules/mars-security.mdc +25 -0
  7. package/cursor/rules/mars-testing.mdc +24 -0
  8. package/cursor/rules/mars-ui-conventions.mdc +29 -0
  9. package/cursor/skills/mars-add-api-route/SKILL.md +120 -0
  10. package/cursor/skills/mars-add-audit-log/SKILL.md +373 -0
  11. package/cursor/skills/mars-add-blog/SKILL.md +447 -0
  12. package/cursor/skills/mars-add-command-palette/SKILL.md +438 -0
  13. package/cursor/skills/mars-add-component/SKILL.md +158 -0
  14. package/cursor/skills/mars-add-crud-routes/SKILL.md +221 -0
  15. package/cursor/skills/mars-add-e2e-test/SKILL.md +227 -0
  16. package/cursor/skills/mars-add-error-boundary/SKILL.md +472 -0
  17. package/cursor/skills/mars-add-feature/SKILL.md +174 -0
  18. package/cursor/skills/mars-add-middleware/SKILL.md +135 -0
  19. package/cursor/skills/mars-add-page/SKILL.md +153 -0
  20. package/cursor/skills/mars-add-prisma-model/SKILL.md +148 -0
  21. package/cursor/skills/mars-add-protected-resource/SKILL.md +192 -0
  22. package/cursor/skills/mars-add-role/SKILL.md +156 -0
  23. package/cursor/skills/mars-add-server-action/SKILL.md +167 -0
  24. package/cursor/skills/mars-add-webhook/SKILL.md +192 -0
  25. package/cursor/skills/mars-build-complete-feature/SKILL.md +228 -0
  26. package/cursor/skills/mars-build-dashboard/SKILL.md +211 -0
  27. package/cursor/skills/mars-build-data-table/SKILL.md +284 -0
  28. package/cursor/skills/mars-build-form/SKILL.md +229 -0
  29. package/cursor/skills/mars-build-landing-page/SKILL.md +248 -0
  30. package/cursor/skills/mars-capture-conversation-context/SKILL.md +119 -0
  31. package/cursor/skills/mars-configure-ai/SKILL.md +617 -0
  32. package/cursor/skills/mars-configure-analytics/SKILL.md +413 -0
  33. package/cursor/skills/mars-configure-dark-mode/SKILL.md +309 -0
  34. package/cursor/skills/mars-configure-email/SKILL.md +170 -0
  35. package/cursor/skills/mars-configure-email-verification/SKILL.md +333 -0
  36. package/cursor/skills/mars-configure-feature-flags/SKILL.md +361 -0
  37. package/cursor/skills/mars-configure-i18n/SKILL.md +518 -0
  38. package/cursor/skills/mars-configure-jobs/SKILL.md +500 -0
  39. package/cursor/skills/mars-configure-magic-links/SKILL.md +385 -0
  40. package/cursor/skills/mars-configure-multi-tenancy/SKILL.md +611 -0
  41. package/cursor/skills/mars-configure-notifications/SKILL.md +569 -0
  42. package/cursor/skills/mars-configure-oauth/SKILL.md +217 -0
  43. package/cursor/skills/mars-configure-onboarding/SKILL.md +483 -0
  44. package/cursor/skills/mars-configure-payments/SKILL.md +243 -0
  45. package/cursor/skills/mars-configure-realtime/SKILL.md +733 -0
  46. package/cursor/skills/mars-configure-search/SKILL.md +581 -0
  47. package/cursor/skills/mars-configure-storage/SKILL.md +273 -0
  48. package/cursor/skills/mars-configure-two-factor/SKILL.md +518 -0
  49. package/cursor/skills/mars-create-execution-plan/SKILL.md +204 -0
  50. package/cursor/skills/mars-create-seed/SKILL.md +191 -0
  51. package/cursor/skills/mars-deploy-to-vercel/SKILL.md +300 -0
  52. package/cursor/skills/mars-design-tokens/SKILL.md +138 -0
  53. package/cursor/skills/mars-setup-billing/SKILL.md +322 -0
  54. package/cursor/skills/mars-setup-project/SKILL.md +104 -0
  55. package/cursor/skills/mars-setup-teams/SKILL.md +688 -0
  56. package/cursor/skills/mars-test-api-route/SKILL.md +219 -0
  57. package/cursor/skills/mars-update-architecture-docs/SKILL.md +189 -0
  58. package/dist/api-error/index.d.ts +27 -0
  59. package/dist/api-error/index.d.ts.map +1 -0
  60. package/dist/api-error/index.js +2 -0
  61. package/dist/auth/credential-tag.d.ts +5 -0
  62. package/dist/auth/credential-tag.d.ts.map +1 -0
  63. package/dist/auth/credential-tag.js +2 -0
  64. package/dist/auth/crypto-utils.d.ts +43 -0
  65. package/dist/auth/crypto-utils.d.ts.map +1 -0
  66. package/dist/auth/crypto-utils.js +1 -0
  67. package/dist/auth/csrf.d.ts +32 -0
  68. package/dist/auth/csrf.d.ts.map +1 -0
  69. package/dist/auth/csrf.js +2 -0
  70. package/dist/auth/hooks/index.d.ts +4 -0
  71. package/dist/auth/hooks/index.d.ts.map +1 -0
  72. package/dist/auth/hooks/index.js +68 -0
  73. package/dist/auth/hooks/useCSRF.d.ts +7 -0
  74. package/dist/auth/hooks/useCSRF.d.ts.map +1 -0
  75. package/dist/auth/hooks/usePasswordStrength.d.ts +17 -0
  76. package/dist/auth/hooks/usePasswordStrength.d.ts.map +1 -0
  77. package/dist/auth/internal-api-key.d.ts +5 -0
  78. package/dist/auth/internal-api-key.d.ts.map +1 -0
  79. package/dist/auth/internal-api-key.js +30 -0
  80. package/dist/auth/link-utils.d.ts +13 -0
  81. package/dist/auth/link-utils.d.ts.map +1 -0
  82. package/dist/auth/link-utils.js +1 -0
  83. package/dist/auth/middleware.d.ts +56 -0
  84. package/dist/auth/middleware.d.ts.map +1 -0
  85. package/dist/auth/middleware.js +3 -0
  86. package/dist/auth/password.d.ts +28 -0
  87. package/dist/auth/password.d.ts.map +1 -0
  88. package/dist/auth/password.js +1 -0
  89. package/dist/auth/reset-token.d.ts +3 -0
  90. package/dist/auth/reset-token.d.ts.map +1 -0
  91. package/dist/auth/reset-token.js +9 -0
  92. package/dist/auth/responses.d.ts +15 -0
  93. package/dist/auth/responses.d.ts.map +1 -0
  94. package/dist/auth/responses.js +2 -0
  95. package/dist/auth/session.d.ts +79 -0
  96. package/dist/auth/session.d.ts.map +1 -0
  97. package/dist/auth/session.js +1 -0
  98. package/dist/auth/types.d.ts +18 -0
  99. package/dist/auth/types.d.ts.map +1 -0
  100. package/dist/auth/types.js +10 -0
  101. package/dist/auth/validation.d.ts +146 -0
  102. package/dist/auth/validation.d.ts.map +1 -0
  103. package/dist/auth/validation.js +116 -0
  104. package/dist/auth/validators.d.ts +4 -0
  105. package/dist/auth/validators.d.ts.map +1 -0
  106. package/dist/auth/validators.js +27 -0
  107. package/dist/auth/verification.d.ts +54 -0
  108. package/dist/auth/verification.d.ts.map +1 -0
  109. package/dist/auth/verification.js +39 -0
  110. package/dist/chunk-4LS3QDD5.js +162 -0
  111. package/dist/chunk-ABBUHT5Z.js +110 -0
  112. package/dist/chunk-CTYAVMOF.js +15 -0
  113. package/dist/chunk-GVLH2GQP.js +14 -0
  114. package/dist/chunk-HOSMMQMA.js +109 -0
  115. package/dist/chunk-MXQ66RUN.js +28 -0
  116. package/dist/chunk-PZE3JGXO.js +149 -0
  117. package/dist/chunk-QAH2Y5WK.js +93 -0
  118. package/dist/chunk-QWMN5UJC.js +76 -0
  119. package/dist/chunk-ROQV54MU.js +117 -0
  120. package/dist/chunk-U4NZQ366.js +46 -0
  121. package/dist/chunk-WBJOIENS.js +22 -0
  122. package/dist/chunk-WO6FHJHG.js +29 -0
  123. package/dist/chunk-Z5BEKPJI.js +96 -0
  124. package/dist/chunk-ZA46T6GX.js +24 -0
  125. package/dist/configure-mars.d.ts +104 -0
  126. package/dist/configure-mars.d.ts.map +1 -0
  127. package/dist/database/index.d.ts +8 -0
  128. package/dist/database/index.d.ts.map +1 -0
  129. package/dist/database/index.js +1 -0
  130. package/dist/email/index.d.ts +25 -0
  131. package/dist/email/index.d.ts.map +1 -0
  132. package/dist/email/index.js +2 -0
  133. package/dist/email/types.d.ts +18 -0
  134. package/dist/email/types.d.ts.map +1 -0
  135. package/dist/env/index.d.ts +36 -0
  136. package/dist/env/index.d.ts.map +1 -0
  137. package/dist/env/index.js +1 -0
  138. package/dist/index.d.ts +6 -0
  139. package/dist/index.d.ts.map +1 -0
  140. package/dist/index.js +163 -0
  141. package/dist/logger/index.d.ts +80 -0
  142. package/dist/logger/index.d.ts.map +1 -0
  143. package/dist/logger/index.js +1 -0
  144. package/dist/payments/index.d.ts +53 -0
  145. package/dist/payments/index.d.ts.map +1 -0
  146. package/dist/payments/index.js +72 -0
  147. package/dist/plugin/builtin/email-plugins.d.ts +10 -0
  148. package/dist/plugin/builtin/email-plugins.d.ts.map +1 -0
  149. package/dist/plugin/builtin/index.d.ts +4 -0
  150. package/dist/plugin/builtin/index.d.ts.map +1 -0
  151. package/dist/plugin/builtin/index.js +324 -0
  152. package/dist/plugin/builtin/payment-plugins.d.ts +4 -0
  153. package/dist/plugin/builtin/payment-plugins.d.ts.map +1 -0
  154. package/dist/plugin/builtin/storage-plugins.d.ts +5 -0
  155. package/dist/plugin/builtin/storage-plugins.d.ts.map +1 -0
  156. package/dist/plugin/index.d.ts +21 -0
  157. package/dist/plugin/index.d.ts.map +1 -0
  158. package/dist/plugin/index.js +30 -0
  159. package/dist/rate-limit/index.d.ts +89 -0
  160. package/dist/rate-limit/index.d.ts.map +1 -0
  161. package/dist/rate-limit/index.js +166 -0
  162. package/dist/seo/faq.d.ts +37 -0
  163. package/dist/seo/faq.d.ts.map +1 -0
  164. package/dist/seo/index.d.ts +75 -0
  165. package/dist/seo/index.d.ts.map +1 -0
  166. package/dist/seo/index.js +1 -0
  167. package/dist/storage/index.d.ts +50 -0
  168. package/dist/storage/index.d.ts.map +1 -0
  169. package/dist/storage/index.js +211 -0
  170. package/dist/test-utils/factories.d.ts +38 -0
  171. package/dist/test-utils/factories.d.ts.map +1 -0
  172. package/dist/test-utils/index.d.ts +6 -0
  173. package/dist/test-utils/index.d.ts.map +1 -0
  174. package/dist/test-utils/index.js +117 -0
  175. package/dist/test-utils/mock-auth.d.ts +25 -0
  176. package/dist/test-utils/mock-auth.d.ts.map +1 -0
  177. package/dist/test-utils/mock-prisma.d.ts +55 -0
  178. package/dist/test-utils/mock-prisma.d.ts.map +1 -0
  179. package/dist/test-utils/render.d.ts +4 -0
  180. package/dist/test-utils/render.d.ts.map +1 -0
  181. package/dist/test-utils/request-helpers.d.ts +6 -0
  182. package/dist/test-utils/request-helpers.d.ts.map +1 -0
  183. package/dist/types.d.ts +53 -0
  184. package/dist/types.d.ts.map +1 -0
  185. package/dist/utils/math.d.ts +2 -0
  186. package/dist/utils/math.d.ts.map +1 -0
  187. package/dist/utils/math.js +7 -0
  188. package/dist/utils/optional-import.d.ts +14 -0
  189. package/dist/utils/optional-import.d.ts.map +1 -0
  190. package/package.json +205 -0
  191. package/scripts/generate-skill-adapters.ts +146 -0
  192. package/scripts/postinstall.mjs +146 -0
package/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # @mars-stack/core
2
+
3
+ Core infrastructure for MARS apps -- auth, database, rate limiting, email, logging, and more.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ yarn add @mars-stack/core
9
+ ```
10
+
11
+ ## What's included
12
+
13
+ - **Auth** -- Session management (JWE), CSRF protection, password hashing (bcrypt + SHA-256 prehash), input validation
14
+ - **Database** -- Prisma proxy with structured error diagnostics
15
+ - **Rate limiting** -- Upstash Redis with in-memory fallback
16
+ - **Email** -- Provider-agnostic email service (SendGrid, Resend, console)
17
+ - **Logger** -- Structured logging via Pino
18
+ - **Env** -- Zod-based environment validation with human-readable errors
19
+ - **SEO** -- Metadata helpers and JSON-LD generation
20
+ - **Test utils** -- Mock factories, request helpers, render utilities
21
+
22
+ ## Usage
23
+
24
+ ```ts
25
+ import { checkRateLimit, RATE_LIMITS } from '@mars-stack/core/rate-limit';
26
+ import { hashPassword, verifyPassword } from '@mars-stack/core/auth/password';
27
+ import { apiSchemas } from '@mars-stack/core/auth/validation';
28
+ ```
29
+
30
+ ## License
31
+
32
+ MIT
@@ -0,0 +1,304 @@
1
+ {
2
+ "version": "1.0.0",
3
+ "description": "Mars skill manifest. Lists all available skills with triggers, dependencies, and capabilities.",
4
+ "skills": {
5
+ "add-api-route": {
6
+ "file": "skills/mars-add-api-route/SKILL.md",
7
+ "triggers": ["add api route", "create api endpoint", "new route handler"],
8
+ "dependencies": [],
9
+ "capabilities": ["file-edit"]
10
+ },
11
+ "add-component": {
12
+ "file": "skills/mars-add-component/SKILL.md",
13
+ "triggers": ["add component", "create component", "new component"],
14
+ "dependencies": [],
15
+ "capabilities": ["file-edit"]
16
+ },
17
+ "add-crud-routes": {
18
+ "file": "skills/mars-add-crud-routes/SKILL.md",
19
+ "triggers": ["add crud", "create crud routes", "add rest endpoints"],
20
+ "dependencies": ["add-api-route", "add-prisma-model"],
21
+ "capabilities": ["file-edit"]
22
+ },
23
+ "add-e2e-test": {
24
+ "file": "skills/mars-add-e2e-test/SKILL.md",
25
+ "triggers": ["add e2e test", "add playwright test", "add end to end test"],
26
+ "dependencies": [],
27
+ "capabilities": ["file-edit"]
28
+ },
29
+ "add-feature": {
30
+ "file": "skills/mars-add-feature/SKILL.md",
31
+ "triggers": ["add feature", "add module", "new feature"],
32
+ "dependencies": ["add-prisma-model", "add-api-route", "add-page"],
33
+ "capabilities": ["file-edit", "terminal"]
34
+ },
35
+ "add-middleware": {
36
+ "file": "skills/mars-add-middleware/SKILL.md",
37
+ "triggers": ["add middleware", "create middleware"],
38
+ "dependencies": [],
39
+ "capabilities": ["file-edit"]
40
+ },
41
+ "add-page": {
42
+ "file": "skills/mars-add-page/SKILL.md",
43
+ "triggers": ["add page", "create page", "new page"],
44
+ "dependencies": [],
45
+ "capabilities": ["file-edit"]
46
+ },
47
+ "add-prisma-model": {
48
+ "file": "skills/mars-add-prisma-model/SKILL.md",
49
+ "triggers": ["add model", "add prisma model", "create database model"],
50
+ "dependencies": [],
51
+ "capabilities": ["file-edit", "terminal"]
52
+ },
53
+ "add-protected-resource": {
54
+ "file": "skills/mars-add-protected-resource/SKILL.md",
55
+ "triggers": ["add protected resource", "add auth resource"],
56
+ "dependencies": ["add-api-route"],
57
+ "capabilities": ["file-edit"]
58
+ },
59
+ "add-role": {
60
+ "file": "skills/mars-add-role/SKILL.md",
61
+ "triggers": ["add role", "create role", "new user role"],
62
+ "dependencies": [],
63
+ "capabilities": ["file-edit"]
64
+ },
65
+ "add-server-action": {
66
+ "file": "skills/mars-add-server-action/SKILL.md",
67
+ "triggers": ["add server action", "create server action"],
68
+ "dependencies": [],
69
+ "capabilities": ["file-edit"]
70
+ },
71
+ "add-webhook": {
72
+ "file": "skills/mars-add-webhook/SKILL.md",
73
+ "triggers": ["add webhook", "create webhook endpoint"],
74
+ "dependencies": ["add-api-route"],
75
+ "capabilities": ["file-edit"]
76
+ },
77
+ "build-dashboard": {
78
+ "file": "skills/mars-build-dashboard/SKILL.md",
79
+ "triggers": ["build dashboard", "create dashboard"],
80
+ "dependencies": ["add-page"],
81
+ "capabilities": ["file-edit"]
82
+ },
83
+ "build-data-table": {
84
+ "file": "skills/mars-build-data-table/SKILL.md",
85
+ "triggers": ["build data table", "create table view", "add table"],
86
+ "dependencies": ["add-component"],
87
+ "capabilities": ["file-edit"]
88
+ },
89
+ "build-form": {
90
+ "file": "skills/mars-build-form/SKILL.md",
91
+ "triggers": ["build form", "create form", "add form"],
92
+ "dependencies": ["add-component"],
93
+ "capabilities": ["file-edit"]
94
+ },
95
+ "build-landing-page": {
96
+ "file": "skills/mars-build-landing-page/SKILL.md",
97
+ "triggers": ["build landing page", "create landing page", "homepage"],
98
+ "dependencies": ["add-page"],
99
+ "capabilities": ["file-edit"]
100
+ },
101
+ "configure-email": {
102
+ "file": "skills/mars-configure-email/SKILL.md",
103
+ "triggers": ["configure email", "setup email", "add email provider"],
104
+ "dependencies": [],
105
+ "capabilities": ["file-edit", "terminal"]
106
+ },
107
+ "configure-oauth": {
108
+ "file": "skills/mars-configure-oauth/SKILL.md",
109
+ "triggers": ["configure oauth", "add google login", "setup social auth"],
110
+ "dependencies": [],
111
+ "capabilities": ["file-edit", "terminal"]
112
+ },
113
+ "configure-ai": {
114
+ "file": "skills/mars-configure-ai/SKILL.md",
115
+ "triggers": ["configure ai", "add openai", "add anthropic", "setup llm", "add chatbot", "add embeddings"],
116
+ "dependencies": ["add-feature", "add-api-route"],
117
+ "capabilities": ["file-edit", "terminal"]
118
+ },
119
+ "configure-i18n": {
120
+ "file": "skills/mars-configure-i18n/SKILL.md",
121
+ "triggers": ["configure i18n", "add translations", "setup internationalization", "add multi-language", "add localization"],
122
+ "dependencies": [],
123
+ "capabilities": ["file-edit", "terminal"]
124
+ },
125
+ "configure-notifications": {
126
+ "file": "skills/mars-configure-notifications/SKILL.md",
127
+ "triggers": ["configure notifications", "add notifications", "add notification bell", "setup alerts", "add activity feed"],
128
+ "dependencies": ["add-feature", "add-api-route"],
129
+ "capabilities": ["file-edit", "terminal"]
130
+ },
131
+ "configure-jobs": {
132
+ "file": "skills/mars-configure-jobs/SKILL.md",
133
+ "triggers": ["configure jobs", "add background jobs", "setup task queue", "add cron jobs", "async processing"],
134
+ "dependencies": ["add-feature"],
135
+ "capabilities": ["file-edit", "terminal"]
136
+ },
137
+ "configure-multi-tenancy": {
138
+ "file": "skills/mars-configure-multi-tenancy/SKILL.md",
139
+ "triggers": ["configure multi-tenancy", "add organizations", "add teams", "add workspaces", "multi-tenant"],
140
+ "dependencies": ["add-feature", "add-prisma-model"],
141
+ "capabilities": ["file-edit", "terminal"]
142
+ },
143
+ "configure-payments": {
144
+ "file": "skills/mars-configure-payments/SKILL.md",
145
+ "triggers": ["configure payments", "add stripe", "setup billing"],
146
+ "dependencies": ["add-feature", "add-webhook"],
147
+ "capabilities": ["file-edit", "terminal"]
148
+ },
149
+ "configure-realtime": {
150
+ "file": "skills/mars-configure-realtime/SKILL.md",
151
+ "triggers": ["configure realtime", "add live updates", "add websockets", "add SSE", "add Pusher", "add Ably", "realtime notifications"],
152
+ "dependencies": ["add-feature"],
153
+ "capabilities": ["file-edit", "terminal"]
154
+ },
155
+ "configure-search": {
156
+ "file": "skills/mars-configure-search/SKILL.md",
157
+ "triggers": ["configure search", "add search", "setup full-text search", "add algolia", "add meilisearch"],
158
+ "dependencies": ["add-feature"],
159
+ "capabilities": ["file-edit", "terminal"]
160
+ },
161
+ "configure-storage": {
162
+ "file": "skills/mars-configure-storage/SKILL.md",
163
+ "triggers": ["configure storage", "add file upload", "setup blob storage"],
164
+ "dependencies": ["add-api-route"],
165
+ "capabilities": ["file-edit", "terminal"]
166
+ },
167
+ "create-seed": {
168
+ "file": "skills/mars-create-seed/SKILL.md",
169
+ "triggers": ["create seed", "add seed data", "database seed"],
170
+ "dependencies": [],
171
+ "capabilities": ["file-edit", "terminal"]
172
+ },
173
+ "design-tokens": {
174
+ "file": "skills/mars-design-tokens/SKILL.md",
175
+ "triggers": ["design tokens", "customize theme", "change colors", "brand colors"],
176
+ "dependencies": [],
177
+ "capabilities": ["file-edit"]
178
+ },
179
+ "setup-project": {
180
+ "file": "skills/mars-setup-project/SKILL.md",
181
+ "triggers": ["setup project", "initialize project", "get started"],
182
+ "dependencies": [],
183
+ "capabilities": ["file-edit", "terminal"]
184
+ },
185
+ "test-api-route": {
186
+ "file": "skills/mars-test-api-route/SKILL.md",
187
+ "triggers": ["test api route", "add api test", "test endpoint"],
188
+ "dependencies": [],
189
+ "capabilities": ["file-edit"]
190
+ },
191
+ "configure-email-verification": {
192
+ "file": "skills/mars-configure-email-verification/SKILL.md",
193
+ "triggers": ["configure email verification", "add email verification", "verify email", "resend verification"],
194
+ "dependencies": ["configure-email"],
195
+ "capabilities": ["file-edit", "terminal"]
196
+ },
197
+ "configure-magic-links": {
198
+ "file": "skills/mars-configure-magic-links/SKILL.md",
199
+ "triggers": ["configure magic links", "add passwordless login", "magic link auth", "email login"],
200
+ "dependencies": ["configure-email"],
201
+ "capabilities": ["file-edit", "terminal"]
202
+ },
203
+ "configure-two-factor": {
204
+ "file": "skills/mars-configure-two-factor/SKILL.md",
205
+ "triggers": ["configure 2fa", "add two-factor", "add totp", "add authenticator", "add backup codes"],
206
+ "dependencies": ["add-feature"],
207
+ "capabilities": ["file-edit", "terminal"]
208
+ },
209
+ "configure-dark-mode": {
210
+ "file": "skills/mars-configure-dark-mode/SKILL.md",
211
+ "triggers": ["configure dark mode", "add dark mode", "add theme toggle", "light dark switch"],
212
+ "dependencies": ["design-tokens"],
213
+ "capabilities": ["file-edit"]
214
+ },
215
+ "configure-onboarding": {
216
+ "file": "skills/mars-configure-onboarding/SKILL.md",
217
+ "triggers": ["configure onboarding", "add onboarding", "setup wizard", "welcome flow", "first-time user"],
218
+ "dependencies": ["add-feature", "add-prisma-model"],
219
+ "capabilities": ["file-edit", "terminal"]
220
+ },
221
+ "add-blog": {
222
+ "file": "skills/mars-add-blog/SKILL.md",
223
+ "triggers": ["add blog", "create blog", "add mdx blog", "add articles", "add posts"],
224
+ "dependencies": ["add-page"],
225
+ "capabilities": ["file-edit", "terminal"]
226
+ },
227
+ "configure-analytics": {
228
+ "file": "skills/mars-configure-analytics/SKILL.md",
229
+ "triggers": ["configure analytics", "add analytics", "add tracking", "add vercel analytics", "add posthog", "add google analytics"],
230
+ "dependencies": [],
231
+ "capabilities": ["file-edit", "terminal"]
232
+ },
233
+ "add-command-palette": {
234
+ "file": "skills/mars-add-command-palette/SKILL.md",
235
+ "triggers": ["add command palette", "add cmd k", "add spotlight", "add quick search", "add keyboard shortcuts"],
236
+ "dependencies": ["add-component"],
237
+ "capabilities": ["file-edit", "terminal"]
238
+ },
239
+ "configure-feature-flags": {
240
+ "file": "skills/mars-configure-feature-flags/SKILL.md",
241
+ "triggers": ["configure feature flags", "add feature toggles", "feature flags", "gradual rollout", "a/b testing"],
242
+ "dependencies": ["add-feature", "add-prisma-model"],
243
+ "capabilities": ["file-edit", "terminal"]
244
+ },
245
+ "add-audit-log": {
246
+ "file": "skills/mars-add-audit-log/SKILL.md",
247
+ "triggers": ["add audit log", "add activity tracking", "audit logging", "compliance logging"],
248
+ "dependencies": ["add-prisma-model", "add-api-route"],
249
+ "capabilities": ["file-edit", "terminal"]
250
+ },
251
+ "add-error-boundary": {
252
+ "file": "skills/mars-add-error-boundary/SKILL.md",
253
+ "triggers": ["add error boundary", "error handling", "add error page", "sentry integration", "global error handler"],
254
+ "dependencies": ["add-component"],
255
+ "capabilities": ["file-edit", "terminal"]
256
+ },
257
+ "deploy-to-vercel": {
258
+ "file": "skills/mars-deploy-to-vercel/SKILL.md",
259
+ "triggers": ["deploy to vercel", "vercel deployment", "deploy to production", "go live", "publish app"],
260
+ "dependencies": [],
261
+ "capabilities": ["terminal"]
262
+ },
263
+ "create-execution-plan": {
264
+ "file": "skills/mars-create-execution-plan/SKILL.md",
265
+ "triggers": ["create execution plan", "create plan", "plan work", "track progress"],
266
+ "dependencies": [],
267
+ "capabilities": ["file-edit"]
268
+ },
269
+ "update-architecture-docs": {
270
+ "file": "skills/mars-update-architecture-docs/SKILL.md",
271
+ "triggers": ["update docs", "update architecture", "sync docs", "update quality score", "refresh documentation"],
272
+ "dependencies": [],
273
+ "capabilities": ["file-edit"]
274
+ },
275
+ "build-complete-feature": {
276
+ "file": "skills/mars-build-complete-feature/SKILL.md",
277
+ "triggers": ["build complete feature", "add full feature", "build feature end to end", "implement feature"],
278
+ "dependencies": ["create-execution-plan", "add-prisma-model", "add-feature", "add-api-route", "add-crud-routes", "add-page", "test-api-route", "add-e2e-test", "update-architecture-docs"],
279
+ "capabilities": ["file-edit", "terminal"],
280
+ "meta": true
281
+ },
282
+ "setup-billing": {
283
+ "file": "skills/mars-setup-billing/SKILL.md",
284
+ "triggers": ["setup billing", "add subscriptions", "add paywall", "stripe end to end", "billing system"],
285
+ "dependencies": ["create-execution-plan", "configure-payments", "add-prisma-model", "add-webhook", "add-feature", "add-api-route", "add-page", "test-api-route", "update-architecture-docs"],
286
+ "capabilities": ["file-edit", "terminal"],
287
+ "meta": true
288
+ },
289
+ "setup-teams": {
290
+ "file": "skills/mars-setup-teams/SKILL.md",
291
+ "triggers": ["setup teams", "add organizations", "add team management", "multi-tenancy end to end", "org switching"],
292
+ "dependencies": ["create-execution-plan", "configure-multi-tenancy", "add-prisma-model", "add-feature", "add-crud-routes", "add-page", "test-api-route", "update-architecture-docs"],
293
+ "capabilities": ["file-edit", "terminal"],
294
+ "meta": true
295
+ },
296
+ "capture-conversation-context": {
297
+ "file": "skills/mars-capture-conversation-context/SKILL.md",
298
+ "triggers": ["capture context", "feed back", "save decisions", "document conversation", "end of session"],
299
+ "dependencies": ["create-execution-plan", "update-architecture-docs"],
300
+ "capabilities": ["file-edit"],
301
+ "meta": true
302
+ }
303
+ }
304
+ }
@@ -0,0 +1,186 @@
1
+ ---
2
+ description: React composition patterns — compound components, state lifting, explicit variants
3
+ globs: **/*.tsx
4
+ alwaysApply: false
5
+ ---
6
+
7
+ ## Composition Over Configuration
8
+
9
+ When building components, prefer composition over boolean props. These patterns apply to all feature components and any new primitives/patterns added to `@mars-stack/ui`.
10
+
11
+ Source: [Vercel Composition Patterns](https://github.com/vercel-labs/agent-skills/tree/main/skills/composition-patterns)
12
+
13
+ ## 1. No Boolean Prop Proliferation (CRITICAL)
14
+
15
+ Don't add boolean props like `isThread`, `isEditing`, `isCompact` to customise component behaviour. Each boolean doubles possible states and creates unmaintainable conditional logic.
16
+
17
+ **Wrong:**
18
+
19
+ ```tsx
20
+ function Composer({ isThread, isEditing, isForwarding, showAttachments }: Props) {
21
+ return (
22
+ <form>
23
+ <Input />
24
+ {isThread ? <ThreadField /> : isEditing ? <EditActions /> : <DefaultActions />}
25
+ {showAttachments && <Attachments />}
26
+ </form>
27
+ );
28
+ }
29
+ ```
30
+
31
+ **Right — create explicit variants that compose shared parts:**
32
+
33
+ ```tsx
34
+ function ThreadComposer({ channelId }: { channelId: string }) {
35
+ return (
36
+ <Composer.Frame>
37
+ <Composer.Input />
38
+ <AlsoSendToChannelField channelId={channelId} />
39
+ <Composer.Footer>
40
+ <Composer.Submit />
41
+ </Composer.Footer>
42
+ </Composer.Frame>
43
+ );
44
+ }
45
+
46
+ function EditComposer() {
47
+ return (
48
+ <Composer.Frame>
49
+ <Composer.Input />
50
+ <Composer.Footer>
51
+ <Composer.CancelEdit />
52
+ <Composer.SaveEdit />
53
+ </Composer.Footer>
54
+ </Composer.Frame>
55
+ );
56
+ }
57
+ ```
58
+
59
+ ## 2. Compound Components with Shared Context (HIGH)
60
+
61
+ Structure complex components as compound components. Subcomponents access shared state via context, not props. Consumers compose the pieces they need.
62
+
63
+ ```tsx
64
+ const ComposerContext = createContext<ComposerContextValue | null>(null);
65
+
66
+ function ComposerFrame({ children }: { children: React.ReactNode }) {
67
+ return <form>{children}</form>;
68
+ }
69
+
70
+ function ComposerInput() {
71
+ const { state, actions: { update } } = use(ComposerContext);
72
+ return <TextInput value={state.input} onChangeText={(text) => update((s) => ({ ...s, input: text }))} />;
73
+ }
74
+
75
+ const Composer = {
76
+ Frame: ComposerFrame,
77
+ Input: ComposerInput,
78
+ Submit: ComposerSubmit,
79
+ // ...
80
+ };
81
+ ```
82
+
83
+ Export compound components as a namespace object, not individual exports.
84
+
85
+ ## 3. Generic Context Interfaces (HIGH)
86
+
87
+ Define context with three parts: `state`, `actions`, `meta`. This interface is a contract that any provider can implement — enabling the same UI to work with different state implementations.
88
+
89
+ ```tsx
90
+ interface ComposerContextValue {
91
+ state: { input: string; attachments: Attachment[]; isSubmitting: boolean };
92
+ actions: { update: (updater: (s: State) => State) => void; submit: () => void };
93
+ meta: { inputRef: React.RefObject<HTMLTextAreaElement> };
94
+ }
95
+ ```
96
+
97
+ UI components consume the interface. Providers implement it. Swap the provider, keep the UI.
98
+
99
+ ## 4. Lift State into Providers (HIGH)
100
+
101
+ Move state into dedicated provider components. This lets sibling components outside the main UI access state without prop drilling.
102
+
103
+ **Wrong — state trapped in component:**
104
+
105
+ ```tsx
106
+ function ForwardDialog() {
107
+ return (
108
+ <Dialog>
109
+ <ForwardComposer />
110
+ <MessagePreview /> {/* Can't access composer state */}
111
+ <ForwardButton /> {/* Can't call submit */}
112
+ </Dialog>
113
+ );
114
+ }
115
+ ```
116
+
117
+ **Right — state in provider, UI siblings can access it:**
118
+
119
+ ```tsx
120
+ function ForwardDialog() {
121
+ return (
122
+ <ForwardProvider>
123
+ <Dialog>
124
+ <ForwardComposer />
125
+ <MessagePreview /> {/* Reads state from context */}
126
+ <ForwardButton /> {/* Calls submit from context */}
127
+ </Dialog>
128
+ </ForwardProvider>
129
+ );
130
+ }
131
+ ```
132
+
133
+ Components that need shared state don't have to be visually nested — they just need to be within the same provider.
134
+
135
+ ## 5. Decouple State from UI (MEDIUM)
136
+
137
+ The provider is the only place that knows how state is managed. UI components consume the context interface — they don't know if state comes from `useState`, Zustand, or a server sync.
138
+
139
+ ```tsx
140
+ // Local state provider
141
+ function ForwardProvider({ children }: { children: React.ReactNode }) {
142
+ const [state, setState] = useState(initialState);
143
+ return <Composer.Provider state={state} actions={{ update: setState, submit }}>{children}</Composer.Provider>;
144
+ }
145
+
146
+ // Global synced state provider — same UI works with both
147
+ function ChannelProvider({ channelId, children }: Props) {
148
+ const { state, update, submit } = useGlobalChannel(channelId);
149
+ return <Composer.Provider state={state} actions={{ update, submit }}>{children}</Composer.Provider>;
150
+ }
151
+ ```
152
+
153
+ ## 6. Children Over Render Props (MEDIUM)
154
+
155
+ Use `children` for composition. Use render props only when the parent needs to pass data back to the child (e.g., list items with index).
156
+
157
+ **Wrong:**
158
+
159
+ ```tsx
160
+ <Composer renderHeader={() => <Header />} renderFooter={() => <Footer />} />
161
+ ```
162
+
163
+ **Right:**
164
+
165
+ ```tsx
166
+ <Composer.Frame>
167
+ <Header />
168
+ <Composer.Input />
169
+ <Footer />
170
+ </Composer.Frame>
171
+ ```
172
+
173
+ ## 7. React 19 APIs
174
+
175
+ This project uses React 19. Follow these conventions:
176
+
177
+ - **No `forwardRef`** — `ref` is a regular prop in React 19.
178
+ - **Use `use()` instead of `useContext()`** — `use()` can be called conditionally.
179
+
180
+ ```tsx
181
+ // Right (React 19)
182
+ function ComposerInput({ ref, ...props }: Props & { ref?: React.Ref<HTMLTextAreaElement> }) {
183
+ const { state } = use(ComposerContext);
184
+ return <textarea ref={ref} value={state.input} {...props} />;
185
+ }
186
+ ```
@@ -0,0 +1,26 @@
1
+ ---
2
+ description: Database and data access patterns
3
+ globs: **/server/**
4
+ alwaysApply: false
5
+ ---
6
+
7
+ ## Prisma
8
+
9
+ - Import the lazy-loaded client: `import { prisma } from '@/lib/prisma'`.
10
+ - User-scoped queries MUST include `userId` from the authenticated session in the `where` clause, never from request parameters.
11
+ - Use `$transaction` for multi-step writes that must be atomic.
12
+ - New models go in `prisma/schema/` as separate `.prisma` files (multi-file schema).
13
+ - After changing the schema: `yarn db:push` (dev) or `yarn db:migrate dev` (with migration history).
14
+
15
+ ## Error Handling
16
+
17
+ - API route catch blocks MUST use `handleApiError(error, { endpoint })` from `@/lib/mars`.
18
+ - `handleApiError` automatically detects Prisma errors and logs actionable diagnostics (connection refused, auth failed, missing tables, SSL issues) to the terminal.
19
+ - Database errors return HTTP 503 to clients. Zod validation errors return 400. Everything else returns 500.
20
+ - Never expose raw database error messages to the client.
21
+
22
+ ## File Handling
23
+
24
+ - File proxy routes MUST stream `response.body` instead of buffering with `arrayBuffer()`.
25
+ - Enforce max file size checks from the DB record before fetching.
26
+ - Sanitize filenames in `Content-Disposition` headers.
@@ -0,0 +1,34 @@
1
+ ---
2
+ description: Project structure and import conventions
3
+ globs:
4
+ alwaysApply: true
5
+ ---
6
+
7
+ ## Directory Layout
8
+
9
+ - `src/lib/` -- Wiring layer: `mars.ts` (re-exports logger, email, api-error, auth middleware, session, CSRF from `@mars-stack/core`) and `prisma.ts` (database client).
10
+ - UI primitives (Button, Input, Select, etc.) and patterns (Card, Modal, FormField) come from the `@mars-stack/ui` package.
11
+ - Shared hooks come from `@mars-stack/ui/hooks`.
12
+ - `src/features/<name>/` -- Feature modules with their own `components/`, `server/`, `hooks/`, `validation/`.
13
+ - `src/config/` -- `app.config.ts` (single source of truth) and `routes.ts`.
14
+ - `src/styles/` -- Design tokens: `primitives.css` → `tokens.css` → `theme.css`.
15
+
16
+ ## Import Rules
17
+
18
+ - Use `@/lib/prisma` for the database client, `@/lib/mars` for core infrastructure (logger, email, api-error, auth wrappers, session, CSRF).
19
+ - Use `@mars-stack/ui` for UI primitives and patterns, `@mars-stack/ui/hooks` for shared hooks.
20
+ - Use `@mars-stack/core/rate-limit` for rate limiting, `@mars-stack/core/test-utils` for test utilities, `@mars-stack/core/auth/hooks` for auth hooks, `@mars-stack/core/auth/validation` for auth validation schemas.
21
+ - `features/` may import from `@/lib/`, `@mars-stack/*`, and `config/`. Features MUST NOT import from other features.
22
+ - `app/` may import from anywhere.
23
+
24
+ ## Naming
25
+
26
+ - Use named exports. Default exports only for Next.js pages/layouts.
27
+ - Prefer explicit TypeScript types. No `any` -- use `unknown` and narrow.
28
+ - Barrel exports (`index.ts`) at the boundary of each module for clean imports.
29
+
30
+ ## Config
31
+
32
+ - `app.config.ts` is the single source of truth for app identity, feature flags, theme, and service providers.
33
+ - Check `appConfig.features.*` before wiring up optional functionality.
34
+ - Environment variables are validated lazily via `src/core/env/`. Add new vars to `buildEnvSchema()`.
@@ -0,0 +1,25 @@
1
+ ---
2
+ description: Security guardrails for all code changes
3
+ globs:
4
+ alwaysApply: true
5
+ ---
6
+
7
+ ## Authentication & Authorization
8
+
9
+ - Every API route under `src/app/api/protected/` MUST use `withAuth`, `withAuthNoParams`, `withRole`, or `withOwnership` from `@/lib/mars`.
10
+ - Admin-only routes MUST use `withRole(['admin'], ...)` which verifies the role against the database on every request. Never trust the JWT role claim alone.
11
+ - Ownership-gated routes MUST use `withOwnership`. Never accept a `userId` parameter from the client for authorization.
12
+ - Public auth endpoints (`login`, `signup`, `forgot`, `reset`, `verify`) MUST call `checkRateLimit` with the appropriate `RATE_LIMITS` config from `@mars-stack/core/rate-limit`.
13
+
14
+ ## Secrets
15
+
16
+ - Use constant-time comparison (`constantTimeEqual`) for all secret/token/signature comparisons. Never use `===` for secrets.
17
+ - CSRF keys are derived from `JWT_SECRET` via HMAC with a domain separator; never reuse `JWT_SECRET` directly.
18
+ - Never log secrets, tokens, or full authorization headers.
19
+ - Server-only modules MUST import `"server-only"` at the top to prevent client-side bundling.
20
+
21
+ ## Serverless Constraints
22
+
23
+ - No `setInterval` / `setTimeout` for background cleanup; use lazy-on-read patterns.
24
+ - No in-memory queues or global mutable state that assumes process persistence.
25
+ - Background processing should fire a separate HTTP request, not rely on fire-and-forget promises.
@@ -0,0 +1,24 @@
1
+ ---
2
+ description: Testing conventions
3
+ globs: **/*.test.ts,**/*.test.tsx
4
+ alwaysApply: false
5
+ ---
6
+
7
+ ## Framework
8
+
9
+ - Unit tests: Vitest (`yarn test`). Config at `vitest.config.ts`.
10
+ - E2E tests: Playwright (`yarn test:e2e`). Config at `playwright.config.ts`.
11
+ - Test files live next to the code they test: `route.test.ts` beside `route.ts`.
12
+
13
+ ## Mocking
14
+
15
+ - Use `@mars-stack/core/test-utils/mock-auth` to mock authenticated sessions in API route tests.
16
+ - Use `@mars-stack/core/test-utils/factories` for consistent test data.
17
+ - Mock Prisma with `vi.mock('@/lib/prisma')` and provide typed mocks for each model method.
18
+
19
+ ## Patterns
20
+
21
+ - Test API routes by calling the exported handler directly, not via HTTP.
22
+ - Assert both the response body and status code.
23
+ - Test error paths: invalid input (Zod), unauthorized, not found, database errors.
24
+ - Unit tests MUST NOT depend on external services (database, Redis, email). Mock everything.
@@ -0,0 +1,29 @@
1
+ ---
2
+ description: UI component and styling conventions
3
+ globs: **/*.tsx
4
+ alwaysApply: false
5
+ ---
6
+
7
+ ## Design Token System
8
+
9
+ MARS uses a three-layer CSS token system. Never use raw Tailwind colour classes (e.g., `text-gray-900`). Always use semantic tokens:
10
+
11
+ - **Surfaces**: `bg-surface-background`, `bg-surface-card`, `bg-surface-elevated`, `bg-surface-input`
12
+ - **Text**: `text-text-primary`, `text-text-secondary`, `text-text-muted`, `text-text-link`, `text-text-error`
13
+ - **Borders**: `border-border-default`, `border-border-input`, `border-border-focus`, `border-border-error`
14
+ - **Brand**: `bg-brand-primary`, `bg-brand-primary-hover`, `text-text-on-brand`
15
+ - **Feedback**: `bg-success-muted`, `text-text-success`, `bg-error-muted`, `text-text-error`
16
+ - **Interactive**: `bg-ghost-hover`, `bg-ghost-active`, `bg-danger-bg`, `focus:ring-ring-focus`
17
+
18
+ ## Component Architecture
19
+
20
+ - **Primitives** (`@mars-stack/ui`): Single-responsibility, fully styled via tokens, accept `className` for overrides. Examples: `Button`, `Input`, `Badge`, `Avatar`, `Spinner`.
21
+ - **Patterns** (`@mars-stack/ui`): Compose primitives, no business logic. Examples: `Card`, `Modal`, `Toast`, `FormField`, `EmptyState`.
22
+ - **Feature components** (`src/features/<name>/components/`): Contain business logic, compose primitives and patterns.
23
+
24
+ ## Rules
25
+
26
+ - Always import components from `@mars-stack/ui` (both primitives and patterns are exported from this package).
27
+ - Use `clsx` for conditional class composition.
28
+ - New shared primitives go in the `@mars-stack/ui` package.
29
+ - Components MUST support dark mode via the token system (tokens swap automatically with `.dark` class).