contradiction-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +536 -0
  3. package/bin/cli.js +182 -0
  4. package/dist/analysis/claimMatcher.d.ts +48 -0
  5. package/dist/analysis/claimMatcher.js +131 -0
  6. package/dist/analysis/claimMatcher.js.map +1 -0
  7. package/dist/analysis/claimRelationship.d.ts +15 -0
  8. package/dist/analysis/claimRelationship.js +12 -0
  9. package/dist/analysis/claimRelationship.js.map +1 -0
  10. package/dist/analysis/confidenceScorer.d.ts +40 -0
  11. package/dist/analysis/confidenceScorer.js +59 -0
  12. package/dist/analysis/confidenceScorer.js.map +1 -0
  13. package/dist/analysis/contextAnalyzer.d.ts +13 -0
  14. package/dist/analysis/contextAnalyzer.js +187 -0
  15. package/dist/analysis/contextAnalyzer.js.map +1 -0
  16. package/dist/analysis/contradictionClassifier.d.ts +16 -0
  17. package/dist/analysis/contradictionClassifier.js +141 -0
  18. package/dist/analysis/contradictionClassifier.js.map +1 -0
  19. package/dist/analysis/contradictionEngine.d.ts +29 -0
  20. package/dist/analysis/contradictionEngine.js +284 -0
  21. package/dist/analysis/contradictionEngine.js.map +1 -0
  22. package/dist/analysis/explanationBuilder.d.ts +36 -0
  23. package/dist/analysis/explanationBuilder.js +77 -0
  24. package/dist/analysis/explanationBuilder.js.map +1 -0
  25. package/dist/analysis/valueComparator.d.ts +38 -0
  26. package/dist/analysis/valueComparator.js +418 -0
  27. package/dist/analysis/valueComparator.js.map +1 -0
  28. package/dist/config/env.d.ts +46 -0
  29. package/dist/config/env.js +34 -0
  30. package/dist/config/env.js.map +1 -0
  31. package/dist/connectors/base/connectorUtils.d.ts +26 -0
  32. package/dist/connectors/base/connectorUtils.js +63 -0
  33. package/dist/connectors/base/connectorUtils.js.map +1 -0
  34. package/dist/connectors/base/security.d.ts +11 -0
  35. package/dist/connectors/base/security.js +9 -0
  36. package/dist/connectors/base/security.js.map +1 -0
  37. package/dist/connectors/connectorRegistry.d.ts +43 -0
  38. package/dist/connectors/connectorRegistry.js +91 -0
  39. package/dist/connectors/connectorRegistry.js.map +1 -0
  40. package/dist/connectors/document/documentConnector.d.ts +45 -0
  41. package/dist/connectors/document/documentConnector.js +410 -0
  42. package/dist/connectors/document/documentConnector.js.map +1 -0
  43. package/dist/connectors/github/githubClient.d.ts +52 -0
  44. package/dist/connectors/github/githubClient.js +207 -0
  45. package/dist/connectors/github/githubClient.js.map +1 -0
  46. package/dist/connectors/github/githubConnector.d.ts +26 -0
  47. package/dist/connectors/github/githubConnector.js +169 -0
  48. package/dist/connectors/github/githubConnector.js.map +1 -0
  49. package/dist/connectors/github/githubExtractor.d.ts +26 -0
  50. package/dist/connectors/github/githubExtractor.js +469 -0
  51. package/dist/connectors/github/githubExtractor.js.map +1 -0
  52. package/dist/connectors/github/githubNormalizer.d.ts +11 -0
  53. package/dist/connectors/github/githubNormalizer.js +24 -0
  54. package/dist/connectors/github/githubNormalizer.js.map +1 -0
  55. package/dist/connectors/github/githubTypes.d.ts +55 -0
  56. package/dist/connectors/github/githubTypes.js +2 -0
  57. package/dist/connectors/github/githubTypes.js.map +1 -0
  58. package/dist/connectors/syncService.d.ts +60 -0
  59. package/dist/connectors/syncService.js +176 -0
  60. package/dist/connectors/syncService.js.map +1 -0
  61. package/dist/connectors/types/connector.d.ts +34 -0
  62. package/dist/connectors/types/connector.js +2 -0
  63. package/dist/connectors/types/connector.js.map +1 -0
  64. package/dist/connectors/types/fetchResult.d.ts +39 -0
  65. package/dist/connectors/types/fetchResult.js +2 -0
  66. package/dist/connectors/types/fetchResult.js.map +1 -0
  67. package/dist/connectors/website/ssrfGuard.d.ts +11 -0
  68. package/dist/connectors/website/ssrfGuard.js +122 -0
  69. package/dist/connectors/website/ssrfGuard.js.map +1 -0
  70. package/dist/connectors/website/websiteConnector.d.ts +30 -0
  71. package/dist/connectors/website/websiteConnector.js +231 -0
  72. package/dist/connectors/website/websiteConnector.js.map +1 -0
  73. package/dist/discovery/candidateGenerator.d.ts +12 -0
  74. package/dist/discovery/candidateGenerator.js +110 -0
  75. package/dist/discovery/candidateGenerator.js.map +1 -0
  76. package/dist/discovery/contradictionScanner.d.ts +30 -0
  77. package/dist/discovery/contradictionScanner.js +47 -0
  78. package/dist/discovery/contradictionScanner.js.map +1 -0
  79. package/dist/discovery/discoveryService.d.ts +37 -0
  80. package/dist/discovery/discoveryService.js +131 -0
  81. package/dist/discovery/discoveryService.js.map +1 -0
  82. package/dist/discovery/rankingService.d.ts +34 -0
  83. package/dist/discovery/rankingService.js +52 -0
  84. package/dist/discovery/rankingService.js.map +1 -0
  85. package/dist/discovery/similarityIndex.d.ts +20 -0
  86. package/dist/discovery/similarityIndex.js +89 -0
  87. package/dist/discovery/similarityIndex.js.map +1 -0
  88. package/dist/domain/entities/claim.d.ts +99 -0
  89. package/dist/domain/entities/claim.js +92 -0
  90. package/dist/domain/entities/claim.js.map +1 -0
  91. package/dist/domain/entities/contradiction.d.ts +110 -0
  92. package/dist/domain/entities/contradiction.js +74 -0
  93. package/dist/domain/entities/contradiction.js.map +1 -0
  94. package/dist/domain/entities/source.d.ts +43 -0
  95. package/dist/domain/entities/source.js +35 -0
  96. package/dist/domain/entities/source.js.map +1 -0
  97. package/dist/domain/types/common.d.ts +46 -0
  98. package/dist/domain/types/common.js +74 -0
  99. package/dist/domain/types/common.js.map +1 -0
  100. package/dist/httpServer.d.ts +25 -0
  101. package/dist/httpServer.js +164 -0
  102. package/dist/httpServer.js.map +1 -0
  103. package/dist/index.d.ts +1 -0
  104. package/dist/index.js +94 -0
  105. package/dist/index.js.map +1 -0
  106. package/dist/intelligence/authorityScorer.d.ts +20 -0
  107. package/dist/intelligence/authorityScorer.js +103 -0
  108. package/dist/intelligence/authorityScorer.js.map +1 -0
  109. package/dist/intelligence/entityResolver.d.ts +33 -0
  110. package/dist/intelligence/entityResolver.js +152 -0
  111. package/dist/intelligence/entityResolver.js.map +1 -0
  112. package/dist/intelligence/evidenceEvaluator.d.ts +15 -0
  113. package/dist/intelligence/evidenceEvaluator.js +63 -0
  114. package/dist/intelligence/evidenceEvaluator.js.map +1 -0
  115. package/dist/intelligence/freshnessScorer.d.ts +25 -0
  116. package/dist/intelligence/freshnessScorer.js +90 -0
  117. package/dist/intelligence/freshnessScorer.js.map +1 -0
  118. package/dist/intelligence/provenanceAnalyzer.d.ts +19 -0
  119. package/dist/intelligence/provenanceAnalyzer.js +33 -0
  120. package/dist/intelligence/provenanceAnalyzer.js.map +1 -0
  121. package/dist/intelligence/resolutionAdvisor.d.ts +40 -0
  122. package/dist/intelligence/resolutionAdvisor.js +118 -0
  123. package/dist/intelligence/resolutionAdvisor.js.map +1 -0
  124. package/dist/intelligence/semanticMatcher.d.ts +21 -0
  125. package/dist/intelligence/semanticMatcher.js +71 -0
  126. package/dist/intelligence/semanticMatcher.js.map +1 -0
  127. package/dist/scripts/comprehensiveVerification.d.ts +5 -0
  128. package/dist/scripts/comprehensiveVerification.js +961 -0
  129. package/dist/scripts/comprehensiveVerification.js.map +1 -0
  130. package/dist/scripts/finalLiveDemo.d.ts +5 -0
  131. package/dist/scripts/finalLiveDemo.js +226 -0
  132. package/dist/scripts/finalLiveDemo.js.map +1 -0
  133. package/dist/scripts/liveMcpSmoke.d.ts +1 -0
  134. package/dist/scripts/liveMcpSmoke.js +89 -0
  135. package/dist/scripts/liveMcpSmoke.js.map +1 -0
  136. package/dist/scripts/seedDemoData.d.ts +6 -0
  137. package/dist/scripts/seedDemoData.js +179 -0
  138. package/dist/scripts/seedDemoData.js.map +1 -0
  139. package/dist/server.d.ts +28 -0
  140. package/dist/server.js +1264 -0
  141. package/dist/server.js.map +1 -0
  142. package/dist/services/analysisService.d.ts +40 -0
  143. package/dist/services/analysisService.js +65 -0
  144. package/dist/services/analysisService.js.map +1 -0
  145. package/dist/services/healthService.d.ts +42 -0
  146. package/dist/services/healthService.js +50 -0
  147. package/dist/services/healthService.js.map +1 -0
  148. package/dist/services/metricsService.d.ts +35 -0
  149. package/dist/services/metricsService.js +57 -0
  150. package/dist/services/metricsService.js.map +1 -0
  151. package/dist/services/rateLimiter.d.ts +23 -0
  152. package/dist/services/rateLimiter.js +45 -0
  153. package/dist/services/rateLimiter.js.map +1 -0
  154. package/dist/services/reviewService.d.ts +32 -0
  155. package/dist/services/reviewService.js +94 -0
  156. package/dist/services/reviewService.js.map +1 -0
  157. package/dist/services/schedulerService.d.ts +30 -0
  158. package/dist/services/schedulerService.js +89 -0
  159. package/dist/services/schedulerService.js.map +1 -0
  160. package/dist/storage/backupService.d.ts +14 -0
  161. package/dist/storage/backupService.js +90 -0
  162. package/dist/storage/backupService.js.map +1 -0
  163. package/dist/storage/database.d.ts +119 -0
  164. package/dist/storage/database.js +935 -0
  165. package/dist/storage/database.js.map +1 -0
  166. package/dist/storage/migrations/001_initial.sql +63 -0
  167. package/dist/storage/migrations/002_discovery_uniqueness.sql +8 -0
  168. package/dist/storage/migrations/003_connector_identity.sql +7 -0
  169. package/dist/storage/migrations/004_claim_context.sql +15 -0
  170. package/dist/storage/migrations/005_claim_history.sql +26 -0
  171. package/dist/storage/migrations/006_contradiction_resolution.sql +27 -0
  172. package/dist/utils/logger.d.ts +20 -0
  173. package/dist/utils/logger.js +48 -0
  174. package/dist/utils/logger.js.map +1 -0
  175. package/package.json +73 -0
@@ -0,0 +1,418 @@
1
+ import semver from 'semver';
2
+ export class ValueComparator {
3
+ compare(valA, valB, explicitValueType) {
4
+ // Basic null/empty guards
5
+ const rawA = (valA ?? '').trim();
6
+ const rawB = (valB ?? '').trim();
7
+ if (rawA === '' && rawB === '') {
8
+ return {
9
+ comparable: true,
10
+ equal: true,
11
+ compatible: true,
12
+ normalizedA: '',
13
+ normalizedB: '',
14
+ valueType: explicitValueType || 'string',
15
+ differenceStrength: 0.0,
16
+ };
17
+ }
18
+ if (rawA === '' || rawB === '') {
19
+ return {
20
+ comparable: true,
21
+ equal: false,
22
+ compatible: false,
23
+ normalizedA: rawA,
24
+ normalizedB: rawB,
25
+ valueType: explicitValueType || 'string',
26
+ differenceStrength: 1.0,
27
+ differenceType: 'EMPTY_VS_NONEMPTY',
28
+ };
29
+ }
30
+ const valueType = (explicitValueType || this.inferValueType(rawA, rawB)).toLowerCase();
31
+ switch (valueType) {
32
+ case 'version':
33
+ return this.compareVersions(rawA, rawB);
34
+ case 'date':
35
+ return this.compareDates(rawA, rawB);
36
+ case 'price':
37
+ return this.comparePrices(rawA, rawB);
38
+ case 'number':
39
+ case 'quantity':
40
+ return this.compareNumbers(rawA, rawB, valueType);
41
+ case 'status':
42
+ return this.compareStatuses(rawA, rawB);
43
+ case 'boolean':
44
+ return this.compareBooleans(rawA, rawB);
45
+ default:
46
+ return this.compareStrings(rawA, rawB, valueType);
47
+ }
48
+ }
49
+ inferValueType(a, b) {
50
+ if (this.isLikelyVersion(a) && this.isLikelyVersion(b))
51
+ return 'version';
52
+ if (this.isLikelyDate(a) && this.isLikelyDate(b))
53
+ return 'date';
54
+ if (this.isLikelyPrice(a) || this.isLikelyPrice(b))
55
+ return 'price';
56
+ if (this.isLikelyNumber(a) && this.isLikelyNumber(b))
57
+ return 'number';
58
+ return 'string';
59
+ }
60
+ // --- VERSION COMPARISON ---
61
+ isLikelyVersion(str) {
62
+ return ((/\bv?\d+(\.\d+)*\b/i.test(str) && /(version|node|v\d|\d+\.\d+|[><=~^])/i.test(str)) ||
63
+ Boolean(semver.validRange(str)));
64
+ }
65
+ cleanSemverRange(val) {
66
+ const cleaned = val
67
+ .replace(/^(?:requires?|prerequisites?|node(?:\.js)?|version|v)?\s*[:=]?\s*/i, '')
68
+ .trim();
69
+ if (semver.validRange(cleaned)) {
70
+ return cleaned;
71
+ }
72
+ return null;
73
+ }
74
+ normalizeVersion(val) {
75
+ // Extract semver-like sequence (e.g., "Node 22" -> "22", "v20.10.0" -> "20.10.0")
76
+ const match = val.match(/\b(?:v|version)?\s*(\d+(?:\.\d+)*)\b/i);
77
+ if (!match)
78
+ return null;
79
+ const versionStr = match[1];
80
+ const segments = versionStr.split('.').map(Number);
81
+ return {
82
+ canonical: segments.join('.'),
83
+ segments,
84
+ };
85
+ }
86
+ compareVersions(a, b) {
87
+ const parsedA = this.normalizeVersion(a);
88
+ const parsedB = this.normalizeVersion(b);
89
+ // Exact string match or identical canonical representation
90
+ if (a === b && parsedA) {
91
+ return {
92
+ comparable: true,
93
+ equal: true,
94
+ compatible: true,
95
+ normalizedA: parsedA.canonical,
96
+ normalizedB: parsedA.canonical,
97
+ valueType: 'version',
98
+ differenceStrength: 0.0,
99
+ details: {
100
+ versionA: parsedA.canonical,
101
+ versionB: parsedA.canonical,
102
+ majorA: parsedA.segments[0],
103
+ majorB: parsedA.segments[0],
104
+ },
105
+ };
106
+ }
107
+ const rangeRegex = /[><=~^\s*|]/;
108
+ const cleanRangeA = this.cleanSemverRange(a);
109
+ const cleanRangeB = this.cleanSemverRange(b);
110
+ const hasRangeOpA = cleanRangeA !== null && rangeRegex.test(cleanRangeA);
111
+ const hasRangeOpB = cleanRangeB !== null && rangeRegex.test(cleanRangeB);
112
+ // 1. One is a SemVer range and the other is a concrete version
113
+ if (hasRangeOpA && !hasRangeOpB && cleanRangeA) {
114
+ const coercedB = semver.coerce(b);
115
+ if (coercedB && semver.valid(coercedB.version)) {
116
+ const satisfies = semver.satisfies(coercedB.version, cleanRangeA);
117
+ return {
118
+ comparable: true,
119
+ equal: false,
120
+ compatible: satisfies,
121
+ normalizedA: parsedA?.canonical || cleanRangeA,
122
+ normalizedB: coercedB.version,
123
+ valueType: 'version',
124
+ differenceStrength: satisfies ? 0.0 : 1.0,
125
+ differenceType: satisfies ? 'RANGE_SATISFIED' : 'RANGE_VIOLATION',
126
+ details: { range: cleanRangeA, version: coercedB.version, satisfies },
127
+ };
128
+ }
129
+ }
130
+ if (!hasRangeOpA && hasRangeOpB && cleanRangeB) {
131
+ const coercedA = semver.coerce(a);
132
+ if (coercedA && semver.valid(coercedA.version)) {
133
+ const satisfies = semver.satisfies(coercedA.version, cleanRangeB);
134
+ return {
135
+ comparable: true,
136
+ equal: false,
137
+ compatible: satisfies,
138
+ normalizedA: coercedA.version,
139
+ normalizedB: parsedB?.canonical || cleanRangeB,
140
+ valueType: 'version',
141
+ differenceStrength: satisfies ? 0.0 : 1.0,
142
+ differenceType: satisfies ? 'RANGE_SATISFIED' : 'RANGE_VIOLATION',
143
+ details: { range: cleanRangeB, version: coercedA.version, satisfies },
144
+ };
145
+ }
146
+ }
147
+ // 2. Both are SemVer ranges
148
+ if (hasRangeOpA && hasRangeOpB && cleanRangeA && cleanRangeB) {
149
+ const intersects = semver.intersects(cleanRangeA, cleanRangeB);
150
+ return {
151
+ comparable: true,
152
+ equal: cleanRangeA === cleanRangeB,
153
+ compatible: intersects,
154
+ normalizedA: parsedA?.canonical || cleanRangeA,
155
+ normalizedB: parsedB?.canonical || cleanRangeB,
156
+ valueType: 'version',
157
+ differenceStrength: intersects ? 0.0 : 1.0,
158
+ differenceType: intersects ? 'RANGES_INTERSECT' : 'DISJOINT_RANGES',
159
+ details: { rangeA: cleanRangeA, rangeB: cleanRangeB, intersects },
160
+ };
161
+ }
162
+ // 3. Fallback to exact / segment version comparison
163
+ if (!parsedA || !parsedB) {
164
+ return this.compareStrings(a, b, 'version');
165
+ }
166
+ const equal = parsedA.canonical === parsedB.canonical;
167
+ const majorA = parsedA.segments[0];
168
+ const majorB = parsedB.segments[0];
169
+ const majorMismatch = majorA !== majorB;
170
+ return {
171
+ comparable: true,
172
+ equal,
173
+ compatible: equal,
174
+ normalizedA: parsedA.canonical,
175
+ normalizedB: parsedB.canonical,
176
+ valueType: 'version',
177
+ differenceStrength: equal ? 0.0 : majorMismatch ? 1.0 : 0.6,
178
+ differenceType: equal
179
+ ? undefined
180
+ : majorMismatch
181
+ ? 'MAJOR_VERSION_MISMATCH'
182
+ : 'MINOR_VERSION_MISMATCH',
183
+ details: {
184
+ versionA: parsedA.canonical,
185
+ versionB: parsedB.canonical,
186
+ majorA,
187
+ majorB,
188
+ },
189
+ };
190
+ }
191
+ // --- DATE COMPARISON ---
192
+ isLikelyDate(str) {
193
+ return !isNaN(Date.parse(str)) && /\d/.test(str);
194
+ }
195
+ normalizeDate(val) {
196
+ // Check if ISO format YYYY-MM-DD
197
+ const isoMatch = val.match(/^(\d{4})-(\d{1,2})-(\d{1,2})/);
198
+ if (isoMatch) {
199
+ const year = isoMatch[1];
200
+ const month = isoMatch[2].padStart(2, '0');
201
+ const day = isoMatch[3].padStart(2, '0');
202
+ return `${year}-${month}-${day}`;
203
+ }
204
+ // Check for DD/MM/YYYY or MM/DD/YYYY format
205
+ const slashMatch = val.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/);
206
+ if (slashMatch) {
207
+ const p1 = Number(slashMatch[1]);
208
+ const p2 = Number(slashMatch[2]);
209
+ const year = slashMatch[3];
210
+ if (p1 > 12) {
211
+ // DD/MM/YYYY
212
+ return `${year}-${String(p2).padStart(2, '0')}-${String(p1).padStart(2, '0')}`;
213
+ }
214
+ else {
215
+ // MM/DD/YYYY
216
+ return `${year}-${String(p1).padStart(2, '0')}-${String(p2).padStart(2, '0')}`;
217
+ }
218
+ }
219
+ const timestamp = Date.parse(val);
220
+ if (isNaN(timestamp)) {
221
+ return null;
222
+ }
223
+ const d = new Date(timestamp);
224
+ const year = d.getFullYear();
225
+ const month = String(d.getMonth() + 1).padStart(2, '0');
226
+ const day = String(d.getDate()).padStart(2, '0');
227
+ return `${year}-${month}-${day}`;
228
+ }
229
+ compareDates(a, b) {
230
+ const normA = this.normalizeDate(a);
231
+ const normB = this.normalizeDate(b);
232
+ if (!normA || !normB) {
233
+ return {
234
+ comparable: false,
235
+ equal: a.trim().toLowerCase() === b.trim().toLowerCase(),
236
+ normalizedA: a.trim(),
237
+ normalizedB: b.trim(),
238
+ valueType: 'date',
239
+ differenceStrength: 0.5,
240
+ differenceType: 'UNPARSEABLE_DATE',
241
+ };
242
+ }
243
+ const equal = normA === normB;
244
+ const timeA = new Date(normA).getTime();
245
+ const timeB = new Date(normB).getTime();
246
+ const dayDiff = Math.abs((timeA - timeB) / (1000 * 60 * 60 * 24));
247
+ return {
248
+ comparable: true,
249
+ equal,
250
+ normalizedA: normA,
251
+ normalizedB: normB,
252
+ valueType: 'date',
253
+ differenceStrength: equal ? 0.0 : Math.min(1.0, 0.4 + dayDiff * 0.1),
254
+ differenceType: equal ? undefined : 'DATE_MISMATCH',
255
+ details: { dayDifference: dayDiff },
256
+ };
257
+ }
258
+ // --- PRICE / CURRENCY COMPARISON ---
259
+ isLikelyPrice(str) {
260
+ return /[$€£¥₹]|(?:\b(?:INR|USD|EUR|GBP|JPY)\b)/i.test(str);
261
+ }
262
+ normalizePrice(val) {
263
+ const currencyMap = {
264
+ '₹': 'INR',
265
+ INR: 'INR',
266
+ $: 'USD',
267
+ USD: 'USD',
268
+ '€': 'EUR',
269
+ EUR: 'EUR',
270
+ '£': 'GBP',
271
+ GBP: 'GBP',
272
+ '¥': 'JPY',
273
+ JPY: 'JPY',
274
+ };
275
+ let currency;
276
+ for (const [symbol, code] of Object.entries(currencyMap)) {
277
+ if (val.toUpperCase().includes(symbol)) {
278
+ currency = code;
279
+ break;
280
+ }
281
+ }
282
+ // Extract numeric amount, removing commas
283
+ const numericStr = val.replace(/[^0-9.]/g, '');
284
+ const amount = parseFloat(numericStr);
285
+ if (isNaN(amount))
286
+ return null;
287
+ return { amount, currency };
288
+ }
289
+ comparePrices(a, b) {
290
+ const parsedA = this.normalizePrice(a);
291
+ const parsedB = this.normalizePrice(b);
292
+ if (!parsedA || !parsedB) {
293
+ return this.compareStrings(a, b, 'price');
294
+ }
295
+ const normStrA = `${parsedA.currency ? parsedA.currency + ' ' : ''}${parsedA.amount}`;
296
+ const normStrB = `${parsedB.currency ? parsedB.currency + ' ' : ''}${parsedB.amount}`;
297
+ // If currencies are both present and differ, this is a currency mismatch
298
+ if (parsedA.currency && parsedB.currency && parsedA.currency !== parsedB.currency) {
299
+ return {
300
+ comparable: true,
301
+ equal: false,
302
+ normalizedA: normStrA,
303
+ normalizedB: normStrB,
304
+ valueType: 'price',
305
+ differenceStrength: 1.0,
306
+ differenceType: 'CURRENCY_MISMATCH',
307
+ details: { currencyA: parsedA.currency, currencyB: parsedB.currency },
308
+ };
309
+ }
310
+ const equal = Math.abs(parsedA.amount - parsedB.amount) < 0.001;
311
+ const diff = Math.abs(parsedA.amount - parsedB.amount);
312
+ return {
313
+ comparable: true,
314
+ equal,
315
+ normalizedA: normStrA,
316
+ normalizedB: normStrB,
317
+ valueType: 'price',
318
+ differenceStrength: equal ? 0.0 : 0.9,
319
+ differenceType: equal ? undefined : 'AMOUNT_MISMATCH',
320
+ details: {
321
+ amountA: parsedA.amount,
322
+ amountB: parsedB.amount,
323
+ difference: diff,
324
+ },
325
+ };
326
+ }
327
+ // --- NUMBER / QUANTITY COMPARISON ---
328
+ isLikelyNumber(str) {
329
+ return /^[-+]?\d+(?:\.\d+)?$/.test(str.trim());
330
+ }
331
+ compareNumbers(a, b, valueType) {
332
+ const numA = parseFloat(a.trim());
333
+ const numB = parseFloat(b.trim());
334
+ if (isNaN(numA) || isNaN(numB)) {
335
+ return this.compareStrings(a, b, valueType);
336
+ }
337
+ const equal = Math.abs(numA - numB) < 0.000001;
338
+ return {
339
+ comparable: true,
340
+ equal,
341
+ normalizedA: String(numA),
342
+ normalizedB: String(numB),
343
+ valueType,
344
+ differenceStrength: equal ? 0.0 : 0.85,
345
+ differenceType: equal ? undefined : 'NUMERIC_MISMATCH',
346
+ details: {
347
+ numberA: numA,
348
+ numberB: numB,
349
+ difference: Math.abs(numA - numB),
350
+ },
351
+ };
352
+ }
353
+ // --- STATUS COMPARISON ---
354
+ compareStatuses(a, b) {
355
+ const normA = a.trim().toLowerCase();
356
+ const normB = b.trim().toLowerCase();
357
+ const equal = normA === normB;
358
+ return {
359
+ comparable: true,
360
+ equal,
361
+ normalizedA: normA,
362
+ normalizedB: normB,
363
+ valueType: 'status',
364
+ differenceStrength: equal ? 0.0 : 0.95,
365
+ differenceType: equal ? undefined : 'STATUS_MISMATCH',
366
+ };
367
+ }
368
+ // --- BOOLEAN COMPARISON ---
369
+ normalizeBoolean(val) {
370
+ const v = val.trim().toLowerCase();
371
+ if (['true', 'yes', '1', 'enabled', 'active', 'on'].includes(v))
372
+ return true;
373
+ if (['false', 'no', '0', 'disabled', 'inactive', 'off'].includes(v))
374
+ return false;
375
+ return null;
376
+ }
377
+ compareBooleans(a, b) {
378
+ const boolA = this.normalizeBoolean(a);
379
+ const boolB = this.normalizeBoolean(b);
380
+ if (boolA === null || boolB === null) {
381
+ return this.compareStrings(a, b, 'boolean');
382
+ }
383
+ const equal = boolA === boolB;
384
+ return {
385
+ comparable: true,
386
+ equal,
387
+ normalizedA: String(boolA),
388
+ normalizedB: String(boolB),
389
+ valueType: 'boolean',
390
+ differenceStrength: equal ? 0.0 : 1.0,
391
+ differenceType: equal ? undefined : 'BOOLEAN_MISMATCH',
392
+ };
393
+ }
394
+ // --- STRING FALLBACK COMPARISON ---
395
+ compareStrings(a, b, valueType) {
396
+ const cleanA = a.trim().replace(/\s+/g, ' ');
397
+ const cleanB = b.trim().replace(/\s+/g, ' ');
398
+ const lowerA = cleanA.toLowerCase();
399
+ const lowerB = cleanB.toLowerCase();
400
+ const exactMatch = cleanA === cleanB;
401
+ const caseInsensitiveMatch = lowerA === lowerB;
402
+ return {
403
+ comparable: true,
404
+ equal: caseInsensitiveMatch,
405
+ normalizedA: cleanA,
406
+ normalizedB: cleanB,
407
+ valueType,
408
+ differenceStrength: caseInsensitiveMatch ? 0.0 : 0.8,
409
+ differenceType: caseInsensitiveMatch ? undefined : 'VALUE_MISMATCH',
410
+ details: {
411
+ exactMatch,
412
+ caseInsensitiveMatch,
413
+ },
414
+ };
415
+ }
416
+ }
417
+ export const valueComparator = new ValueComparator();
418
+ //# sourceMappingURL=valueComparator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"valueComparator.js","sourceRoot":"","sources":["../../src/analysis/valueComparator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import { z } from 'zod';
2
+ declare const EnvSchema: z.ZodObject<{
3
+ NODE_ENV: z.ZodDefault<z.ZodEnum<{
4
+ development: "development";
5
+ production: "production";
6
+ test: "test";
7
+ }>>;
8
+ DATABASE_PATH: z.ZodDefault<z.ZodString>;
9
+ LOG_LEVEL: z.ZodDefault<z.ZodEnum<{
10
+ error: "error";
11
+ debug: "debug";
12
+ info: "info";
13
+ warn: "warn";
14
+ }>>;
15
+ SERVER_NAME: z.ZodDefault<z.ZodString>;
16
+ SERVER_VERSION: z.ZodDefault<z.ZodString>;
17
+ GITHUB_TOKEN: z.ZodOptional<z.ZodString>;
18
+ MCP_TRANSPORT: z.ZodDefault<z.ZodEnum<{
19
+ stdio: "stdio";
20
+ http: "http";
21
+ }>>;
22
+ HTTP_HOST: z.ZodDefault<z.ZodString>;
23
+ HTTP_PORT: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
24
+ API_KEY: z.ZodOptional<z.ZodString>;
25
+ RATE_LIMIT_PER_MINUTE: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
26
+ MAX_BATCH_CONCURRENCY: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
27
+ SEMANTIC_MATCHING_ENABLED: z.ZodDefault<z.ZodCoercedBoolean<unknown>>;
28
+ }, z.core.$strip>;
29
+ export type EnvConfig = z.infer<typeof EnvSchema>;
30
+ export declare function loadConfig(envOverrides?: Partial<Record<string, string>>): EnvConfig;
31
+ export declare const config: {
32
+ NODE_ENV: "development" | "production" | "test";
33
+ DATABASE_PATH: string;
34
+ LOG_LEVEL: "error" | "debug" | "info" | "warn";
35
+ SERVER_NAME: string;
36
+ SERVER_VERSION: string;
37
+ MCP_TRANSPORT: "stdio" | "http";
38
+ HTTP_HOST: string;
39
+ HTTP_PORT: number;
40
+ RATE_LIMIT_PER_MINUTE: number;
41
+ MAX_BATCH_CONCURRENCY: number;
42
+ SEMANTIC_MATCHING_ENABLED: boolean;
43
+ GITHUB_TOKEN?: string | undefined;
44
+ API_KEY?: string | undefined;
45
+ };
46
+ export {};
@@ -0,0 +1,34 @@
1
+ import dotenv from 'dotenv';
2
+ import { z } from 'zod';
3
+ import { ConfigurationError } from '../domain/types/common.js';
4
+ process.env.DOTENV_CONFIG_QUIET = 'true';
5
+ dotenv.config({ quiet: true });
6
+ const EnvSchema = z.object({
7
+ NODE_ENV: z.enum(['development', 'test', 'production']).default('development'),
8
+ DATABASE_PATH: z.string().min(1).default('./data/contradiction.db'),
9
+ LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
10
+ SERVER_NAME: z.string().min(1).default('contradiction-mcp'),
11
+ SERVER_VERSION: z.string().min(1).default('0.1.0'),
12
+ GITHUB_TOKEN: z.string().optional(),
13
+ MCP_TRANSPORT: z.enum(['stdio', 'http']).default('stdio'),
14
+ HTTP_HOST: z.string().default('0.0.0.0'),
15
+ HTTP_PORT: z.coerce.number().int().positive().default(3000),
16
+ API_KEY: z.string().optional(),
17
+ RATE_LIMIT_PER_MINUTE: z.coerce.number().int().positive().default(60),
18
+ MAX_BATCH_CONCURRENCY: z.coerce.number().int().positive().default(3),
19
+ SEMANTIC_MATCHING_ENABLED: z.coerce.boolean().default(false),
20
+ });
21
+ export function loadConfig(envOverrides) {
22
+ const mergedEnv = {
23
+ ...process.env,
24
+ ...envOverrides,
25
+ };
26
+ const parsed = EnvSchema.safeParse(mergedEnv);
27
+ if (!parsed.success) {
28
+ const issues = parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('; ');
29
+ throw new ConfigurationError(`Environment configuration invalid: ${issues}`);
30
+ }
31
+ return parsed.data;
32
+ }
33
+ export const config = loadConfig();
34
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/config/env.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,MAAM,CAAC;AACzC,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAE/B,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;IAC9E,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,yBAAyB,CAAC;IACnE,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACrE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC;IAC3D,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IAClD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnC,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IACzD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC;IACxC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC3D,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,qBAAqB,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACrE,qBAAqB,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACpE,yBAAyB,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;CAC7D,CAAC,CAAC;AAIH,MAAM,UAAU,UAAU,CAAC,YAA8C;IACvE,MAAM,SAAS,GAAG;QAChB,GAAG,OAAO,CAAC,GAAG;QACd,GAAG,YAAY;KAChB,CAAC;IAEF,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9F,MAAM,IAAI,kBAAkB,CAAC,sCAAsC,MAAM,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Sanitizes an error message or string to ensure tokens, secrets,
3
+ * and sensitive authentication headers are never leaked.
4
+ */
5
+ export declare function sanitizeSecrets(text: string): string;
6
+ /**
7
+ * Formats a clean, sanitized error message from an unknown error.
8
+ */
9
+ export declare function sanitizeErrorMessage(error: unknown): string;
10
+ /**
11
+ * Generates a stable canonical external identifier for a Source.
12
+ * Example: 'github:octocat/hello-world'
13
+ */
14
+ export declare function createSourceExternalId(type: string, identifier: string): string;
15
+ /**
16
+ * Generates a deterministic external identifier for an extracted Claim.
17
+ * Guarantees that syncing the same file and property repeatedly references
18
+ * the exact same external claim entity.
19
+ *
20
+ * Example: 'github:octocat/hello-world:package.json:node_version'
21
+ */
22
+ export declare function createClaimExternalId(sourceExternalId: string, filePath: string, predicate: string, distinctKey?: string): string;
23
+ /**
24
+ * Deterministically hashes input data to detect whether content changed.
25
+ */
26
+ export declare function hashContent(content: string): string;
@@ -0,0 +1,63 @@
1
+ import crypto from 'node:crypto';
2
+ /**
3
+ * Sanitizes an error message or string to ensure tokens, secrets,
4
+ * and sensitive authentication headers are never leaked.
5
+ */
6
+ export function sanitizeSecrets(text) {
7
+ if (!text)
8
+ return '';
9
+ return text
10
+ .replace(/(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{20,255}/g, '[REDACTED_GITHUB_TOKEN]')
11
+ .replace(/Bearer\s+[A-Za-z0-9_.-]+/gi, 'Bearer [REDACTED]')
12
+ .replace(/token\s+[A-Za-z0-9_.-]+/gi, 'token [REDACTED]')
13
+ .replace(/access_token=[A-Za-z0-9_.-]+/gi, 'access_token=[REDACTED]');
14
+ }
15
+ /**
16
+ * Formats a clean, sanitized error message from an unknown error.
17
+ */
18
+ export function sanitizeErrorMessage(error) {
19
+ if (error instanceof Error) {
20
+ return sanitizeSecrets(error.message);
21
+ }
22
+ return sanitizeSecrets(String(error));
23
+ }
24
+ /**
25
+ * Generates a stable canonical external identifier for a Source.
26
+ * Example: 'github:octocat/hello-world'
27
+ */
28
+ export function createSourceExternalId(type, identifier) {
29
+ const normType = type.trim().toLowerCase();
30
+ const normId = identifier
31
+ .trim()
32
+ .toLowerCase()
33
+ .replace(/^\/+|\/+$/g, '');
34
+ return `${normType}:${normId}`;
35
+ }
36
+ /**
37
+ * Generates a deterministic external identifier for an extracted Claim.
38
+ * Guarantees that syncing the same file and property repeatedly references
39
+ * the exact same external claim entity.
40
+ *
41
+ * Example: 'github:octocat/hello-world:package.json:node_version'
42
+ */
43
+ export function createClaimExternalId(sourceExternalId, filePath, predicate, distinctKey) {
44
+ const normSource = sourceExternalId.trim().toLowerCase();
45
+ const normFile = filePath
46
+ .trim()
47
+ .toLowerCase()
48
+ .replace(/^\/+|\/+$/g, '');
49
+ const normPred = predicate.trim().toLowerCase();
50
+ const base = `${normSource}:${normFile}:${normPred}`;
51
+ if (distinctKey) {
52
+ const normKey = distinctKey.trim().toLowerCase();
53
+ return `${base}:${normKey}`;
54
+ }
55
+ return base;
56
+ }
57
+ /**
58
+ * Deterministically hashes input data to detect whether content changed.
59
+ */
60
+ export function hashContent(content) {
61
+ return crypto.createHash('sha256').update(content, 'utf-8').digest('hex');
62
+ }
63
+ //# sourceMappingURL=connectorUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connectorUtils.js","sourceRoot":"","sources":["../../../src/connectors/base/connectorUtils.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,OAAO,IAAI;SACR,OAAO,CAAC,+CAA+C,EAAE,yBAAyB,CAAC;SACnF,OAAO,CAAC,4BAA4B,EAAE,mBAAmB,CAAC;SAC1D,OAAO,CAAC,2BAA2B,EAAE,kBAAkB,CAAC;SACxD,OAAO,CAAC,gCAAgC,EAAE,yBAAyB,CAAC,CAAC;AAC1E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY,EAAE,UAAkB;IACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,MAAM,MAAM,GAAG,UAAU;SACtB,IAAI,EAAE;SACN,WAAW,EAAE;SACb,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAC7B,OAAO,GAAG,QAAQ,IAAI,MAAM,EAAE,CAAC;AACjC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CACnC,gBAAwB,EACxB,QAAgB,EAChB,SAAiB,EACjB,WAAoB;IAEpB,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACzD,MAAM,QAAQ,GAAG,QAAQ;SACtB,IAAI,EAAE;SACN,WAAW,EAAE;SACb,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAC7B,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAChD,MAAM,IAAI,GAAG,GAAG,UAAU,IAAI,QAAQ,IAAI,QAAQ,EAAE,CAAC;IAErD,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACjD,OAAO,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC;IAC9B,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5E,CAAC"}
@@ -0,0 +1,11 @@
1
+ export type DataSensitivityLevel = 'PUBLIC' | 'INTERNAL' | 'CONFIDENTIAL' | 'RESTRICTED';
2
+ export interface ConnectorSecurityDescriptor {
3
+ readOnly: boolean;
4
+ requiresNetwork: boolean;
5
+ requiresAuthentication: boolean;
6
+ requiredPermissions: string[];
7
+ sensitivityLevel: DataSensitivityLevel;
8
+ allowedProtocols?: string[];
9
+ ssrfProtected?: boolean;
10
+ }
11
+ export declare const DEFAULT_READ_ONLY_SECURITY: ConnectorSecurityDescriptor;
@@ -0,0 +1,9 @@
1
+ export const DEFAULT_READ_ONLY_SECURITY = {
2
+ readOnly: true,
3
+ requiresNetwork: false,
4
+ requiresAuthentication: false,
5
+ requiredPermissions: ['read'],
6
+ sensitivityLevel: 'INTERNAL',
7
+ ssrfProtected: true,
8
+ };
9
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../../../src/connectors/base/security.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,MAAM,0BAA0B,GAAgC;IACrE,QAAQ,EAAE,IAAI;IACd,eAAe,EAAE,KAAK;IACtB,sBAAsB,EAAE,KAAK;IAC7B,mBAAmB,EAAE,CAAC,MAAM,CAAC;IAC7B,gBAAgB,EAAE,UAAU;IAC5B,aAAa,EAAE,IAAI;CACpB,CAAC"}