couchloop-eq-mcp 1.0.3 → 1.0.5

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 (285) hide show
  1. package/README.md +24 -11
  2. package/dist/clients/shrinkChatClient.js +1 -1
  3. package/dist/clients/shrinkChatClient.js.map +1 -1
  4. package/dist/developer/analyzers/bloat-detector.d.ts +89 -0
  5. package/dist/developer/analyzers/bloat-detector.d.ts.map +1 -0
  6. package/dist/developer/analyzers/bloat-detector.js +483 -0
  7. package/dist/developer/analyzers/bloat-detector.js.map +1 -0
  8. package/dist/developer/backup/auto-backup.d.ts +96 -0
  9. package/dist/developer/backup/auto-backup.d.ts.map +1 -0
  10. package/dist/developer/backup/auto-backup.js +346 -0
  11. package/dist/developer/backup/auto-backup.js.map +1 -0
  12. package/dist/developer/blockers/package-blocker.d.ts +33 -0
  13. package/dist/developer/blockers/package-blocker.d.ts.map +1 -0
  14. package/dist/developer/blockers/package-blocker.js +224 -0
  15. package/dist/developer/blockers/package-blocker.js.map +1 -0
  16. package/dist/developer/evaluators/ai-error-preventer.d.ts +54 -0
  17. package/dist/developer/evaluators/ai-error-preventer.d.ts.map +1 -0
  18. package/dist/developer/evaluators/ai-error-preventer.js +270 -0
  19. package/dist/developer/evaluators/ai-error-preventer.js.map +1 -0
  20. package/dist/developer/evaluators/build-context-detector.d.ts +44 -0
  21. package/dist/developer/evaluators/build-context-detector.d.ts.map +1 -0
  22. package/dist/developer/evaluators/build-context-detector.js +258 -0
  23. package/dist/developer/evaluators/build-context-detector.js.map +1 -0
  24. package/dist/developer/evaluators/package-evaluator.d.ts +37 -0
  25. package/dist/developer/evaluators/package-evaluator.d.ts.map +1 -0
  26. package/dist/developer/evaluators/package-evaluator.js +278 -0
  27. package/dist/developer/evaluators/package-evaluator.js.map +1 -0
  28. package/dist/developer/guards/file-guardian.d.ts +79 -0
  29. package/dist/developer/guards/file-guardian.d.ts.map +1 -0
  30. package/dist/developer/guards/file-guardian.js +309 -0
  31. package/dist/developer/guards/file-guardian.js.map +1 -0
  32. package/dist/developer/managers/context-manager.d.ts +61 -0
  33. package/dist/developer/managers/context-manager.d.ts.map +1 -0
  34. package/dist/developer/managers/context-manager.js +302 -0
  35. package/dist/developer/managers/context-manager.js.map +1 -0
  36. package/dist/developer/metrics/complexity-calculator.d.ts +52 -0
  37. package/dist/developer/metrics/complexity-calculator.d.ts.map +1 -0
  38. package/dist/developer/metrics/complexity-calculator.js +259 -0
  39. package/dist/developer/metrics/complexity-calculator.js.map +1 -0
  40. package/dist/developer/reports/review-summary.d.ts +49 -0
  41. package/dist/developer/reports/review-summary.d.ts.map +1 -0
  42. package/dist/developer/reports/review-summary.js +249 -0
  43. package/dist/developer/reports/review-summary.js.map +1 -0
  44. package/dist/developer/scanners/review-assistant.d.ts +41 -0
  45. package/dist/developer/scanners/review-assistant.d.ts.map +1 -0
  46. package/dist/developer/scanners/review-assistant.js +374 -0
  47. package/dist/developer/scanners/review-assistant.js.map +1 -0
  48. package/dist/developer/scanners/secret-scanner.d.ts +66 -0
  49. package/dist/developer/scanners/secret-scanner.d.ts.map +1 -0
  50. package/dist/developer/scanners/secret-scanner.js +287 -0
  51. package/dist/developer/scanners/secret-scanner.js.map +1 -0
  52. package/dist/developer/scanners/sql-injection-detector.d.ts +54 -0
  53. package/dist/developer/scanners/sql-injection-detector.d.ts.map +1 -0
  54. package/dist/developer/scanners/sql-injection-detector.js +174 -0
  55. package/dist/developer/scanners/sql-injection-detector.js.map +1 -0
  56. package/dist/developer/scanners/xss-detector.d.ts +60 -0
  57. package/dist/developer/scanners/xss-detector.d.ts.map +1 -0
  58. package/dist/developer/scanners/xss-detector.js +229 -0
  59. package/dist/developer/scanners/xss-detector.js.map +1 -0
  60. package/dist/developer/types/ai-errors.d.ts +34 -0
  61. package/dist/developer/types/ai-errors.d.ts.map +1 -0
  62. package/dist/developer/types/ai-errors.js +271 -0
  63. package/dist/developer/types/ai-errors.js.map +1 -0
  64. package/dist/developer/types/package.d.ts +32 -0
  65. package/dist/developer/types/package.d.ts.map +1 -0
  66. package/dist/developer/types/package.js +5 -0
  67. package/dist/developer/types/package.js.map +1 -0
  68. package/dist/developer/updaters/dependency-updater.d.ts +102 -0
  69. package/dist/developer/updaters/dependency-updater.d.ts.map +1 -0
  70. package/dist/developer/updaters/dependency-updater.js +472 -0
  71. package/dist/developer/updaters/dependency-updater.js.map +1 -0
  72. package/dist/developer/validators/cargo.d.ts +14 -0
  73. package/dist/developer/validators/cargo.d.ts.map +1 -0
  74. package/dist/developer/validators/cargo.js +132 -0
  75. package/dist/developer/validators/cargo.js.map +1 -0
  76. package/dist/developer/validators/gem.d.ts +14 -0
  77. package/dist/developer/validators/gem.d.ts.map +1 -0
  78. package/dist/developer/validators/gem.js +85 -0
  79. package/dist/developer/validators/gem.js.map +1 -0
  80. package/dist/developer/validators/go.d.ts +14 -0
  81. package/dist/developer/validators/go.d.ts.map +1 -0
  82. package/dist/developer/validators/go.js +138 -0
  83. package/dist/developer/validators/go.js.map +1 -0
  84. package/dist/developer/validators/maven.d.ts +14 -0
  85. package/dist/developer/validators/maven.d.ts.map +1 -0
  86. package/dist/developer/validators/maven.js +99 -0
  87. package/dist/developer/validators/maven.js.map +1 -0
  88. package/dist/developer/validators/npm.d.ts +14 -0
  89. package/dist/developer/validators/npm.d.ts.map +1 -0
  90. package/dist/developer/validators/npm.js +96 -0
  91. package/dist/developer/validators/npm.js.map +1 -0
  92. package/dist/developer/validators/nuget.d.ts +15 -0
  93. package/dist/developer/validators/nuget.d.ts.map +1 -0
  94. package/dist/developer/validators/nuget.js +107 -0
  95. package/dist/developer/validators/nuget.js.map +1 -0
  96. package/dist/developer/validators/pypi.d.ts +14 -0
  97. package/dist/developer/validators/pypi.d.ts.map +1 -0
  98. package/dist/developer/validators/pypi.js +118 -0
  99. package/dist/developer/validators/pypi.js.map +1 -0
  100. package/dist/developer/validators/registry-manager.d.ts +37 -0
  101. package/dist/developer/validators/registry-manager.d.ts.map +1 -0
  102. package/dist/developer/validators/registry-manager.js +89 -0
  103. package/dist/developer/validators/registry-manager.js.map +1 -0
  104. package/dist/developer/validators/version-checker.d.ts +145 -0
  105. package/dist/developer/validators/version-checker.d.ts.map +1 -0
  106. package/dist/developer/validators/version-checker.js +529 -0
  107. package/dist/developer/validators/version-checker.js.map +1 -0
  108. package/dist/server/index.js.map +1 -1
  109. package/dist/server/middleware/auth.d.ts +7 -9
  110. package/dist/server/middleware/auth.d.ts.map +1 -1
  111. package/dist/server/middleware/auth.js.map +1 -1
  112. package/dist/tools/check-versions.d.ts +100 -0
  113. package/dist/tools/check-versions.d.ts.map +1 -0
  114. package/dist/tools/check-versions.js +328 -0
  115. package/dist/tools/check-versions.js.map +1 -0
  116. package/dist/tools/detect-code-smell.d.ts +9 -0
  117. package/dist/tools/detect-code-smell.d.ts.map +1 -0
  118. package/dist/tools/detect-code-smell.js +231 -0
  119. package/dist/tools/detect-code-smell.js.map +1 -0
  120. package/dist/tools/index.d.ts +471 -0
  121. package/dist/tools/index.d.ts.map +1 -1
  122. package/dist/tools/index.js +178 -0
  123. package/dist/tools/index.js.map +1 -1
  124. package/dist/tools/journey.js +1 -1
  125. package/dist/tools/journey.js.map +1 -1
  126. package/dist/tools/pre-review-code.d.ts +71 -0
  127. package/dist/tools/pre-review-code.d.ts.map +1 -0
  128. package/dist/tools/pre-review-code.js +159 -0
  129. package/dist/tools/pre-review-code.js.map +1 -0
  130. package/dist/tools/preserve-context.d.ts +27 -0
  131. package/dist/tools/preserve-context.d.ts.map +1 -0
  132. package/dist/tools/preserve-context.js +98 -0
  133. package/dist/tools/preserve-context.js.map +1 -0
  134. package/dist/tools/protect-files.d.ts +224 -0
  135. package/dist/tools/protect-files.d.ts.map +1 -0
  136. package/dist/tools/protect-files.js +286 -0
  137. package/dist/tools/protect-files.js.map +1 -0
  138. package/dist/tools/scan-security.d.ts +38 -0
  139. package/dist/tools/scan-security.d.ts.map +1 -0
  140. package/dist/tools/scan-security.js +237 -0
  141. package/dist/tools/scan-security.js.map +1 -0
  142. package/dist/tools/validate_packages.d.ts +8 -0
  143. package/dist/tools/validate_packages.d.ts.map +1 -0
  144. package/dist/tools/validate_packages.js +159 -0
  145. package/dist/tools/validate_packages.js.map +1 -0
  146. package/dist/types/auth.d.ts +18 -18
  147. package/dist/types/auth.d.ts.map +1 -1
  148. package/dist/types/auth.js +91 -36
  149. package/dist/types/auth.js.map +1 -1
  150. package/dist/types/context.d.ts +46 -0
  151. package/dist/types/context.d.ts.map +1 -0
  152. package/dist/types/context.js +17 -0
  153. package/dist/types/context.js.map +1 -0
  154. package/dist/types/file-protection.d.ts +50 -0
  155. package/dist/types/file-protection.d.ts.map +1 -0
  156. package/dist/types/file-protection.js +9 -0
  157. package/dist/types/file-protection.js.map +1 -0
  158. package/dist/utils/errorHandler.d.ts.map +1 -1
  159. package/dist/utils/errorHandler.js +2 -1
  160. package/dist/utils/errorHandler.js.map +1 -1
  161. package/package.json +23 -2
  162. package/dist/db/migrate.d.ts +0 -4
  163. package/dist/db/migrate.d.ts.map +0 -1
  164. package/dist/db/migrate.js +0 -34
  165. package/dist/db/migrate.js.map +0 -1
  166. package/dist/db/migrations/schema.d.ts +0 -1074
  167. package/dist/db/migrations/schema.d.ts.map +0 -1
  168. package/dist/db/migrations/schema.js +0 -160
  169. package/dist/db/migrations/schema.js.map +0 -1
  170. package/dist/db/schema.d.ts +0 -1576
  171. package/dist/db/schema.d.ts.map +0 -1
  172. package/dist/db/schema.js +0 -204
  173. package/dist/db/schema.js.map +0 -1
  174. package/dist/db/seed.d.ts +0 -4
  175. package/dist/db/seed.d.ts.map +0 -1
  176. package/dist/db/seed.js +0 -57
  177. package/dist/db/seed.js.map +0 -1
  178. package/dist/db/seedOAuth.d.ts +0 -4
  179. package/dist/db/seedOAuth.d.ts.map +0 -1
  180. package/dist/db/seedOAuth.js +0 -76
  181. package/dist/db/seedOAuth.js.map +0 -1
  182. package/dist/governance/config.d.ts +0 -66
  183. package/dist/governance/config.d.ts.map +0 -1
  184. package/dist/governance/config.js +0 -238
  185. package/dist/governance/config.js.map +0 -1
  186. package/dist/governance/detectors/hallucination.d.ts +0 -61
  187. package/dist/governance/detectors/hallucination.d.ts.map +0 -1
  188. package/dist/governance/detectors/hallucination.js +0 -338
  189. package/dist/governance/detectors/hallucination.js.map +0 -1
  190. package/dist/governance/detectors/inconsistency.d.ts +0 -99
  191. package/dist/governance/detectors/inconsistency.d.ts.map +0 -1
  192. package/dist/governance/detectors/inconsistency.js +0 -548
  193. package/dist/governance/detectors/inconsistency.js.map +0 -1
  194. package/dist/governance/detectors/toneDrift.d.ts +0 -63
  195. package/dist/governance/detectors/toneDrift.d.ts.map +0 -1
  196. package/dist/governance/detectors/toneDrift.js +0 -421
  197. package/dist/governance/detectors/toneDrift.js.map +0 -1
  198. package/dist/governance/detectors/unsafeReasoning.d.ts +0 -54
  199. package/dist/governance/detectors/unsafeReasoning.d.ts.map +0 -1
  200. package/dist/governance/detectors/unsafeReasoning.js +0 -473
  201. package/dist/governance/detectors/unsafeReasoning.js.map +0 -1
  202. package/dist/governance/evaluationEngine.d.ts +0 -112
  203. package/dist/governance/evaluationEngine.d.ts.map +0 -1
  204. package/dist/governance/evaluationEngine.js +0 -265
  205. package/dist/governance/evaluationEngine.js.map +0 -1
  206. package/dist/governance/intervention.d.ts +0 -81
  207. package/dist/governance/intervention.d.ts.map +0 -1
  208. package/dist/governance/intervention.js +0 -405
  209. package/dist/governance/intervention.js.map +0 -1
  210. package/dist/server/oauth/anomalyDetection.d.ts +0 -146
  211. package/dist/server/oauth/anomalyDetection.d.ts.map +0 -1
  212. package/dist/server/oauth/anomalyDetection.js +0 -405
  213. package/dist/server/oauth/anomalyDetection.js.map +0 -1
  214. package/dist/server/oauth/authServer.d.ts +0 -61
  215. package/dist/server/oauth/authServer.d.ts.map +0 -1
  216. package/dist/server/oauth/authServer.js +0 -283
  217. package/dist/server/oauth/authServer.js.map +0 -1
  218. package/dist/server/oauth/dpop.d.ts +0 -135
  219. package/dist/server/oauth/dpop.d.ts.map +0 -1
  220. package/dist/server/oauth/dpop.js +0 -338
  221. package/dist/server/oauth/dpop.js.map +0 -1
  222. package/dist/server/oauth/gdpr/consent.d.ts +0 -173
  223. package/dist/server/oauth/gdpr/consent.d.ts.map +0 -1
  224. package/dist/server/oauth/gdpr/consent.js +0 -388
  225. package/dist/server/oauth/gdpr/consent.js.map +0 -1
  226. package/dist/server/oauth/gdpr/dataPortability.d.ts +0 -214
  227. package/dist/server/oauth/gdpr/dataPortability.d.ts.map +0 -1
  228. package/dist/server/oauth/gdpr/dataPortability.js +0 -486
  229. package/dist/server/oauth/gdpr/dataPortability.js.map +0 -1
  230. package/dist/server/oauth/gdpr/index.d.ts +0 -103
  231. package/dist/server/oauth/gdpr/index.d.ts.map +0 -1
  232. package/dist/server/oauth/gdpr/index.js +0 -273
  233. package/dist/server/oauth/gdpr/index.js.map +0 -1
  234. package/dist/server/oauth/gdpr/rightToErasure.d.ts +0 -184
  235. package/dist/server/oauth/gdpr/rightToErasure.d.ts.map +0 -1
  236. package/dist/server/oauth/gdpr/rightToErasure.js +0 -527
  237. package/dist/server/oauth/gdpr/rightToErasure.js.map +0 -1
  238. package/dist/server/oauth/monitoring/securityMonitor.d.ts +0 -218
  239. package/dist/server/oauth/monitoring/securityMonitor.d.ts.map +0 -1
  240. package/dist/server/oauth/monitoring/securityMonitor.js +0 -615
  241. package/dist/server/oauth/monitoring/securityMonitor.js.map +0 -1
  242. package/dist/server/oauth/pkce.d.ts +0 -61
  243. package/dist/server/oauth/pkce.d.ts.map +0 -1
  244. package/dist/server/oauth/pkce.js +0 -157
  245. package/dist/server/oauth/pkce.js.map +0 -1
  246. package/dist/server/oauth/providers/base.d.ts +0 -147
  247. package/dist/server/oauth/providers/base.d.ts.map +0 -1
  248. package/dist/server/oauth/providers/base.js +0 -312
  249. package/dist/server/oauth/providers/base.js.map +0 -1
  250. package/dist/server/oauth/providers/github.d.ts +0 -55
  251. package/dist/server/oauth/providers/github.d.ts.map +0 -1
  252. package/dist/server/oauth/providers/github.js +0 -225
  253. package/dist/server/oauth/providers/github.js.map +0 -1
  254. package/dist/server/oauth/providers/google.d.ts +0 -49
  255. package/dist/server/oauth/providers/google.d.ts.map +0 -1
  256. package/dist/server/oauth/providers/google.js +0 -153
  257. package/dist/server/oauth/providers/google.js.map +0 -1
  258. package/dist/server/oauth/providers/index.d.ts +0 -9
  259. package/dist/server/oauth/providers/index.d.ts.map +0 -1
  260. package/dist/server/oauth/providers/index.js +0 -24
  261. package/dist/server/oauth/providers/index.js.map +0 -1
  262. package/dist/server/oauth/refreshTokenRotation.d.ts +0 -114
  263. package/dist/server/oauth/refreshTokenRotation.d.ts.map +0 -1
  264. package/dist/server/oauth/refreshTokenRotation.js +0 -344
  265. package/dist/server/oauth/refreshTokenRotation.js.map +0 -1
  266. package/dist/server/oauth/security.d.ts +0 -101
  267. package/dist/server/oauth/security.d.ts.map +0 -1
  268. package/dist/server/oauth/security.js +0 -268
  269. package/dist/server/oauth/security.js.map +0 -1
  270. package/dist/server/oauth/tokenEncryption.d.ts +0 -80
  271. package/dist/server/oauth/tokenEncryption.d.ts.map +0 -1
  272. package/dist/server/oauth/tokenEncryption.js +0 -218
  273. package/dist/server/oauth/tokenEncryption.js.map +0 -1
  274. package/dist/tools/sendMessage-complex-backup.d.ts +0 -6
  275. package/dist/tools/sendMessage-complex-backup.d.ts.map +0 -1
  276. package/dist/tools/sendMessage-complex-backup.js +0 -545
  277. package/dist/tools/sendMessage-complex-backup.js.map +0 -1
  278. package/dist/tools/sendMessage-revised.d.ts +0 -11
  279. package/dist/tools/sendMessage-revised.d.ts.map +0 -1
  280. package/dist/tools/sendMessage-revised.js +0 -429
  281. package/dist/tools/sendMessage-revised.js.map +0 -1
  282. package/dist/tools/sendMessage-truly-simple.d.ts +0 -8
  283. package/dist/tools/sendMessage-truly-simple.d.ts.map +0 -1
  284. package/dist/tools/sendMessage-truly-simple.js +0 -299
  285. package/dist/tools/sendMessage-truly-simple.js.map +0 -1
@@ -0,0 +1,237 @@
1
+ /**
2
+ * MCP Tool: scan_security
3
+ * Comprehensive security vulnerability scanner for AI-generated code
4
+ * Detects SQL injection, XSS, hardcoded secrets, and other security issues
5
+ */
6
+ import { z } from 'zod';
7
+ import { SqlInjectionDetector } from '../developer/scanners/sql-injection-detector.js';
8
+ import { XssDetector } from '../developer/scanners/xss-detector.js';
9
+ import { SecretScanner } from '../developer/scanners/secret-scanner.js';
10
+ import { logger } from '../utils/logger.js';
11
+ const inputSchema = z.object({
12
+ code: z.string().describe('Code snippet to scan for security vulnerabilities'),
13
+ language: z.enum(['javascript', 'typescript', 'python', 'java', 'sql', 'html', 'unknown']).default('javascript').describe('Programming language of the code'),
14
+ scanType: z.enum(['quick', 'thorough']).default('thorough').describe('Scan depth: quick (essential) or thorough (comprehensive)'),
15
+ });
16
+ export const scanSecurityTool = {
17
+ name: 'scan_security',
18
+ description: 'Comprehensive security scanner for AI-generated code. Detects SQL injection, XSS, hardcoded secrets, and other vulnerabilities with CWE codes and secure alternatives.',
19
+ inputSchema: {
20
+ type: 'object',
21
+ properties: {
22
+ code: {
23
+ type: 'string',
24
+ description: 'Code snippet to scan for security vulnerabilities'
25
+ },
26
+ language: {
27
+ type: 'string',
28
+ enum: ['javascript', 'typescript', 'python', 'java', 'sql', 'html', 'unknown'],
29
+ default: 'javascript',
30
+ description: 'Programming language of the code'
31
+ },
32
+ scanType: {
33
+ type: 'string',
34
+ enum: ['quick', 'thorough'],
35
+ default: 'thorough',
36
+ description: 'Scan depth: quick (essential checks) or thorough (comprehensive)'
37
+ }
38
+ },
39
+ required: ['code']
40
+ }
41
+ };
42
+ export async function handleScanSecurity(input) {
43
+ try {
44
+ const params = inputSchema.parse(input);
45
+ logger.info(`Security scan requested for ${params.language} code (${params.scanType} mode)`);
46
+ const vulnerabilities = [];
47
+ // Run appropriate scanners based on language and scan type
48
+ if (params.scanType === 'thorough' || ['javascript', 'typescript', 'sql'].includes(params.language)) {
49
+ const sqlDetector = new SqlInjectionDetector();
50
+ const sqlVulns = sqlDetector.scan(params.code);
51
+ vulnerabilities.push(...formatVulnerabilities(sqlVulns, 'SQLInjectionDetector'));
52
+ }
53
+ if (params.scanType === 'thorough' || ['javascript', 'typescript', 'html', 'python', 'java'].includes(params.language)) {
54
+ const xssDetector = new XssDetector();
55
+ const xssVulns = xssDetector.scan(params.code);
56
+ vulnerabilities.push(...formatVulnerabilities(xssVulns, 'XssDetector'));
57
+ }
58
+ if (params.scanType === 'thorough' || ['javascript', 'typescript', 'python', 'java'].includes(params.language)) {
59
+ const secretScanner = new SecretScanner();
60
+ const secretVulns = secretScanner.scan(params.code);
61
+ vulnerabilities.push(...formatVulnerabilities(secretVulns, 'SecretScanner'));
62
+ }
63
+ // Sort by severity and line number
64
+ vulnerabilities.sort((a, b) => {
65
+ const severityOrder = { CRITICAL: 0, HIGH: 1, MEDIUM: 2, LOW: 3 };
66
+ const aSeverity = severityOrder[a.severity] ?? 4;
67
+ const bSeverity = severityOrder[b.severity] ?? 4;
68
+ if (aSeverity !== bSeverity)
69
+ return aSeverity - bSeverity;
70
+ return a.line - b.line;
71
+ });
72
+ // Calculate summary
73
+ const summary = calculateSummary(vulnerabilities, params.language, params.scanType);
74
+ // Generate recommendations
75
+ const recommendations = generateRecommendations(vulnerabilities);
76
+ // Generate developer notes
77
+ const developerNotes = generateDeveloperNotes(vulnerabilities, params.language);
78
+ // Determine overall risk level
79
+ const riskLevel = determineRiskLevel(summary);
80
+ const result = {
81
+ summary,
82
+ vulnerabilities,
83
+ riskLevel,
84
+ recommendations,
85
+ developerNotes,
86
+ };
87
+ logger.info(`Security scan completed: ${vulnerabilities.length} vulnerabilities found (${summary.critical} critical, ${summary.high} high)`);
88
+ return result;
89
+ }
90
+ catch (error) {
91
+ logger.error('Error during security scan:', error);
92
+ if (error instanceof z.ZodError) {
93
+ return {
94
+ summary: {
95
+ totalVulnerabilities: 0,
96
+ critical: 0,
97
+ high: 0,
98
+ medium: 0,
99
+ low: 0,
100
+ language: 'unknown',
101
+ scanType: 'thorough',
102
+ },
103
+ vulnerabilities: [],
104
+ riskLevel: 'SAFE',
105
+ recommendations: ['Invalid input provided to security scanner'],
106
+ developerNotes: `Validation error: ${error.message}`,
107
+ };
108
+ }
109
+ return {
110
+ summary: {
111
+ totalVulnerabilities: 0,
112
+ critical: 0,
113
+ high: 0,
114
+ medium: 0,
115
+ low: 0,
116
+ language: 'unknown',
117
+ scanType: 'thorough',
118
+ },
119
+ vulnerabilities: [],
120
+ riskLevel: 'SAFE',
121
+ recommendations: ['An error occurred during scanning'],
122
+ developerNotes: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
123
+ };
124
+ }
125
+ }
126
+ /**
127
+ * Format vulnerabilities from scanners to unified format
128
+ */
129
+ function formatVulnerabilities(vulns, scannerName) {
130
+ return vulns.map(vuln => ({
131
+ ...vuln,
132
+ scanner: scannerName,
133
+ }));
134
+ }
135
+ /**
136
+ * Calculate vulnerability summary
137
+ */
138
+ function calculateSummary(vulnerabilities, language, scanType) {
139
+ const counts = {
140
+ CRITICAL: 0,
141
+ HIGH: 0,
142
+ MEDIUM: 0,
143
+ LOW: 0,
144
+ };
145
+ for (const vuln of vulnerabilities) {
146
+ counts[vuln.severity]++;
147
+ }
148
+ return {
149
+ totalVulnerabilities: vulnerabilities.length,
150
+ critical: counts.CRITICAL,
151
+ high: counts.HIGH,
152
+ medium: counts.MEDIUM,
153
+ low: counts.LOW,
154
+ language,
155
+ scanType,
156
+ };
157
+ }
158
+ /**
159
+ * Generate recommendations based on vulnerabilities found
160
+ */
161
+ function generateRecommendations(vulnerabilities) {
162
+ const recommendations = new Set();
163
+ // Group vulnerabilities by type
164
+ const hasSQL = vulnerabilities.some(v => v.type === 'SQL_INJECTION' || v.type === 'UNPARAMETERIZED_QUERY');
165
+ const hasXSS = vulnerabilities.some(v => v.type?.includes('XSS') || v.type?.includes('INNERHTML'));
166
+ const hasSecrets = vulnerabilities.some(v => v.type === 'HARDCODED_API_KEY' || v.type === 'HARDCODED_PASSWORD');
167
+ if (hasSQL) {
168
+ recommendations.add('Use parameterized queries for all database operations. Never concatenate user input directly into SQL strings.');
169
+ recommendations.add('Consider using an ORM like Prisma, Drizzle, or TypeORM that handle SQL injection prevention automatically.');
170
+ recommendations.add('Validate and whitelist all dynamic table and column names using strict allowlists.');
171
+ }
172
+ if (hasXSS) {
173
+ recommendations.add('Use textContent instead of innerHTML for displaying user-provided text.');
174
+ recommendations.add('Always sanitize untrusted HTML using libraries like DOMPurify before rendering.');
175
+ recommendations.add('Use content security policies (CSP) to prevent inline script execution.');
176
+ recommendations.add('Never use eval() or Function() constructors with user input.');
177
+ recommendations.add('In React, prefer component composition over dangerouslySetInnerHTML.');
178
+ }
179
+ if (hasSecrets) {
180
+ recommendations.add('Move all secrets to environment variables (.env files, never commit these).');
181
+ recommendations.add('Use a secrets management system: AWS Secrets Manager, HashiCorp Vault, or cloud provider equivalents.');
182
+ recommendations.add('Rotate all exposed credentials immediately - they may be compromised.');
183
+ recommendations.add('Implement pre-commit hooks to prevent secrets from being committed.');
184
+ }
185
+ // General recommendations
186
+ recommendations.add('Enable OWASP dependency scanning in your CI/CD pipeline (npm audit, Snyk, etc.).');
187
+ recommendations.add('Implement automated security scanning in code review process.');
188
+ recommendations.add('Conduct regular security audits of AI-generated code before deployment.');
189
+ recommendations.add('Use security linters: ESLint security plugins, Semgrep, or SonarQube.');
190
+ return Array.from(recommendations);
191
+ }
192
+ /**
193
+ * Generate developer-friendly notes
194
+ */
195
+ function generateDeveloperNotes(vulnerabilities, language) {
196
+ const criticalCount = vulnerabilities.filter(v => v.severity === 'CRITICAL').length;
197
+ const highCount = vulnerabilities.filter(v => v.severity === 'HIGH').length;
198
+ if (vulnerabilities.length === 0) {
199
+ return `Good news! No security vulnerabilities detected in this ${language} code snippet during scanning. ✓`;
200
+ }
201
+ let notes = `Security scan found ${vulnerabilities.length} potential issue(s) in this ${language} code:\n`;
202
+ if (criticalCount > 0) {
203
+ notes += `\n🔴 CRITICAL (${criticalCount}): These vulnerabilities could lead to immediate security breaches. Fix these before any deployment.\n`;
204
+ }
205
+ if (highCount > 0) {
206
+ notes += `\n🟠 HIGH (${highCount}): Serious security issues that should be fixed as soon as possible.\n`;
207
+ }
208
+ const mediumCount = vulnerabilities.filter(v => v.severity === 'MEDIUM').length;
209
+ if (mediumCount > 0) {
210
+ notes += `\n🟡 MEDIUM (${mediumCount}): Important security improvements to make.\n`;
211
+ }
212
+ notes += `\n📋 Each vulnerability includes:
213
+ - The specific code location (line number)
214
+ - CWE code for security reference
215
+ - Clear explanation of the risk
216
+ - Secure code example for fixing
217
+
218
+ ⚠️ Research Finding: 80% of AI-generated code contains security vulnerabilities. Developers are 3.5x more likely to think insecure code is secure. Always review AI-generated code with security in mind.`;
219
+ return notes;
220
+ }
221
+ /**
222
+ * Determine overall risk level
223
+ */
224
+ function determineRiskLevel(summary) {
225
+ if (summary.critical > 0)
226
+ return 'CRITICAL';
227
+ if (summary.high >= 3)
228
+ return 'CRITICAL';
229
+ if (summary.high > 0)
230
+ return 'HIGH';
231
+ if (summary.medium >= 3)
232
+ return 'MEDIUM';
233
+ if (summary.medium > 0)
234
+ return 'LOW';
235
+ return 'SAFE';
236
+ }
237
+ //# sourceMappingURL=scan-security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-security.js","sourceRoot":"","sources":["../../src/tools/scan-security.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * MCP Tool: validate_packages
3
+ * Validates package dependencies and prevents hallucinated packages
4
+ */
5
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
6
+ export declare const validatePackagesTool: Tool;
7
+ export declare function handleValidatePackages(input: unknown): Promise<object>;
8
+ //# sourceMappingURL=validate_packages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate_packages.d.ts","sourceRoot":"","sources":["../../src/tools/validate_packages.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAgB1D,eAAO,MAAM,oBAAoB,EAAE,IA0ClC,CAAC;AAEF,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CA2F5E"}
@@ -0,0 +1,159 @@
1
+ /**
2
+ * MCP Tool: validate_packages
3
+ * Validates package dependencies and prevents hallucinated packages
4
+ */
5
+ import { z } from 'zod';
6
+ import { PackageBlocker } from '../developer/blockers/package-blocker.js';
7
+ import { PackageEvaluator } from '../developer/evaluators/package-evaluator.js';
8
+ const inputSchema = z.object({
9
+ code: z.string().optional().describe('Code snippet containing package imports/requires'),
10
+ command: z.string().optional().describe('Package manager command (npm install, pip install, etc.)'),
11
+ packages: z.array(z.object({
12
+ name: z.string(),
13
+ version: z.string().optional(),
14
+ registry: z.enum(['npm', 'pypi', 'maven']).optional()
15
+ })).optional().describe('Array of packages to validate'),
16
+ language: z.enum(['javascript', 'typescript', 'python', 'java', 'unknown']).default('unknown'),
17
+ autoFix: z.boolean().default(true).describe('Automatically fix package names when possible')
18
+ });
19
+ export const validatePackagesTool = {
20
+ name: 'validate_packages',
21
+ description: 'Validate package dependencies to prevent installation of non-existent or malicious packages',
22
+ inputSchema: {
23
+ type: 'object',
24
+ properties: {
25
+ code: {
26
+ type: 'string',
27
+ description: 'Code snippet containing package imports/requires'
28
+ },
29
+ command: {
30
+ type: 'string',
31
+ description: 'Package manager command (npm install, pip install, etc.)'
32
+ },
33
+ packages: {
34
+ type: 'array',
35
+ items: {
36
+ type: 'object',
37
+ properties: {
38
+ name: { type: 'string' },
39
+ version: { type: 'string' },
40
+ registry: {
41
+ type: 'string',
42
+ enum: ['npm', 'pypi', 'maven']
43
+ }
44
+ },
45
+ required: ['name']
46
+ },
47
+ description: 'Array of packages to validate'
48
+ },
49
+ language: {
50
+ type: 'string',
51
+ enum: ['javascript', 'typescript', 'python', 'java', 'unknown'],
52
+ default: 'unknown'
53
+ },
54
+ autoFix: {
55
+ type: 'boolean',
56
+ default: true,
57
+ description: 'Automatically fix package names when possible'
58
+ }
59
+ }
60
+ }
61
+ };
62
+ export async function handleValidatePackages(input) {
63
+ try {
64
+ const params = inputSchema.parse(input);
65
+ const blocker = new PackageBlocker(params.autoFix);
66
+ const evaluator = new PackageEvaluator();
67
+ // Handle code validation
68
+ if (params.code) {
69
+ const result = await blocker.interceptCode(params.code, params.language);
70
+ return {
71
+ type: 'code_validation',
72
+ allowed: result.allowed,
73
+ blockedPackages: result.blockedPackages,
74
+ warnings: result.warnings,
75
+ suggestions: result.suggestions,
76
+ modifiedCode: result.modified,
77
+ summary: generateSummary(result.blockedPackages, result.warnings)
78
+ };
79
+ }
80
+ // Handle command validation
81
+ if (params.command) {
82
+ const result = await blocker.interceptCommand(params.command);
83
+ return {
84
+ type: 'command_validation',
85
+ allowed: result.allowed,
86
+ blockedPackages: result.blockedPackages,
87
+ warnings: result.warnings,
88
+ suggestions: result.suggestions,
89
+ modifiedCommand: result.modified,
90
+ summary: generateSummary(result.blockedPackages, result.warnings)
91
+ };
92
+ }
93
+ // Handle direct package list validation
94
+ if (params.packages && params.packages.length > 0) {
95
+ const results = await Promise.all(params.packages.map(async (pkg) => {
96
+ const evaluation = await evaluator.evaluate(pkg.name, { language: params.language }, pkg.version);
97
+ return {
98
+ package: pkg.name,
99
+ version: pkg.version,
100
+ exists: evaluation.package.exists,
101
+ blocked: evaluation.blocked,
102
+ reason: evaluation.reason,
103
+ warnings: evaluation.warning,
104
+ suggestions: evaluation.suggestions,
105
+ latestVersion: evaluation.package.latestVersion,
106
+ deprecated: evaluation.package.deprecated,
107
+ securityIssues: evaluation.package.securityIssues
108
+ };
109
+ }));
110
+ const blockedCount = results.filter(r => r.blocked).length;
111
+ const warningCount = results.filter(r => r.warnings).length;
112
+ return {
113
+ type: 'package_validation',
114
+ packages: results,
115
+ summary: {
116
+ total: results.length,
117
+ valid: results.filter(r => r.exists && !r.blocked).length,
118
+ blocked: blockedCount,
119
+ warnings: warningCount,
120
+ message: blockedCount > 0
121
+ ? `⚠️ ${blockedCount} package(s) blocked - they don't exist or have issues`
122
+ : warningCount > 0
123
+ ? `✓ All packages exist but ${warningCount} have warnings`
124
+ : '✅ All packages validated successfully'
125
+ }
126
+ };
127
+ }
128
+ return {
129
+ error: 'No input provided. Please provide code, command, or packages to validate.'
130
+ };
131
+ }
132
+ catch (error) {
133
+ console.error('Package validation error:', error);
134
+ return {
135
+ error: error instanceof Error ? error.message : 'Failed to validate packages'
136
+ };
137
+ }
138
+ }
139
+ function generateSummary(blockedPackages, warnings) {
140
+ if (blockedPackages.length === 0 && warnings.length === 0) {
141
+ return {
142
+ status: 'success',
143
+ message: '✅ All packages validated successfully'
144
+ };
145
+ }
146
+ if (blockedPackages.length > 0) {
147
+ return {
148
+ status: 'blocked',
149
+ message: `❌ Blocked ${blockedPackages.length} non-existent/malicious package(s)`,
150
+ details: `Prevented installation of: ${blockedPackages.join(', ')}`
151
+ };
152
+ }
153
+ return {
154
+ status: 'warning',
155
+ message: `⚠️ ${warnings.length} warning(s) found`,
156
+ details: warnings[0] // Show first warning
157
+ };
158
+ }
159
+ //# sourceMappingURL=validate_packages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate_packages.js","sourceRoot":"","sources":["../../src/tools/validate_packages.ts"],"names":[],"mappings":"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"}
@@ -4,25 +4,9 @@ import { z } from 'zod';
4
4
  * This allows the AI agent to provide user authentication info
5
5
  */
6
6
  export declare const AuthContextSchema: z.ZodObject<{
7
- /**
8
- * OAuth access token or session identifier
9
- * This will be validated against the OAuth tokens table
10
- */
11
7
  token: z.ZodOptional<z.ZodString>;
12
- /**
13
- * External user identifier (from OAuth provider)
14
- * Used as a fallback if token validation fails
15
- */
16
8
  user_id: z.ZodOptional<z.ZodString>;
17
- /**
18
- * Client identifier (ChatGPT, Claude, etc.)
19
- * Helps track which AI agent is making the request
20
- */
21
9
  client_id: z.ZodOptional<z.ZodString>;
22
- /**
23
- * Stable conversation identifier for user binding
24
- * Used to generate persistent user IDs for MCP clients without OAuth
25
- */
26
10
  conversation_id: z.ZodOptional<z.ZodString>;
27
11
  }, "strip", z.ZodTypeAny, {
28
12
  user_id?: string | undefined;
@@ -38,8 +22,24 @@ export declare const AuthContextSchema: z.ZodObject<{
38
22
  export type AuthContext = z.infer<typeof AuthContextSchema>;
39
23
  /**
40
24
  * Extract user ID from authentication context
41
- * Implements secure hash-based persistent identity for MCP clients
42
- * Falls back to ephemeral IDs only when no stable context is available
25
+ * Implements tiered identity:
26
+ * - Priority 1: OAuth token validation (Pro tier - cross-device)
27
+ * - Priority 2: External user ID + client ID (ChatGPT OAuth)
28
+ * - Priority 3: Local file-based identity (Free tier - single machine)
29
+ * - Priority 4: Conversation-based ID (single window only)
30
+ * - Fallback: Ephemeral IDs (no persistence)
43
31
  */
44
32
  export declare function extractUserFromContext(authContext?: AuthContext): Promise<string>;
33
+ /**
34
+ * Get user tier from identity prefix
35
+ */
36
+ export declare function getUserTier(userId: string): 'pro' | 'free' | 'ephemeral';
37
+ /**
38
+ * Check if user has Pro tier features
39
+ */
40
+ export declare function hasProFeatures(userId: string): boolean;
41
+ /**
42
+ * Get the local identity file path for debugging/support
43
+ */
44
+ export declare function getIdentityFilePath(): string;
45
45
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/types/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;GAGG;AACH,eAAO,MAAM,iBAAiB;IAC5B;;;OAGG;;IAGH;;;OAGG;;IAGH;;;OAGG;;IAGH;;;OAGG;;;;;;;;;;;;EAEH,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D;;;;GAIG;AACH,wBAAsB,sBAAsB,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAwCvF"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/types/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;EAK5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AA0D5D;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAwCvF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,WAAW,CAMxE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C"}
@@ -1,71 +1,126 @@
1
1
  import { z } from 'zod';
2
2
  import { createHash } from 'crypto';
3
+ import { homedir, hostname } from 'os';
4
+ import { join } from 'path';
5
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
3
6
  /**
4
7
  * Authentication context that can be passed through MCP tool calls
5
8
  * This allows the AI agent to provide user authentication info
6
9
  */
7
10
  export const AuthContextSchema = z.object({
8
- /**
9
- * OAuth access token or session identifier
10
- * This will be validated against the OAuth tokens table
11
- */
12
11
  token: z.string().optional().describe('OAuth access token or session identifier'),
13
- /**
14
- * External user identifier (from OAuth provider)
15
- * Used as a fallback if token validation fails
16
- */
17
12
  user_id: z.string().optional().describe('External user identifier from OAuth provider'),
18
- /**
19
- * Client identifier (ChatGPT, Claude, etc.)
20
- * Helps track which AI agent is making the request
21
- */
22
13
  client_id: z.string().optional().describe('Client application identifier'),
23
- /**
24
- * Stable conversation identifier for user binding
25
- * Used to generate persistent user IDs for MCP clients without OAuth
26
- */
27
14
  conversation_id: z.string().optional().describe('Stable conversation identifier for user binding'),
28
15
  });
16
+ const IDENTITY_DIR = join(homedir(), '.couchloop-mcp');
17
+ const IDENTITY_FILE = join(IDENTITY_DIR, 'identity.json');
18
+ /**
19
+ * Get or create local identity file for free tier users
20
+ * This provides single-machine persistence without requiring OAuth
21
+ */
22
+ function getOrCreateLocalIdentity() {
23
+ try {
24
+ // Ensure directory exists
25
+ if (!existsSync(IDENTITY_DIR)) {
26
+ mkdirSync(IDENTITY_DIR, { recursive: true });
27
+ }
28
+ // Check if identity file exists
29
+ if (existsSync(IDENTITY_FILE)) {
30
+ const data = readFileSync(IDENTITY_FILE, 'utf-8');
31
+ const identity = JSON.parse(data);
32
+ if (identity.user_id && identity.user_id.startsWith('local_')) {
33
+ return identity.user_id;
34
+ }
35
+ }
36
+ // Create new local identity
37
+ const machineId = createHash('sha256')
38
+ .update(hostname() + ':' + homedir() + ':' + Date.now())
39
+ .digest('hex')
40
+ .substring(0, 24);
41
+ const newIdentity = {
42
+ user_id: 'local_' + machineId,
43
+ created_at: new Date().toISOString(),
44
+ machine: hostname(),
45
+ tier: 'free',
46
+ };
47
+ writeFileSync(IDENTITY_FILE, JSON.stringify(newIdentity, null, 2));
48
+ console.log('Created local identity: ' + newIdentity.user_id + ' at ' + IDENTITY_FILE);
49
+ return newIdentity.user_id;
50
+ }
51
+ catch (error) {
52
+ console.warn('Failed to create/read local identity file:', error);
53
+ return '';
54
+ }
55
+ }
29
56
  /**
30
57
  * Extract user ID from authentication context
31
- * Implements secure hash-based persistent identity for MCP clients
32
- * Falls back to ephemeral IDs only when no stable context is available
58
+ * Implements tiered identity:
59
+ * - Priority 1: OAuth token validation (Pro tier - cross-device)
60
+ * - Priority 2: External user ID + client ID (ChatGPT OAuth)
61
+ * - Priority 3: Local file-based identity (Free tier - single machine)
62
+ * - Priority 4: Conversation-based ID (single window only)
63
+ * - Fallback: Ephemeral IDs (no persistence)
33
64
  */
34
65
  export async function extractUserFromContext(authContext) {
35
- // Priority 1: Hash-based persistent ID from external user identifier
66
+ // Priority 1: OAuth token validation (Pro tier - future)
67
+ if (authContext?.token) {
68
+ const hash = createHash('sha256').update(authContext.token).digest('hex');
69
+ return 'oauth_' + hash.substring(0, 24);
70
+ }
71
+ // Priority 2: Hash-based persistent ID from external user identifier
36
72
  // For ChatGPT: this is the openai/subject that persists across all chat windows
37
- // We hash it to avoid storing any external PII
38
73
  if (authContext?.user_id && authContext?.client_id) {
39
74
  const hash = createHash('sha256')
40
- .update(`${authContext.client_id}:${authContext.user_id}`)
75
+ .update(authContext.client_id + ':' + authContext.user_id)
41
76
  .digest('hex');
42
- // Use client prefix to identify the source
43
- return `${authContext.client_id}_${hash.substring(0, 24)}`;
77
+ return authContext.client_id + '_' + hash.substring(0, 24);
44
78
  }
45
- // Priority 2: JWT token validation (future OAuth implementation)
46
- if (authContext?.token) {
47
- // TODO: Implement proper JWT validation and extraction
48
- // For now, use token as a temporary identifier
49
- return `oauth_${authContext.token.substring(0, 16)}`;
79
+ // Priority 3: Local file-based identity (Free tier)
80
+ // Provides single-machine persistence for VS Code, Cursor, Claude Desktop, etc.
81
+ const localIdentity = getOrCreateLocalIdentity();
82
+ if (localIdentity) {
83
+ return localIdentity;
50
84
  }
51
- // Priority 3: Conversation-based ID (single chat window only)
52
- // This is less ideal as it doesn't persist across windows
85
+ // Priority 4: Conversation-based ID (single chat window only)
53
86
  if (authContext?.client_id && authContext?.conversation_id) {
54
87
  const hash = createHash('sha256')
55
- .update(`${authContext.client_id}:conv:${authContext.conversation_id}`)
88
+ .update(authContext.client_id + ':conv:' + authContext.conversation_id)
56
89
  .digest('hex');
57
- // Use conv_ prefix to identify these as conversation-specific IDs
58
- return `conv_${hash.substring(0, 28)}`;
90
+ return 'conv_' + hash.substring(0, 28);
59
91
  }
60
92
  // Fallback: Create ephemeral user with warning
61
- // These should be cleaned up periodically as they indicate missing context
62
93
  console.warn('Creating ephemeral user - no stable identity provided', {
63
94
  client_id: authContext?.client_id,
64
95
  has_conversation_id: !!authContext?.conversation_id,
65
96
  timestamp: new Date().toISOString()
66
97
  });
67
98
  const { nanoid } = await import('nanoid');
68
- // Use ephemeral_ prefix to clearly identify temporary users
69
- return `ephemeral_${nanoid(12)}`;
99
+ return 'ephemeral_' + nanoid(12);
100
+ }
101
+ /**
102
+ * Get user tier from identity prefix
103
+ */
104
+ export function getUserTier(userId) {
105
+ if (userId.startsWith('oauth_'))
106
+ return 'pro';
107
+ if (userId.startsWith('local_'))
108
+ return 'free';
109
+ if (userId.startsWith('ephemeral_'))
110
+ return 'ephemeral';
111
+ // Client-based IDs (chatgpt_, claude_, etc.) could be either
112
+ return 'free';
113
+ }
114
+ /**
115
+ * Check if user has Pro tier features
116
+ */
117
+ export function hasProFeatures(userId) {
118
+ return getUserTier(userId) === 'pro';
119
+ }
120
+ /**
121
+ * Get the local identity file path for debugging/support
122
+ */
123
+ export function getIdentityFilePath() {
124
+ return IDENTITY_FILE;
70
125
  }
71
126
  //# sourceMappingURL=auth.js.map