midas-mcp 5.3.8 → 5.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.
@@ -0,0 +1,651 @@
1
+ /**
2
+ * Reality Check Module
3
+ *
4
+ * Analyzes project docs to infer what requirements apply,
5
+ * categorizes them by what AI can/cannot do,
6
+ * and generates context-aware prompts for Cursor.
7
+ */
8
+ import { existsSync, readFileSync } from 'fs';
9
+ import { join } from 'path';
10
+ import { sanitizePath } from './security.js';
11
+ // ============================================================================
12
+ // REALITY CHECK DEFINITIONS
13
+ // ============================================================================
14
+ const REALITY_CHECKS = {
15
+ // ✅ GENERATABLE - AI can draft these
16
+ PRIVACY_POLICY: {
17
+ key: 'PRIVACY_POLICY',
18
+ category: 'Legal',
19
+ tier: 'generatable',
20
+ headline: 'You need a Privacy Policy',
21
+ explanation: 'You collect user data. Users need to know what you collect, why, and how to delete it.',
22
+ priority: 'critical',
23
+ promptTemplate: `Create a privacy policy for this project based on the brainlift and PRD.
24
+
25
+ We collect: {{dataCollected}}
26
+ Target users: {{targetUsers}}
27
+ Business model: {{businessModel}}
28
+
29
+ Include sections:
30
+ - What we collect and why
31
+ - How we use the data
32
+ - Third parties we share with (if any)
33
+ - How long we keep data
34
+ - User rights (access, correct, delete)
35
+ - How to contact us
36
+
37
+ Save to docs/privacy-policy.md
38
+
39
+ Add at the top: "DRAFT - Review with a lawyer before publishing"`,
40
+ condition: (p) => p.collectsUserData,
41
+ },
42
+ TERMS_OF_SERVICE: {
43
+ key: 'TERMS_OF_SERVICE',
44
+ category: 'Legal',
45
+ tier: 'generatable',
46
+ headline: 'You need Terms of Service',
47
+ explanation: 'Any public product needs terms defining the rules of use and liability limits.',
48
+ priority: 'high',
49
+ promptTemplate: `Create terms of service for this project based on the brainlift and PRD.
50
+
51
+ Product type: {{productType}}
52
+ Business model: {{businessModel}}
53
+ Key features: {{keyFeatures}}
54
+
55
+ Include sections:
56
+ - Acceptance of terms
57
+ - Description of service
58
+ - User responsibilities
59
+ - Prohibited uses
60
+ - Intellectual property
61
+ - Limitation of liability
62
+ - Termination
63
+ - Governing law (placeholder for jurisdiction)
64
+
65
+ Save to docs/terms-of-service.md
66
+
67
+ Add at the top: "DRAFT - Review with a lawyer before publishing"`,
68
+ condition: (p) => p.collectsUserData || p.hasPayments,
69
+ },
70
+ AI_DISCLOSURE: {
71
+ key: 'AI_DISCLOSURE',
72
+ category: 'Transparency',
73
+ tier: 'generatable',
74
+ headline: 'You need an AI disclosure',
75
+ explanation: 'Users should know when AI is involved and that it can make mistakes.',
76
+ priority: 'high',
77
+ promptTemplate: `Create an AI transparency disclosure for this project.
78
+
79
+ Based on the brainlift, this project uses AI to: {{aiUsage}}
80
+
81
+ Create a user-friendly disclosure explaining:
82
+ - What AI does in this product
83
+ - That AI can make mistakes or produce inaccurate results
84
+ - How users can report issues or get human help
85
+ - Any limitations users should know about
86
+
87
+ Save to docs/ai-disclosure.md
88
+
89
+ Also add a brief inline disclosure component/text that can be shown in the UI where AI is used.`,
90
+ condition: (p) => p.usesAI,
91
+ },
92
+ REFUND_POLICY: {
93
+ key: 'REFUND_POLICY',
94
+ category: 'Business',
95
+ tier: 'generatable',
96
+ headline: 'You need a refund policy',
97
+ explanation: 'Paid products need clear refund terms to avoid disputes and chargebacks.',
98
+ priority: 'high',
99
+ promptTemplate: `Create a refund policy for this project.
100
+
101
+ Business model: {{businessModel}}
102
+ Subscription type: {{subscriptionType}}
103
+
104
+ Include:
105
+ - Refund eligibility (time period, conditions)
106
+ - How to request a refund
107
+ - Processing time
108
+ - Exceptions (if any)
109
+ - Contact information
110
+
111
+ Keep it simple and fair - generous refund policies reduce chargebacks.
112
+
113
+ Save to docs/refund-policy.md`,
114
+ condition: (p) => p.hasPayments,
115
+ },
116
+ CONTENT_POLICY: {
117
+ key: 'CONTENT_POLICY',
118
+ category: 'Trust',
119
+ tier: 'generatable',
120
+ headline: 'You need a content policy',
121
+ explanation: 'User-generated content needs rules about what\'s allowed and how violations are handled.',
122
+ priority: 'high',
123
+ promptTemplate: `Create a content policy for this project.
124
+
125
+ This product allows users to: {{userContentType}}
126
+
127
+ Include:
128
+ - What content is allowed
129
+ - What content is prohibited (hate speech, harassment, illegal content, etc.)
130
+ - How violations are reported
131
+ - How we handle violations (warning, removal, ban)
132
+ - Appeal process
133
+
134
+ Save to docs/content-policy.md`,
135
+ condition: (p) => p.hasUserContent,
136
+ },
137
+ // ⚠️ ASSISTABLE - AI can create guide, needs professional verification
138
+ GDPR_COMPLIANCE: {
139
+ key: 'GDPR_COMPLIANCE',
140
+ category: 'Compliance',
141
+ tier: 'assistable',
142
+ headline: 'GDPR applies to your product',
143
+ explanation: 'You\'re targeting EU users. You need lawful basis for data processing, user consent, and data rights.',
144
+ priority: 'critical',
145
+ alsoNeeded: ['Legal review of implementation', 'DPA registration if required', 'Data Processing Agreements with vendors'],
146
+ promptTemplate: `Create a GDPR compliance implementation guide for this project.
147
+
148
+ Based on analysis:
149
+ - Data collected: {{dataCollected}}
150
+ - Processing purposes: {{processingPurposes}}
151
+ - Third parties: {{thirdParties}}
152
+
153
+ Generate:
154
+ 1. Data inventory table (what data, why collected, legal basis, retention period)
155
+ 2. Consent flow requirements (what needs explicit consent vs legitimate interest)
156
+ 3. User rights implementation checklist:
157
+ - Right to access (export user data)
158
+ - Right to rectification (edit profile)
159
+ - Right to erasure (delete account)
160
+ - Right to portability (download data)
161
+ 4. Cookie consent requirements
162
+ 5. Privacy by design checklist
163
+
164
+ Save to docs/gdpr-implementation.md
165
+
166
+ Note at top: "This is a technical implementation guide. Legal review required before launch."`,
167
+ condition: (p) => p.targetsEU && p.collectsUserData,
168
+ },
169
+ CCPA_COMPLIANCE: {
170
+ key: 'CCPA_COMPLIANCE',
171
+ category: 'Compliance',
172
+ tier: 'assistable',
173
+ headline: 'CCPA applies to your product',
174
+ explanation: 'California users have rights to know, delete, and opt-out of data sales.',
175
+ priority: 'high',
176
+ alsoNeeded: ['Legal review', '"Do Not Sell" link if applicable'],
177
+ promptTemplate: `Create a CCPA compliance checklist for this project.
178
+
179
+ Data collected: {{dataCollected}}
180
+ California users expected: Yes
181
+
182
+ Include:
183
+ 1. Right to know (disclosure of data collected)
184
+ 2. Right to delete implementation
185
+ 3. Right to opt-out (if selling data)
186
+ 4. Non-discrimination requirements
187
+ 5. Privacy policy updates needed for CCPA
188
+
189
+ Save to docs/ccpa-checklist.md`,
190
+ condition: (p) => p.targetsCalifornia && p.collectsUserData,
191
+ },
192
+ ACCESSIBILITY: {
193
+ key: 'ACCESSIBILITY',
194
+ category: 'Inclusion',
195
+ tier: 'assistable',
196
+ headline: 'Consider accessibility (WCAG)',
197
+ explanation: 'Making your product accessible helps more users and may be legally required for some customers.',
198
+ priority: 'medium',
199
+ alsoNeeded: ['Actual testing with screen readers', 'User testing with diverse users'],
200
+ promptTemplate: `Create an accessibility checklist and implementation guide for this project.
201
+
202
+ Review the codebase and create:
203
+ 1. WCAG 2.1 AA compliance checklist with current status
204
+ 2. Priority fixes needed (semantic HTML, ARIA labels, color contrast)
205
+ 3. Keyboard navigation requirements
206
+ 4. Screen reader compatibility notes
207
+ 5. Form accessibility (labels, error messages)
208
+
209
+ For each issue found, provide the fix.
210
+
211
+ Save checklist to docs/accessibility-checklist.md`,
212
+ condition: (p) => p.targetAudience.some(a => ['enterprise', 'education', 'government'].includes(a)) || p.collectsUserData,
213
+ },
214
+ BIAS_ASSESSMENT: {
215
+ key: 'BIAS_ASSESSMENT',
216
+ category: 'Ethics',
217
+ tier: 'assistable',
218
+ headline: 'AI bias assessment needed',
219
+ explanation: 'AI that makes decisions about people can have unintended bias. Document what you\'ve considered.',
220
+ priority: 'high',
221
+ alsoNeeded: ['Testing with diverse user groups', 'Regular monitoring for bias', 'Human override mechanism'],
222
+ promptTemplate: `Create an AI bias assessment document for this project.
223
+
224
+ AI is used for: {{aiUsage}}
225
+ Decisions affected: {{decisionsAffected}}
226
+
227
+ Document:
228
+ 1. What decisions the AI influences
229
+ 2. Potential sources of bias (training data, model architecture)
230
+ 3. Protected characteristics that could be affected
231
+ 4. Mitigation strategies implemented
232
+ 5. Monitoring plan for detecting bias
233
+ 6. Human override / appeal mechanism
234
+
235
+ Save to docs/ai-bias-assessment.md
236
+
237
+ This is for internal documentation and transparency.`,
238
+ condition: (p) => p.aiMakesDecisions,
239
+ },
240
+ // ❌ HUMAN ONLY - Requires real-world action
241
+ PAYMENT_SETUP: {
242
+ key: 'PAYMENT_SETUP',
243
+ category: 'Business',
244
+ tier: 'human_only',
245
+ headline: 'You need payment processing',
246
+ explanation: 'You want to charge users. You need a payment provider account first.',
247
+ priority: 'critical',
248
+ humanSteps: [
249
+ 'Go to stripe.com and create an account',
250
+ 'Complete business verification (1-3 days)',
251
+ 'Set up your bank account for payouts',
252
+ 'Get your API keys from the dashboard',
253
+ ],
254
+ externalLinks: ['https://stripe.com', 'https://stripe.com/docs/keys'],
255
+ promptTemplate: `Implement Stripe payment integration for this project.
256
+
257
+ Requirements from PRD:
258
+ - Business model: {{businessModel}}
259
+ - Pricing: {{pricing}}
260
+
261
+ Implement:
262
+ 1. Stripe SDK setup with environment variables for keys
263
+ 2. Checkout session creation for {{checkoutType}}
264
+ 3. Webhook handler for payment events (payment_intent.succeeded, subscription events)
265
+ 4. Customer portal link for subscription management
266
+ 5. Subscription status middleware to gate premium features
267
+
268
+ I have my Stripe API keys ready. Use STRIPE_SECRET_KEY and STRIPE_PUBLISHABLE_KEY env vars.`,
269
+ condition: (p) => p.hasPayments,
270
+ },
271
+ BUSINESS_REGISTRATION: {
272
+ key: 'BUSINESS_REGISTRATION',
273
+ category: 'Legal',
274
+ tier: 'human_only',
275
+ headline: 'Consider business registration',
276
+ explanation: 'If you\'re making money, you may need a business entity for taxes and liability protection.',
277
+ priority: 'medium',
278
+ humanSteps: [
279
+ 'Research business structures (LLC, Corp, Sole Prop)',
280
+ 'Register in your state/country',
281
+ 'Get an EIN (US) or equivalent tax ID',
282
+ 'Open a business bank account',
283
+ ],
284
+ externalLinks: ['https://www.sba.gov/business-guide/launch-your-business/choose-business-structure'],
285
+ promptTemplate: `No code needed. This is a business/legal step.
286
+
287
+ Once you have your business set up, update your docs:
288
+ - Add business name to privacy policy and terms
289
+ - Add business address to contact information
290
+ - Update payment provider with business details`,
291
+ condition: (p) => p.hasPayments && p.businessModel !== 'free',
292
+ },
293
+ TAX_SETUP: {
294
+ key: 'TAX_SETUP',
295
+ category: 'Business',
296
+ tier: 'human_only',
297
+ headline: 'You need tax handling',
298
+ explanation: 'Selling internationally means dealing with VAT, GST, and sales tax. Stripe Tax can help.',
299
+ priority: 'high',
300
+ humanSteps: [
301
+ 'Enable Stripe Tax in your Stripe dashboard',
302
+ 'Register for VAT/GST in required jurisdictions',
303
+ 'Or use a service like Paddle that handles tax for you',
304
+ ],
305
+ externalLinks: ['https://stripe.com/tax', 'https://paddle.com'],
306
+ promptTemplate: `Add Stripe Tax integration to handle VAT/GST automatically.
307
+
308
+ Enable tax calculation in checkout:
309
+ 1. Add tax_behavior: 'exclusive' or 'inclusive' to prices
310
+ 2. Enable automatic_tax in checkout sessions
311
+ 3. Collect customer address for tax calculation
312
+ 4. Display tax amounts in checkout UI
313
+
314
+ See Stripe Tax docs for jurisdiction-specific setup.`,
315
+ condition: (p) => p.hasPayments && p.targetsEU,
316
+ },
317
+ DOMAIN_SSL: {
318
+ key: 'DOMAIN_SSL',
319
+ category: 'Infrastructure',
320
+ tier: 'human_only',
321
+ headline: 'You need a domain and SSL',
322
+ explanation: 'To launch publicly, you need a domain name and HTTPS.',
323
+ priority: 'high',
324
+ humanSteps: [
325
+ 'Choose and purchase a domain (Namecheap, Cloudflare, etc.)',
326
+ 'Point DNS to your hosting provider',
327
+ 'SSL is usually automatic with modern hosts (Vercel, Netlify, etc.)',
328
+ ],
329
+ externalLinks: ['https://www.namecheap.com', 'https://www.cloudflare.com'],
330
+ promptTemplate: `No code needed for domain purchase.
331
+
332
+ Once you have your domain, update:
333
+ 1. Environment variables with production URL
334
+ 2. OAuth redirect URLs if using social login
335
+ 3. Stripe webhook URLs
336
+ 4. Any hardcoded localhost references`,
337
+ condition: (p) => p.collectsUserData || p.hasPayments,
338
+ },
339
+ APP_STORE: {
340
+ key: 'APP_STORE',
341
+ category: 'Distribution',
342
+ tier: 'human_only',
343
+ headline: 'App Store submission needed',
344
+ explanation: 'Mobile apps need App Store / Play Store developer accounts and review.',
345
+ priority: 'critical',
346
+ humanSteps: [
347
+ 'Apple: Enroll in Apple Developer Program ($99/year)',
348
+ 'Google: Create Google Play Developer account ($25 one-time)',
349
+ 'Prepare screenshots, descriptions, privacy policy URL',
350
+ 'Submit for review (Apple: 1-7 days, Google: hours to days)',
351
+ ],
352
+ externalLinks: ['https://developer.apple.com/programs/', 'https://play.google.com/console'],
353
+ promptTemplate: `Prepare app store submission materials:
354
+
355
+ 1. Generate app screenshots for required sizes
356
+ 2. Write app store description (short and long)
357
+ 3. Create app preview video (optional but recommended)
358
+ 4. Prepare answers for review questions (data usage, permissions)
359
+ 5. Ensure privacy policy URL is live and accessible
360
+
361
+ Check that the app follows platform guidelines before submission.`,
362
+ condition: (p) => p.targetAudience.includes('mobile'),
363
+ },
364
+ COPPA_COMPLIANCE: {
365
+ key: 'COPPA_COMPLIANCE',
366
+ category: 'Compliance',
367
+ tier: 'human_only',
368
+ headline: 'COPPA compliance required',
369
+ explanation: 'Users under 13 require parental consent and special data handling.',
370
+ priority: 'critical',
371
+ humanSteps: [
372
+ 'Implement age gate / verification',
373
+ 'Get verifiable parental consent mechanism',
374
+ 'Limit data collection for children',
375
+ 'Review with lawyer specializing in children\'s privacy',
376
+ ],
377
+ externalLinks: ['https://www.ftc.gov/business-guidance/resources/complying-coppa-frequently-asked-questions'],
378
+ alsoNeeded: ['Legal review', 'Parental consent mechanism'],
379
+ promptTemplate: `Implement COPPA-compliant age verification:
380
+
381
+ 1. Add age gate before registration
382
+ 2. If under 13, collect parent email
383
+ 3. Send parental consent request
384
+ 4. Only allow account creation after consent verified
385
+ 5. Limit data collection for child accounts
386
+ 6. Add easy way for parents to review/delete child data
387
+
388
+ This requires careful legal review - the FTC enforces COPPA strictly.`,
389
+ condition: (p) => p.hasUnder13Users,
390
+ },
391
+ SOC2: {
392
+ key: 'SOC2',
393
+ category: 'Certification',
394
+ tier: 'human_only',
395
+ headline: 'Enterprise customers may require SOC 2',
396
+ explanation: 'B2B/enterprise sales often require SOC 2 certification to prove security practices.',
397
+ priority: 'medium',
398
+ humanSteps: [
399
+ 'This is a 6-12 month process costing $20K-100K+',
400
+ 'Choose a SOC 2 auditor (Vanta, Drata can help automate)',
401
+ 'Implement required controls',
402
+ 'Undergo Type I then Type II audit',
403
+ ],
404
+ externalLinks: ['https://vanta.com', 'https://drata.com'],
405
+ promptTemplate: `SOC 2 is a certification process, not code.
406
+
407
+ However, you can prepare by implementing:
408
+ 1. Access control (role-based permissions, MFA)
409
+ 2. Audit logging (who did what, when)
410
+ 3. Encryption at rest and in transit
411
+ 4. Incident response procedures
412
+ 5. Vendor management documentation
413
+
414
+ Create a security checklist: docs/security-checklist.md`,
415
+ condition: (p) => p.targetAudience.includes('enterprise'),
416
+ },
417
+ };
418
+ // ============================================================================
419
+ // INFERENCE FUNCTIONS
420
+ // ============================================================================
421
+ /**
422
+ * Infer project profile from brainlift, PRD, and package.json
423
+ */
424
+ export function inferProjectProfile(projectPath) {
425
+ const safePath = sanitizePath(projectPath);
426
+ const profile = {
427
+ collectsUserData: false,
428
+ collectsSensitiveData: false,
429
+ hasUnder13Users: false,
430
+ targetsEU: false,
431
+ targetsCalifornia: false,
432
+ hasPayments: false,
433
+ hasSubscriptions: false,
434
+ hasUserContent: false,
435
+ usesAI: false,
436
+ aiMakesDecisions: false,
437
+ isOpenSource: false,
438
+ targetAudience: [],
439
+ businessModel: 'free',
440
+ industry: [],
441
+ };
442
+ // Read docs
443
+ const brainliftPath = join(safePath, 'docs', 'brainlift.md');
444
+ const prdPath = join(safePath, 'docs', 'prd.md');
445
+ const readmePath = join(safePath, 'README.md');
446
+ const packagePath = join(safePath, 'package.json');
447
+ let content = '';
448
+ if (existsSync(brainliftPath)) {
449
+ content += readFileSync(brainliftPath, 'utf-8').toLowerCase() + '\n';
450
+ }
451
+ if (existsSync(prdPath)) {
452
+ content += readFileSync(prdPath, 'utf-8').toLowerCase() + '\n';
453
+ }
454
+ if (existsSync(readmePath)) {
455
+ content += readFileSync(readmePath, 'utf-8').toLowerCase() + '\n';
456
+ }
457
+ // Package.json analysis
458
+ if (existsSync(packagePath)) {
459
+ try {
460
+ const pkg = JSON.parse(readFileSync(packagePath, 'utf-8'));
461
+ const deps = Object.keys(pkg.dependencies || {}).join(' ').toLowerCase();
462
+ const allContent = JSON.stringify(pkg).toLowerCase();
463
+ // Check for payment libraries
464
+ if (deps.includes('stripe') || deps.includes('paypal') || deps.includes('paddle')) {
465
+ profile.hasPayments = true;
466
+ }
467
+ // Check for AI libraries
468
+ if (deps.includes('openai') || deps.includes('anthropic') || deps.includes('langchain') || deps.includes('ai')) {
469
+ profile.usesAI = true;
470
+ }
471
+ // Check for auth (implies user data)
472
+ if (deps.includes('next-auth') || deps.includes('passport') || deps.includes('clerk') || deps.includes('auth0') || deps.includes('firebase')) {
473
+ profile.collectsUserData = true;
474
+ }
475
+ // Open source check
476
+ if (pkg.license && pkg.license !== 'UNLICENSED' && pkg.license !== 'proprietary') {
477
+ profile.isOpenSource = true;
478
+ }
479
+ content += allContent + '\n';
480
+ }
481
+ catch { /* ignore parse errors */ }
482
+ }
483
+ // Keyword analysis
484
+ const keywords = {
485
+ // User data
486
+ collectsUserData: ['user', 'account', 'login', 'signup', 'register', 'email', 'profile', 'auth'],
487
+ collectsSensitiveData: ['health', 'medical', 'financial', 'bank', 'credit', 'ssn', 'biometric', 'face', 'fingerprint'],
488
+ hasUnder13Users: ['kids', 'children', 'child', 'k-12', 'elementary', 'middle school', 'under 13'],
489
+ targetsEU: ['eu', 'europe', 'european', 'gdpr', 'uk', 'germany', 'france', 'spain', 'global', 'international', 'worldwide'],
490
+ targetsCalifornia: ['california', 'ccpa', 'us', 'usa', 'united states', 'global', 'international'],
491
+ hasPayments: ['payment', 'subscribe', 'subscription', 'premium', 'paid', 'pricing', 'monetize', 'charge', 'stripe', 'billing', 'freemium', 'pro plan'],
492
+ hasSubscriptions: ['subscription', 'monthly', 'yearly', 'annual', 'recurring', 'plan'],
493
+ hasUserContent: ['upload', 'post', 'share', 'comment', 'create content', 'user generated', 'ugc', 'community'],
494
+ usesAI: ['ai', 'artificial intelligence', 'machine learning', 'ml', 'gpt', 'llm', 'claude', 'openai', 'generate', 'recommend'],
495
+ aiMakesDecisions: ['recommend', 'suggest', 'decide', 'score', 'rank', 'filter', 'personalize', 'match'],
496
+ };
497
+ for (const [key, terms] of Object.entries(keywords)) {
498
+ if (terms.some(term => content.includes(term))) {
499
+ profile[key] = true;
500
+ }
501
+ }
502
+ // Target audience inference
503
+ if (content.includes('student') || content.includes('education') || content.includes('learn')) {
504
+ profile.targetAudience.push('students');
505
+ }
506
+ if (content.includes('enterprise') || content.includes('b2b') || content.includes('business') || content.includes('team')) {
507
+ profile.targetAudience.push('enterprise');
508
+ }
509
+ if (content.includes('developer') || content.includes('api') || content.includes('sdk')) {
510
+ profile.targetAudience.push('developers');
511
+ }
512
+ if (content.includes('mobile') || content.includes('ios') || content.includes('android') || content.includes('app store')) {
513
+ profile.targetAudience.push('mobile');
514
+ }
515
+ // Business model inference
516
+ if (content.includes('free') && !content.includes('freemium') && !content.includes('premium')) {
517
+ profile.businessModel = 'free';
518
+ }
519
+ else if (content.includes('freemium') || (content.includes('free') && content.includes('premium'))) {
520
+ profile.businessModel = 'freemium';
521
+ }
522
+ else if (content.includes('subscription') || content.includes('saas')) {
523
+ profile.businessModel = 'subscription';
524
+ }
525
+ else if (content.includes('enterprise') || content.includes('b2b')) {
526
+ profile.businessModel = 'b2b';
527
+ }
528
+ else if (profile.hasPayments) {
529
+ profile.businessModel = 'paid';
530
+ }
531
+ // Industry inference
532
+ if (content.includes('health') || content.includes('medical') || content.includes('patient')) {
533
+ profile.industry.push('healthcare');
534
+ }
535
+ if (content.includes('finance') || content.includes('banking') || content.includes('invest')) {
536
+ profile.industry.push('finance');
537
+ }
538
+ if (content.includes('education') || content.includes('school') || content.includes('course')) {
539
+ profile.industry.push('education');
540
+ }
541
+ return profile;
542
+ }
543
+ /**
544
+ * Generate context-aware prompt by filling in template variables
545
+ */
546
+ function fillPromptTemplate(template, profile, projectPath) {
547
+ const safePath = sanitizePath(projectPath);
548
+ // Read docs for context
549
+ let brainliftContent = '';
550
+ let prdContent = '';
551
+ const brainliftPath = join(safePath, 'docs', 'brainlift.md');
552
+ const prdPath = join(safePath, 'docs', 'prd.md');
553
+ if (existsSync(brainliftPath)) {
554
+ brainliftContent = readFileSync(brainliftPath, 'utf-8').slice(0, 1000);
555
+ }
556
+ if (existsSync(prdPath)) {
557
+ prdContent = readFileSync(prdPath, 'utf-8').slice(0, 1000);
558
+ }
559
+ // Build replacements
560
+ const replacements = {
561
+ '{{dataCollected}}': profile.collectsSensitiveData
562
+ ? 'user accounts, emails, and sensitive data (health/financial)'
563
+ : profile.collectsUserData
564
+ ? 'user accounts, emails, preferences'
565
+ : 'minimal data',
566
+ '{{targetUsers}}': profile.targetAudience.length > 0
567
+ ? profile.targetAudience.join(', ')
568
+ : 'general users',
569
+ '{{businessModel}}': profile.businessModel,
570
+ '{{productType}}': profile.usesAI ? 'AI-powered application' : 'web application',
571
+ '{{keyFeatures}}': brainliftContent.slice(0, 200) || 'See brainlift for details',
572
+ '{{aiUsage}}': profile.usesAI ? 'AI features (see brainlift for specifics)' : 'No AI',
573
+ '{{processingPurposes}}': 'account management, service delivery, analytics',
574
+ '{{thirdParties}}': profile.hasPayments ? 'Stripe for payments, analytics provider' : 'analytics provider',
575
+ '{{subscriptionType}}': profile.hasSubscriptions ? 'recurring subscription' : 'one-time purchase',
576
+ '{{userContentType}}': 'create and share content',
577
+ '{{decisionsAffected}}': 'recommendations, personalization',
578
+ '{{pricing}}': 'See PRD for pricing details',
579
+ '{{checkoutType}}': profile.hasSubscriptions ? 'subscription' : 'one-time payment',
580
+ };
581
+ let result = template;
582
+ for (const [key, value] of Object.entries(replacements)) {
583
+ result = result.replace(new RegExp(key.replace(/[{}]/g, '\\$&'), 'g'), value);
584
+ }
585
+ return result;
586
+ }
587
+ /**
588
+ * Get all applicable reality checks for a project
589
+ */
590
+ export function getRealityChecks(projectPath) {
591
+ const profile = inferProjectProfile(projectPath);
592
+ const checks = [];
593
+ for (const check of Object.values(REALITY_CHECKS)) {
594
+ if (check.condition(profile)) {
595
+ const cursorPrompt = fillPromptTemplate(check.promptTemplate, profile, projectPath);
596
+ checks.push({
597
+ key: check.key,
598
+ category: check.category,
599
+ tier: check.tier,
600
+ headline: check.headline,
601
+ explanation: check.explanation,
602
+ cursorPrompt,
603
+ humanSteps: check.humanSteps,
604
+ externalLinks: check.externalLinks,
605
+ alsoNeeded: check.alsoNeeded,
606
+ priority: check.priority,
607
+ });
608
+ }
609
+ }
610
+ // Sort by priority and tier
611
+ const priorityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
612
+ const tierOrder = { human_only: 0, assistable: 1, generatable: 2 };
613
+ checks.sort((a, b) => {
614
+ const priorityDiff = priorityOrder[a.priority] - priorityOrder[b.priority];
615
+ if (priorityDiff !== 0)
616
+ return priorityDiff;
617
+ return tierOrder[a.tier] - tierOrder[b.tier];
618
+ });
619
+ return {
620
+ profile,
621
+ checks,
622
+ summary: {
623
+ total: checks.length,
624
+ critical: checks.filter(c => c.priority === 'critical').length,
625
+ generatable: checks.filter(c => c.tier === 'generatable').length,
626
+ assistable: checks.filter(c => c.tier === 'assistable').length,
627
+ humanOnly: checks.filter(c => c.tier === 'human_only').length,
628
+ },
629
+ };
630
+ }
631
+ /**
632
+ * Get tier symbol for display
633
+ */
634
+ export function getTierSymbol(tier) {
635
+ switch (tier) {
636
+ case 'generatable': return '✅';
637
+ case 'assistable': return '⚠️';
638
+ case 'human_only': return '🔴';
639
+ }
640
+ }
641
+ /**
642
+ * Get tier description
643
+ */
644
+ export function getTierDescription(tier) {
645
+ switch (tier) {
646
+ case 'generatable': return 'AI can draft this';
647
+ case 'assistable': return 'AI can help, needs review';
648
+ case 'human_only': return 'You need to do this';
649
+ }
650
+ }
651
+ //# sourceMappingURL=reality.js.map