@vibecheckai/cli 3.0.2 → 3.0.3

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 (68) hide show
  1. package/package.json +9 -1
  2. package/bin/cli-hygiene.js +0 -241
  3. package/bin/guardrail.js +0 -834
  4. package/bin/runners/cli-utils.js +0 -1070
  5. package/bin/runners/context/ai-task-decomposer.js +0 -337
  6. package/bin/runners/context/analyzer.js +0 -462
  7. package/bin/runners/context/api-contracts.js +0 -427
  8. package/bin/runners/context/context-diff.js +0 -342
  9. package/bin/runners/context/context-pruner.js +0 -291
  10. package/bin/runners/context/dependency-graph.js +0 -414
  11. package/bin/runners/context/generators/claude.js +0 -107
  12. package/bin/runners/context/generators/codex.js +0 -108
  13. package/bin/runners/context/generators/copilot.js +0 -119
  14. package/bin/runners/context/generators/cursor.js +0 -514
  15. package/bin/runners/context/generators/mcp.js +0 -151
  16. package/bin/runners/context/generators/windsurf.js +0 -180
  17. package/bin/runners/context/git-context.js +0 -302
  18. package/bin/runners/context/index.js +0 -1042
  19. package/bin/runners/context/insights.js +0 -173
  20. package/bin/runners/context/mcp-server/generate-rules.js +0 -337
  21. package/bin/runners/context/mcp-server/index.js +0 -1176
  22. package/bin/runners/context/mcp-server/package.json +0 -24
  23. package/bin/runners/context/memory.js +0 -200
  24. package/bin/runners/context/monorepo.js +0 -215
  25. package/bin/runners/context/multi-repo-federation.js +0 -404
  26. package/bin/runners/context/patterns.js +0 -253
  27. package/bin/runners/context/proof-context.js +0 -972
  28. package/bin/runners/context/security-scanner.js +0 -303
  29. package/bin/runners/context/semantic-search.js +0 -350
  30. package/bin/runners/context/shared.js +0 -264
  31. package/bin/runners/context/team-conventions.js +0 -310
  32. package/bin/runners/lib/ai-bridge.js +0 -416
  33. package/bin/runners/lib/analysis-core.js +0 -271
  34. package/bin/runners/lib/analyzers.js +0 -541
  35. package/bin/runners/lib/audit-bridge.js +0 -391
  36. package/bin/runners/lib/auth-truth.js +0 -193
  37. package/bin/runners/lib/auth.js +0 -215
  38. package/bin/runners/lib/backup.js +0 -62
  39. package/bin/runners/lib/billing.js +0 -107
  40. package/bin/runners/lib/claims.js +0 -118
  41. package/bin/runners/lib/cli-ui.js +0 -540
  42. package/bin/runners/lib/compliance-bridge-new.js +0 -0
  43. package/bin/runners/lib/compliance-bridge.js +0 -165
  44. package/bin/runners/lib/contracts/auth-contract.js +0 -194
  45. package/bin/runners/lib/contracts/env-contract.js +0 -178
  46. package/bin/runners/lib/contracts/external-contract.js +0 -198
  47. package/bin/runners/lib/contracts/guard.js +0 -168
  48. package/bin/runners/lib/contracts/index.js +0 -89
  49. package/bin/runners/lib/contracts/plan-validator.js +0 -311
  50. package/bin/runners/lib/contracts/route-contract.js +0 -192
  51. package/bin/runners/lib/detect.js +0 -89
  52. package/bin/runners/lib/doctor/autofix.js +0 -254
  53. package/bin/runners/lib/doctor/index.js +0 -37
  54. package/bin/runners/lib/doctor/modules/dependencies.js +0 -325
  55. package/bin/runners/lib/doctor/modules/index.js +0 -46
  56. package/bin/runners/lib/doctor/modules/network.js +0 -250
  57. package/bin/runners/lib/doctor/modules/project.js +0 -312
  58. package/bin/runners/lib/doctor/modules/runtime.js +0 -224
  59. package/bin/runners/lib/doctor/modules/security.js +0 -348
  60. package/bin/runners/lib/doctor/modules/system.js +0 -213
  61. package/bin/runners/lib/doctor/modules/vibecheck.js +0 -394
  62. package/bin/runners/lib/doctor/reporter.js +0 -262
  63. package/bin/runners/lib/doctor/service.js +0 -262
  64. package/bin/runners/lib/doctor/types.js +0 -113
  65. package/bin/runners/lib/doctor/ui.js +0 -263
  66. package/bin/runners/lib/doctor-enhanced.js +0 -233
  67. package/bin/runners/lib/doctor-v2.js +0 -608
  68. package/bin/runners/lib/enforcement.js +0 -72
@@ -1,119 +0,0 @@
1
- /**
2
- * GitHub Copilot Instructions Generator
3
- * Generates .github/copilot-instructions.md
4
- */
5
-
6
- /**
7
- * Generate Copilot instructions
8
- */
9
- function generateCopilotInstructions(analysis) {
10
- const p = analysis.patterns || {};
11
- const m = analysis.monorepo || {};
12
-
13
- return `# GitHub Copilot Instructions - ${analysis.name}
14
-
15
- ## Project Overview
16
-
17
- This is a **${analysis.framework || "JavaScript"}** project using **${analysis.language || "JavaScript"}**.
18
- Architecture: ${analysis.architecture}
19
- ${m.isMonorepo ? `Monorepo: ${m.type} with ${m.workspaces?.length || 0} workspaces` : ""}
20
-
21
- ## Tech Stack
22
-
23
- ${analysis.hasNextjs ? "- Next.js (App Router)" : ""}
24
- ${analysis.hasReact ? "- React" : ""}
25
- ${analysis.hasTypescript ? "- TypeScript (strict mode)" : ""}
26
- ${analysis.hasPrisma ? "- Prisma ORM" : ""}
27
- ${analysis.hasTailwind ? "- Tailwind CSS" : ""}
28
- ${p.stateManagement ? `- State Management: ${p.stateManagement}` : ""}
29
- ${p.validation ? `- Validation: ${p.validation}` : ""}
30
- ${p.authentication ? `- Authentication: ${p.authentication}` : ""}
31
- ${p.dataFetching?.length ? `- Data Fetching: ${p.dataFetching.join(", ")}` : ""}
32
- ${p.testing?.length ? `- Testing: ${p.testing.join(", ")}` : ""}
33
-
34
- ## Project Structure
35
-
36
- \`\`\`
37
- ${analysis.directories.map(d => `${d}/`).join("\n")}
38
- \`\`\`
39
-
40
- ${m.isMonorepo && m.workspaces?.length > 0 ? `## Workspaces
41
-
42
- ${m.workspaces.slice(0, 8).map(w => `- \`${w.path}\` - ${w.name}`).join("\n")}
43
- ` : ""}
44
-
45
- ## Existing Components
46
-
47
- When generating UI code, prefer using these existing components:
48
- ${analysis.components.slice(0, 25).map(c => `- ${c}`).join("\n") || "None detected"}
49
-
50
- ${p.hooks?.length > 0 ? `## Custom Hooks
51
-
52
- Use these existing hooks instead of creating new ones:
53
- ${p.hooks.slice(0, 15).map(h => `- \`${h}\``).join("\n")}
54
- ` : ""}
55
-
56
- ## API Routes
57
-
58
- ${analysis.apiRoutes.slice(0, 15).map(r => `- ${r}`).join("\n") || "None detected"}
59
-
60
- ${analysis.models.length > 0 ? `## Data Models (Prisma)
61
-
62
- ${analysis.models.map(m => `- ${m}`).join("\n")}
63
- ` : ""}
64
-
65
- ${analysis.envVars?.variables?.length > 0 ? `## Environment Variables
66
-
67
- Required variables:
68
- ${analysis.envVars.variables.slice(0, 15).map(v => `- \`${v}\``).join("\n")}
69
- ` : ""}
70
-
71
- ## Code Conventions
72
-
73
- ### File Naming
74
- - Components: ${analysis.conventions.naming.components || "PascalCase"} (e.g., \`Button.tsx\`)
75
- - Utilities: camelCase (e.g., \`formatDate.ts\`)
76
- - Types: PascalCase with \`.types.ts\` suffix
77
-
78
- ### Import Aliases
79
- - Use \`@/\` for src imports (e.g., \`@/components/Button\`)
80
- - Never use deep relative imports like \`../../../\`
81
-
82
- ### TypeScript
83
- ${analysis.hasTypescript ? `- Enable strict mode
84
- - No \`any\` types - use \`unknown\` or proper types
85
- - Define interfaces for all props and API responses` : "- Use JSDoc comments for type hints"}
86
-
87
- ## Critical Rules
88
-
89
- 1. **Security**: Never hardcode API keys, secrets, or credentials
90
- 2. **Types**: ${analysis.hasTypescript ? "No `any` types allowed" : "Use JSDoc for type hints"}
91
- 3. **Components**: Check existing components before creating new ones
92
- 4. **Hooks**: Use existing custom hooks when available
93
- 5. **Validation**: ${p.validation ? `Always validate input with ${p.validation}` : "Always validate user input"}
94
- 6. **Styling**: ${analysis.hasTailwind ? "Use Tailwind CSS classes" : "Follow existing styling patterns"}
95
- 7. **State**: ${p.stateManagement ? `Use ${p.stateManagement} for global state` : "Keep state minimal and local"}
96
-
97
- ${p.antiPatterns?.length > 0 ? `## Anti-Patterns to Avoid
98
-
99
- ${p.antiPatterns.map(ap => `- ❌ ${ap.message} → ${ap.suggestion}`).join("\n")}
100
- ` : ""}
101
-
102
- ## When Writing Code
103
-
104
- 1. Follow existing patterns in the codebase
105
- 2. Use TypeScript strict types
106
- 3. Add proper error handling
107
- 4. Use existing utilities and helpers
108
- 5. Keep functions small and focused
109
- 6. Write self-documenting code
110
-
111
- ---
112
-
113
- *Context Enhanced by vibecheck AI*
114
- `;
115
- }
116
-
117
- module.exports = {
118
- generateCopilotInstructions,
119
- };
@@ -1,514 +0,0 @@
1
- /**
2
- * Cursor Rules Generator
3
- * Generates .cursorrules and .cursor/rules/*.mdc files
4
- */
5
-
6
- /**
7
- * Get directory purpose description
8
- */
9
- function getDirectoryPurpose(dir) {
10
- const purposes = {
11
- "src": "Source code root",
12
- "app": "Next.js App Router pages",
13
- "pages": "Next.js Pages Router",
14
- "components": "Reusable UI components",
15
- "lib": "Utility functions and shared logic",
16
- "utils": "Helper functions",
17
- "hooks": "Custom React hooks",
18
- "services": "API and external service integrations",
19
- "api": "API route handlers",
20
- "server": "Server-side code",
21
- "prisma": "Database schema and migrations",
22
- "public": "Static assets",
23
- "styles": "CSS and styling",
24
- "types": "TypeScript type definitions",
25
- "config": "Configuration files",
26
- "test": "Test files",
27
- "__tests__": "Test files",
28
- };
29
- return purposes[dir] || "Project files";
30
- }
31
-
32
- /**
33
- * Generate main .cursorrules file
34
- */
35
- function generateCursorRules(analysis) {
36
- const p = analysis.patterns || {};
37
- const t = analysis.types || {};
38
- const s = analysis.stats || {};
39
- const env = analysis.envVars || {};
40
- const m = analysis.monorepo || {};
41
-
42
- return `# vibecheck AI - Project Context for Cursor
43
-
44
- > Auto-generated by \`vibecheck context\`. Regenerate when your codebase changes.
45
-
46
- ## Project Overview
47
-
48
- - **Name**: ${analysis.name}
49
- - **Framework**: ${analysis.framework || "Unknown"}
50
- - **Language**: ${analysis.language || "JavaScript"}
51
- - **Architecture**: ${analysis.architecture}
52
- ${s.totalFiles ? `- **Size**: ${s.totalFiles} files, ~${Math.round(s.totalLines / 1000)}k lines` : ""}
53
- ${m.isMonorepo ? `- **Monorepo**: ${m.type} with ${m.workspaces?.length || 0} workspaces` : ""}
54
-
55
- ## Tech Stack
56
-
57
- ${analysis.hasNextjs ? "- Next.js (App Router)" : ""}
58
- ${analysis.hasReact ? "- React" : ""}
59
- ${analysis.hasTypescript ? "- TypeScript" : ""}
60
- ${analysis.hasPrisma ? "- Prisma ORM" : ""}
61
- ${analysis.hasTailwind ? "- Tailwind CSS" : ""}
62
- ${p.stateManagement ? `- State: ${p.stateManagement}` : ""}
63
- ${p.validation ? `- Validation: ${p.validation}` : ""}
64
- ${p.authentication ? `- Auth: ${p.authentication}` : ""}
65
- ${p.dataFetching?.length ? `- Data Fetching: ${p.dataFetching.join(", ")}` : ""}
66
-
67
- ## Project Structure
68
-
69
- \`\`\`
70
- ${analysis.directories.map(d => `${d}/`).join("\n")}
71
- \`\`\`
72
-
73
- ${m.isMonorepo && m.workspaces?.length > 0 ? `## Workspaces
74
-
75
- ${m.workspaces.slice(0, 10).map(w => `- \`${w.path}\` - ${w.name}`).join("\n")}
76
- ` : ""}
77
-
78
- ${p.hooks?.length > 0 ? `## Custom Hooks (Use These!)
79
-
80
- ${p.hooks.slice(0, 15).map(h => `- \`${h}\``).join("\n")}
81
-
82
- ${p.codeExamples?.hooks ? `### Example: ${p.codeExamples.hooks.name}
83
- \`\`\`typescript
84
- // From: ${p.codeExamples.hooks.file}
85
- ${p.codeExamples.hooks.code}
86
- \`\`\`
87
- ` : ""}
88
- ` : ""}
89
-
90
- ${analysis.apiRoutes.length > 0 ? `## API Routes
91
-
92
- ${analysis.apiRoutes.slice(0, 20).map(r => `- \`${r}\``).join("\n")}
93
- ${analysis.apiRoutes.length > 20 ? `\n... and ${analysis.apiRoutes.length - 20} more` : ""}
94
- ` : ""}
95
-
96
- ${analysis.components.length > 0 ? `## Components (Check Before Creating New)
97
-
98
- ${analysis.components.slice(0, 30).map(c => `- \`${c}\``).join("\n")}
99
- ${analysis.components.length > 30 ? `\n... and ${analysis.components.length - 30} more` : ""}
100
- ` : ""}
101
-
102
- ${analysis.models.length > 0 ? `## Data Models (Prisma)
103
-
104
- ${analysis.models.map(m => `- \`${m}\``).join("\n")}
105
- ` : ""}
106
-
107
- ${t.interfaces?.length > 0 || t.types?.length > 0 ? `## Key Types & Interfaces
108
-
109
- ${t.interfaces?.slice(0, 15).map(i => `- \`interface ${i}\``).join("\n") || ""}
110
- ${t.types?.slice(0, 10).map(ty => `- \`type ${ty}\``).join("\n") || ""}
111
- ${t.enums?.length > 0 ? `\nEnums: ${t.enums.slice(0, 5).map(e => `\`${e}\``).join(", ")}` : ""}
112
- ` : ""}
113
-
114
- ${env.variables?.length > 0 ? `## Environment Variables
115
-
116
- Required env vars:
117
- ${env.variables.slice(0, 20).map(v => `- \`${v}\``).join("\n")}
118
- ${env.files?.length ? `\nEnv files: ${env.files.join(", ")}` : ""}
119
- ` : ""}
120
-
121
- ${analysis.scripts?.length > 0 ? `## NPM Scripts
122
-
123
- ${analysis.scripts.slice(0, 10).map(s => `- \`npm run ${s.name}\` - ${s.command}`).join("\n")}
124
- ` : ""}
125
-
126
- ## Coding Conventions
127
-
128
- ### File Naming
129
- - Components: ${analysis.conventions.naming.components || "PascalCase"} (e.g., \`Button.tsx\`, \`UserCard.tsx\`)
130
- - Utilities: camelCase (e.g., \`formatDate.ts\`, \`apiClient.ts\`)
131
- - Types: PascalCase with \`.d.ts\` or \`.types.ts\` suffix
132
-
133
- ### Import Order
134
- 1. React/Next.js imports
135
- 2. Third-party libraries
136
- 3. Internal components (\`@/components/\`)
137
- 4. Internal utilities (\`@/lib/\`, \`@/utils/\`)
138
- 5. Types
139
- 6. Styles
140
-
141
- ### Code Style
142
- - Use ${analysis.hasTypescript ? "TypeScript with strict mode" : "JavaScript with JSDoc comments"}
143
- - Prefer functional components with hooks
144
- - Use path aliases (\`@/\`) for imports
145
- ${analysis.hasTailwind ? "- Use Tailwind CSS for styling (no inline styles)" : ""}
146
- ${analysis.hasPrisma ? "- Use Prisma client for database operations" : ""}
147
- ${p.stateManagement ? `- Use ${p.stateManagement} for state management` : ""}
148
- ${p.validation ? `- Use ${p.validation} for input validation` : ""}
149
-
150
- ## Critical Rules
151
-
152
- 1. **Never hardcode secrets** - Use environment variables
153
- 2. **No mock data in production** - Check for \`demo\`, \`fake\`, \`mock\` patterns
154
- 3. **Type everything** - No \`any\` types${analysis.hasTypescript ? "" : " (use JSDoc)"}
155
- 4. **Follow existing patterns** - Match the codebase style
156
- 5. **Use existing components** - Don't recreate what exists
157
- 6. **API routes must validate input** - Never trust client data
158
- ${p.hooks?.length ? `7. **Use existing hooks** - Check custom hooks list above` : ""}
159
-
160
- ${p.antiPatterns?.length > 0 ? `## ⚠️ Avoid These Patterns
161
-
162
- ${p.antiPatterns.map(ap => `- **${ap.message}** - ${ap.suggestion}`).join("\n")}
163
- ` : ""}
164
-
165
- ## When Creating New Files
166
-
167
- 1. Check if similar file exists first
168
- 2. Place in correct directory based on type
169
- 3. Follow naming conventions
170
- 4. Import from correct paths
171
- 5. Add proper types/interfaces
172
- ${p.hooks?.length ? `6. Check if there's an existing hook you can use` : ""}
173
-
174
- ---
175
-
176
- *Context Enhanced by vibecheck AI*
177
- `;
178
- }
179
-
180
- /**
181
- * Generate modular Cursor rules (.cursor/rules/*.mdc)
182
- */
183
- function generateCursorModularRules(analysis) {
184
- const rules = {};
185
- const p = analysis.patterns || {};
186
- const t = analysis.types || {};
187
- const env = analysis.envVars || {};
188
- const m = analysis.monorepo || {};
189
-
190
- // Architecture rules
191
- rules["architecture"] = `---
192
- description: Project architecture and structure guidelines
193
- globs: ["**/*.{ts,tsx,js,jsx}"]
194
- alwaysApply: true
195
- ---
196
-
197
- # Architecture Guidelines
198
-
199
- ## Project Type: ${analysis.architecture}
200
-
201
- ${analysis.hasNextjs ? `### Next.js App Router Structure
202
- - Pages go in \`app/\` directory
203
- - API routes in \`app/api/\`
204
- - Layouts use \`layout.tsx\`
205
- - Loading states use \`loading.tsx\`
206
- - Error boundaries use \`error.tsx\`
207
- ` : ""}
208
-
209
- ${m.isMonorepo ? `### Monorepo Structure (${m.type})
210
-
211
- Workspaces:
212
- ${m.workspaces?.slice(0, 8).map(w => `- \`${w.path}\` - ${w.name}`).join("\n") || "None detected"}
213
-
214
- ${m.sharedPackages?.length > 0 ? `Shared Packages:
215
- ${m.sharedPackages.slice(0, 5).map(p => `- ${p.name} (used in ${p.usedIn} workspaces)`).join("\n")}` : ""}
216
- ` : ""}
217
-
218
- ### Directory Purpose
219
- ${analysis.directories.map(d => `- \`${d}/\` - ${getDirectoryPurpose(d)}`).join("\n")}
220
-
221
- ### Import Aliases
222
- - Use \`@/\` for src directory imports
223
- - Never use relative imports deeper than \`../\`
224
- `;
225
-
226
- // Data flow rules
227
- if (analysis.hasPrisma || analysis.apiRoutes.length > 0 || p.dataFetching?.length) {
228
- rules["data-flow"] = `---
229
- description: Data fetching and API interaction patterns
230
- globs: ["**/api/**", "**/lib/**", "**/services/**", "**/hooks/**"]
231
- alwaysApply: false
232
- ---
233
-
234
- # Data Flow Guidelines
235
-
236
- ${p.dataFetching?.length ? `## Data Fetching: ${p.dataFetching.join(", ")}
237
-
238
- ${p.dataFetching.includes("TanStack Query") ? `### TanStack Query Pattern
239
- - Use \`useQuery\` for GET requests
240
- - Use \`useMutation\` for POST/PUT/DELETE
241
- - Define query keys consistently
242
- - Invalidate queries after mutations
243
- ` : ""}
244
- ${p.dataFetching.includes("SWR") ? `### SWR Pattern
245
- - Use \`useSWR\` for data fetching
246
- - Define fetcher functions
247
- - Handle loading and error states
248
- ` : ""}
249
- ${p.dataFetching.includes("tRPC") ? `### tRPC Pattern
250
- - Use tRPC procedures for type-safe API calls
251
- - Define routers in \`server/api/routers\`
252
- - Use \`api.*.useQuery()\` pattern
253
- ` : ""}
254
- ` : ""}
255
-
256
- ${analysis.hasPrisma ? `## Database (Prisma)
257
-
258
- Models: ${analysis.models.join(", ")}
259
-
260
- Rules:
261
- - Use Prisma client from \`@/lib/prisma\` or \`@/server/db\`
262
- - Use transactions for multi-step operations
263
- - Handle errors with try/catch
264
- - Never expose raw database errors
265
- ` : ""}
266
-
267
- ${analysis.apiRoutes.length > 0 ? `## API Routes
268
-
269
- ${analysis.apiRoutes.slice(0, 15).map(r => `- ${r}`).join("\n")}
270
-
271
- Rules:
272
- ${p.validation ? `- Validate all input with ${p.validation}` : "- Validate all input"}
273
- - Return consistent response shapes
274
- - Use proper HTTP status codes
275
- ` : ""}
276
- `;
277
- }
278
-
279
- // Component rules
280
- if (analysis.components.length > 0) {
281
- rules["components"] = `---
282
- description: Component creation and styling guidelines
283
- globs: ["**/components/**/*.{tsx,jsx}"]
284
- alwaysApply: false
285
- ---
286
-
287
- # Component Guidelines
288
-
289
- ## Existing Components (${analysis.components.length})
290
- ${analysis.components.slice(0, 20).map(c => `- \`${c}\``).join("\n")}
291
-
292
- ## Before Creating New Components
293
-
294
- 1. **Check if it exists above**
295
- 2. Place in \`components/\` or feature folder
296
- 3. Use ${analysis.conventions.naming.components || "PascalCase"} naming
297
- 4. Export as named export
298
- ${analysis.hasTailwind ? "5. Use Tailwind CSS for styling" : ""}
299
- ${p.styling?.length ? `6. Styling: ${p.styling.join(", ")}` : ""}
300
-
301
- ## Component Template
302
-
303
- \`\`\`tsx
304
- interface Props {
305
- // Define props with types
306
- }
307
-
308
- export function ComponentName({ ...props }: Props) {
309
- return (
310
- // JSX
311
- );
312
- }
313
- \`\`\`
314
- `;
315
- }
316
-
317
- // Hooks rules
318
- if (p.hooks?.length > 0) {
319
- rules["hooks"] = `---
320
- description: Custom hooks patterns and usage
321
- globs: ["**/hooks/**/*.{ts,tsx}", "**/use*.{ts,tsx}"]
322
- alwaysApply: false
323
- ---
324
-
325
- # Custom Hooks
326
-
327
- ## Available Hooks (${p.hooks.length})
328
-
329
- ${p.hooks.map(h => `- \`${h}\``).join("\n")}
330
-
331
- ## Before Creating a New Hook
332
-
333
- 1. **Check the list above first**
334
- 2. Name it \`use[Feature]\`
335
- 3. Place in \`hooks/\` or \`lib/hooks/\`
336
- 4. Return a consistent shape
337
-
338
- ${p.codeExamples?.hooks ? `## Example
339
-
340
- \`\`\`typescript
341
- // ${p.codeExamples.hooks.file}
342
- ${p.codeExamples.hooks.code}
343
- \`\`\`
344
- ` : ""}
345
- `;
346
- }
347
-
348
- // State management rules
349
- if (p.stateManagement) {
350
- rules["state"] = `---
351
- description: State management patterns
352
- globs: ["**/store/**", "**/state/**", "**/context/**"]
353
- alwaysApply: false
354
- ---
355
-
356
- # State Management: ${p.stateManagement}
357
-
358
- ${p.stateManagement === "Zustand" ? `## Zustand Pattern
359
-
360
- \`\`\`typescript
361
- import { create } from 'zustand'
362
-
363
- interface Store {
364
- count: number
365
- increment: () => void
366
- }
367
-
368
- export const useStore = create<Store>((set) => ({
369
- count: 0,
370
- increment: () => set((state) => ({ count: state.count + 1 })),
371
- }))
372
- \`\`\`
373
-
374
- - Create stores in \`store/\` directory
375
- - Use typed store interfaces
376
- - Keep stores focused and small
377
- ` : ""}
378
- ${p.stateManagement === "Redux Toolkit" ? `## Redux Toolkit Pattern
379
-
380
- \`\`\`typescript
381
- import { createSlice } from '@reduxjs/toolkit'
382
-
383
- const slice = createSlice({
384
- name: 'feature',
385
- initialState: {},
386
- reducers: {}
387
- })
388
- \`\`\`
389
-
390
- - Use createSlice for reducers
391
- - Use createAsyncThunk for async
392
- ` : ""}
393
- ${p.stateManagement === "React Context" ? `## Context Pattern
394
-
395
- \`\`\`typescript
396
- const Context = createContext<Type | null>(null)
397
-
398
- export function useFeature() {
399
- const context = useContext(Context)
400
- if (!context) throw new Error('Must be used within Provider')
401
- return context
402
- }
403
- \`\`\`
404
- ` : ""}
405
- `;
406
- }
407
-
408
- // Types rules
409
- if (t.interfaces?.length > 0 || t.types?.length > 0) {
410
- rules["types"] = `---
411
- description: Type definitions and interfaces
412
- globs: ["**/*.d.ts", "**/types/**", "**/*.types.ts"]
413
- alwaysApply: false
414
- ---
415
-
416
- # Type Definitions
417
-
418
- ## Interfaces (${t.interfaces?.length || 0})
419
- ${t.interfaces?.slice(0, 20).map(i => `- \`${i}\``).join("\n") || "None"}
420
-
421
- ## Types (${t.types?.length || 0})
422
- ${t.types?.slice(0, 15).map(ty => `- \`${ty}\``).join("\n") || "None"}
423
-
424
- ${t.enums?.length > 0 ? `## Enums
425
- ${t.enums.map(e => `- \`${e}\``).join("\n")}` : ""}
426
-
427
- ## Conventions
428
- - Interfaces for object shapes
429
- - Type aliases for unions
430
- - No \`any\` - use \`unknown\`
431
- `;
432
- }
433
-
434
- // Environment rules
435
- if (env.variables?.length > 0) {
436
- rules["environment"] = `---
437
- description: Environment variables
438
- globs: ["**/*.env*", "**/config/**"]
439
- alwaysApply: false
440
- ---
441
-
442
- # Environment Variables (${env.variables?.length || 0})
443
-
444
- ${env.variables?.slice(0, 25).map(v => `- \`${v}\``).join("\n")}
445
-
446
- ## Rules
447
- - Never commit \`.env\` files
448
- - Access via \`process.env.VAR_NAME\`
449
- - Prefix client-side vars with \`NEXT_PUBLIC_\`
450
- `;
451
- }
452
-
453
- // Anti-patterns rules
454
- if (p.antiPatterns?.length > 0) {
455
- rules["avoid"] = `---
456
- description: Patterns to avoid
457
- globs: ["**/*.{ts,tsx,js,jsx}"]
458
- alwaysApply: true
459
- ---
460
-
461
- # ⚠️ Patterns to Avoid
462
-
463
- ${p.antiPatterns.map(ap => `## ${ap.severity === 'error' ? '🔴' : '🟡'} ${ap.message}
464
- **Fix:** ${ap.suggestion}
465
- `).join("\n")}
466
-
467
- ## General
468
- - ❌ No \`any\` type
469
- - ❌ No hardcoded secrets
470
- - ❌ No console.log in production
471
- - ❌ No mock data in production
472
- `;
473
- }
474
-
475
- // Testing rules
476
- if (p.testing?.length > 0) {
477
- rules["testing"] = `---
478
- description: Testing patterns
479
- globs: ["**/*.test.{ts,tsx}", "**/*.spec.{ts,tsx}"]
480
- alwaysApply: false
481
- ---
482
-
483
- # Testing: ${p.testing.join(", ")}
484
-
485
- ${p.testing.includes("Jest") || p.testing.includes("Vitest") ? `## Unit Tests
486
-
487
- \`\`\`typescript
488
- describe('Feature', () => {
489
- it('should work', () => {
490
- expect(result).toBe('expected')
491
- })
492
- })
493
- \`\`\`
494
- ` : ""}
495
- ${p.testing.includes("Playwright") ? `## E2E Tests
496
-
497
- \`\`\`typescript
498
- test('user flow', async ({ page }) => {
499
- await page.goto('/')
500
- await page.click('button')
501
- })
502
- \`\`\`
503
- ` : ""}
504
- `;
505
- }
506
-
507
- return rules;
508
- }
509
-
510
- module.exports = {
511
- generateCursorRules,
512
- generateCursorModularRules,
513
- getDirectoryPurpose,
514
- };