codeguardian-mcp 1.0.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 (335) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +348 -0
  3. package/dist/agent/agentTools.d.ts +26 -0
  4. package/dist/agent/agentTools.d.ts.map +1 -0
  5. package/dist/agent/agentTools.js +699 -0
  6. package/dist/agent/agentTools.js.map +1 -0
  7. package/dist/agent/autoValidator.d.ts +110 -0
  8. package/dist/agent/autoValidator.d.ts.map +1 -0
  9. package/dist/agent/autoValidator.js +964 -0
  10. package/dist/agent/autoValidator.js.map +1 -0
  11. package/dist/agent/fileWatcher.d.ts +28 -0
  12. package/dist/agent/fileWatcher.d.ts.map +1 -0
  13. package/dist/agent/fileWatcher.js +88 -0
  14. package/dist/agent/fileWatcher.js.map +1 -0
  15. package/dist/agent/guardianPersistence.d.ts +98 -0
  16. package/dist/agent/guardianPersistence.d.ts.map +1 -0
  17. package/dist/agent/guardianPersistence.js +296 -0
  18. package/dist/agent/guardianPersistence.js.map +1 -0
  19. package/dist/agent/mcpNotifications.d.ts +38 -0
  20. package/dist/agent/mcpNotifications.d.ts.map +1 -0
  21. package/dist/agent/mcpNotifications.js +81 -0
  22. package/dist/agent/mcpNotifications.js.map +1 -0
  23. package/dist/analyzers/aiPatterns.d.ts +16 -0
  24. package/dist/analyzers/aiPatterns.d.ts.map +1 -0
  25. package/dist/analyzers/aiPatterns.js +103 -0
  26. package/dist/analyzers/aiPatterns.js.map +1 -0
  27. package/dist/analyzers/antiPatterns.d.ts +60 -0
  28. package/dist/analyzers/antiPatterns.d.ts.map +1 -0
  29. package/dist/analyzers/antiPatterns.js +198 -0
  30. package/dist/analyzers/antiPatterns.js.map +1 -0
  31. package/dist/analyzers/builtinTypes.d.ts +18 -0
  32. package/dist/analyzers/builtinTypes.d.ts.map +1 -0
  33. package/dist/analyzers/builtinTypes.js +1275 -0
  34. package/dist/analyzers/builtinTypes.js.map +1 -0
  35. package/dist/analyzers/complexity.d.ts +14 -0
  36. package/dist/analyzers/complexity.d.ts.map +1 -0
  37. package/dist/analyzers/complexity.js +610 -0
  38. package/dist/analyzers/complexity.js.map +1 -0
  39. package/dist/analyzers/findingVerifier.d.ts +59 -0
  40. package/dist/analyzers/findingVerifier.d.ts.map +1 -0
  41. package/dist/analyzers/findingVerifier.js +1169 -0
  42. package/dist/analyzers/findingVerifier.js.map +1 -0
  43. package/dist/analyzers/impactAnalyzer.d.ts +53 -0
  44. package/dist/analyzers/impactAnalyzer.d.ts.map +1 -0
  45. package/dist/analyzers/impactAnalyzer.js +152 -0
  46. package/dist/analyzers/impactAnalyzer.js.map +1 -0
  47. package/dist/analyzers/languageDetector.d.ts +48 -0
  48. package/dist/analyzers/languageDetector.d.ts.map +1 -0
  49. package/dist/analyzers/languageDetector.js +404 -0
  50. package/dist/analyzers/languageDetector.js.map +1 -0
  51. package/dist/analyzers/parsers/incrementalParser.d.ts +53 -0
  52. package/dist/analyzers/parsers/incrementalParser.d.ts.map +1 -0
  53. package/dist/analyzers/parsers/incrementalParser.js +193 -0
  54. package/dist/analyzers/parsers/incrementalParser.js.map +1 -0
  55. package/dist/analyzers/parsers/scopeResolver.d.ts +92 -0
  56. package/dist/analyzers/parsers/scopeResolver.d.ts.map +1 -0
  57. package/dist/analyzers/parsers/scopeResolver.js +324 -0
  58. package/dist/analyzers/parsers/scopeResolver.js.map +1 -0
  59. package/dist/analyzers/parsers/semanticIndex.d.ts +127 -0
  60. package/dist/analyzers/parsers/semanticIndex.d.ts.map +1 -0
  61. package/dist/analyzers/parsers/semanticIndex.js +429 -0
  62. package/dist/analyzers/parsers/semanticIndex.js.map +1 -0
  63. package/dist/analyzers/parsers/sessionDiffAnalyzer.d.ts +42 -0
  64. package/dist/analyzers/parsers/sessionDiffAnalyzer.d.ts.map +1 -0
  65. package/dist/analyzers/parsers/sessionDiffAnalyzer.js +233 -0
  66. package/dist/analyzers/parsers/sessionDiffAnalyzer.js.map +1 -0
  67. package/dist/analyzers/parsers/treeSitterParser.d.ts +76 -0
  68. package/dist/analyzers/parsers/treeSitterParser.d.ts.map +1 -0
  69. package/dist/analyzers/parsers/treeSitterParser.js +709 -0
  70. package/dist/analyzers/parsers/treeSitterParser.js.map +1 -0
  71. package/dist/analyzers/relevanceScorer.d.ts +43 -0
  72. package/dist/analyzers/relevanceScorer.d.ts.map +1 -0
  73. package/dist/analyzers/relevanceScorer.js +200 -0
  74. package/dist/analyzers/relevanceScorer.js.map +1 -0
  75. package/dist/analyzers/standardLibrary.d.ts +22 -0
  76. package/dist/analyzers/standardLibrary.d.ts.map +1 -0
  77. package/dist/analyzers/standardLibrary.js +211 -0
  78. package/dist/analyzers/standardLibrary.js.map +1 -0
  79. package/dist/analyzers/symbolGraph.d.ts +30 -0
  80. package/dist/analyzers/symbolGraph.d.ts.map +1 -0
  81. package/dist/analyzers/symbolGraph.js +380 -0
  82. package/dist/analyzers/symbolGraph.js.map +1 -0
  83. package/dist/analyzers/symbolTable.d.ts +18 -0
  84. package/dist/analyzers/symbolTable.d.ts.map +1 -0
  85. package/dist/analyzers/symbolTable.js +176 -0
  86. package/dist/analyzers/symbolTable.js.map +1 -0
  87. package/dist/analyzers/typeChecker.d.ts +13 -0
  88. package/dist/analyzers/typeChecker.d.ts.map +1 -0
  89. package/dist/analyzers/typeChecker.js +580 -0
  90. package/dist/analyzers/typeChecker.js.map +1 -0
  91. package/dist/analyzers/usagePatterns.d.ts +42 -0
  92. package/dist/analyzers/usagePatterns.d.ts.map +1 -0
  93. package/dist/analyzers/usagePatterns.js +75 -0
  94. package/dist/analyzers/usagePatterns.js.map +1 -0
  95. package/dist/api-contract/context/backend.d.ts +19 -0
  96. package/dist/api-contract/context/backend.d.ts.map +1 -0
  97. package/dist/api-contract/context/backend.js +64 -0
  98. package/dist/api-contract/context/backend.js.map +1 -0
  99. package/dist/api-contract/context/contract.d.ts +34 -0
  100. package/dist/api-contract/context/contract.d.ts.map +1 -0
  101. package/dist/api-contract/context/contract.js +306 -0
  102. package/dist/api-contract/context/contract.js.map +1 -0
  103. package/dist/api-contract/context/frontend.d.ts +19 -0
  104. package/dist/api-contract/context/frontend.d.ts.map +1 -0
  105. package/dist/api-contract/context/frontend.js +64 -0
  106. package/dist/api-contract/context/frontend.js.map +1 -0
  107. package/dist/api-contract/detector.d.ts +28 -0
  108. package/dist/api-contract/detector.d.ts.map +1 -0
  109. package/dist/api-contract/detector.js +393 -0
  110. package/dist/api-contract/detector.js.map +1 -0
  111. package/dist/api-contract/extractors/python.d.ts +32 -0
  112. package/dist/api-contract/extractors/python.d.ts.map +1 -0
  113. package/dist/api-contract/extractors/python.js +521 -0
  114. package/dist/api-contract/extractors/python.js.map +1 -0
  115. package/dist/api-contract/extractors/pythonAstUtils.d.ts +44 -0
  116. package/dist/api-contract/extractors/pythonAstUtils.d.ts.map +1 -0
  117. package/dist/api-contract/extractors/pythonAstUtils.js +489 -0
  118. package/dist/api-contract/extractors/pythonAstUtils.js.map +1 -0
  119. package/dist/api-contract/extractors/tsAstUtils.d.ts +47 -0
  120. package/dist/api-contract/extractors/tsAstUtils.d.ts.map +1 -0
  121. package/dist/api-contract/extractors/tsAstUtils.js +173 -0
  122. package/dist/api-contract/extractors/tsAstUtils.js.map +1 -0
  123. package/dist/api-contract/extractors/typescript.d.ts +32 -0
  124. package/dist/api-contract/extractors/typescript.d.ts.map +1 -0
  125. package/dist/api-contract/extractors/typescript.js +666 -0
  126. package/dist/api-contract/extractors/typescript.js.map +1 -0
  127. package/dist/api-contract/index.d.ts +104 -0
  128. package/dist/api-contract/index.d.ts.map +1 -0
  129. package/dist/api-contract/index.js +232 -0
  130. package/dist/api-contract/index.js.map +1 -0
  131. package/dist/api-contract/types.d.ts +151 -0
  132. package/dist/api-contract/types.d.ts.map +1 -0
  133. package/dist/api-contract/types.js +19 -0
  134. package/dist/api-contract/types.js.map +1 -0
  135. package/dist/api-contract/validators/endpoint.d.ts +21 -0
  136. package/dist/api-contract/validators/endpoint.d.ts.map +1 -0
  137. package/dist/api-contract/validators/endpoint.js +224 -0
  138. package/dist/api-contract/validators/endpoint.js.map +1 -0
  139. package/dist/api-contract/validators/index.d.ts +40 -0
  140. package/dist/api-contract/validators/index.d.ts.map +1 -0
  141. package/dist/api-contract/validators/index.js +875 -0
  142. package/dist/api-contract/validators/index.js.map +1 -0
  143. package/dist/api-contract/validators/parameter.d.ts +17 -0
  144. package/dist/api-contract/validators/parameter.d.ts.map +1 -0
  145. package/dist/api-contract/validators/parameter.js +250 -0
  146. package/dist/api-contract/validators/parameter.js.map +1 -0
  147. package/dist/api-contract/validators/type.d.ts +38 -0
  148. package/dist/api-contract/validators/type.d.ts.map +1 -0
  149. package/dist/api-contract/validators/type.js +244 -0
  150. package/dist/api-contract/validators/type.js.map +1 -0
  151. package/dist/context/apiContract/complexTypeSupport.d.ts +83 -0
  152. package/dist/context/apiContract/complexTypeSupport.d.ts.map +1 -0
  153. package/dist/context/apiContract/complexTypeSupport.js +665 -0
  154. package/dist/context/apiContract/complexTypeSupport.js.map +1 -0
  155. package/dist/context/apiContract/graphqlSupport.d.ts +105 -0
  156. package/dist/context/apiContract/graphqlSupport.d.ts.map +1 -0
  157. package/dist/context/apiContract/graphqlSupport.js +671 -0
  158. package/dist/context/apiContract/graphqlSupport.js.map +1 -0
  159. package/dist/context/apiContract/index.d.ts +14 -0
  160. package/dist/context/apiContract/index.d.ts.map +1 -0
  161. package/dist/context/apiContract/index.js +17 -0
  162. package/dist/context/apiContract/index.js.map +1 -0
  163. package/dist/context/apiContract/webSocketSupport.d.ts +104 -0
  164. package/dist/context/apiContract/webSocketSupport.d.ts.map +1 -0
  165. package/dist/context/apiContract/webSocketSupport.js +465 -0
  166. package/dist/context/apiContract/webSocketSupport.js.map +1 -0
  167. package/dist/context/apiContractContext.d.ts +15 -0
  168. package/dist/context/apiContractContext.d.ts.map +1 -0
  169. package/dist/context/apiContractContext.js +979 -0
  170. package/dist/context/apiContractContext.js.map +1 -0
  171. package/dist/context/apiContractExtraction.d.ts +52 -0
  172. package/dist/context/apiContractExtraction.d.ts.map +1 -0
  173. package/dist/context/apiContractExtraction.js +438 -0
  174. package/dist/context/apiContractExtraction.js.map +1 -0
  175. package/dist/context/contextLineage.d.ts +79 -0
  176. package/dist/context/contextLineage.d.ts.map +1 -0
  177. package/dist/context/contextLineage.js +259 -0
  178. package/dist/context/contextLineage.js.map +1 -0
  179. package/dist/context/contextOrchestrator.d.ts +57 -0
  180. package/dist/context/contextOrchestrator.d.ts.map +1 -0
  181. package/dist/context/contextOrchestrator.js +162 -0
  182. package/dist/context/contextOrchestrator.js.map +1 -0
  183. package/dist/context/intentTracker.d.ts +73 -0
  184. package/dist/context/intentTracker.d.ts.map +1 -0
  185. package/dist/context/intentTracker.js +168 -0
  186. package/dist/context/intentTracker.js.map +1 -0
  187. package/dist/context/projectContext.d.ts +219 -0
  188. package/dist/context/projectContext.d.ts.map +1 -0
  189. package/dist/context/projectContext.js +1984 -0
  190. package/dist/context/projectContext.js.map +1 -0
  191. package/dist/prompts/index.d.ts +17 -0
  192. package/dist/prompts/index.d.ts.map +1 -0
  193. package/dist/prompts/index.js +260 -0
  194. package/dist/prompts/index.js.map +1 -0
  195. package/dist/prompts/library.d.ts +51 -0
  196. package/dist/prompts/library.d.ts.map +1 -0
  197. package/dist/prompts/library.js +65 -0
  198. package/dist/prompts/library.js.map +1 -0
  199. package/dist/prompts/templates.d.ts +44 -0
  200. package/dist/prompts/templates.d.ts.map +1 -0
  201. package/dist/prompts/templates.js +97 -0
  202. package/dist/prompts/templates.js.map +1 -0
  203. package/dist/queue/jobPersistence.d.ts +46 -0
  204. package/dist/queue/jobPersistence.d.ts.map +1 -0
  205. package/dist/queue/jobPersistence.js +158 -0
  206. package/dist/queue/jobPersistence.js.map +1 -0
  207. package/dist/queue/jobQueue.d.ts +116 -0
  208. package/dist/queue/jobQueue.d.ts.map +1 -0
  209. package/dist/queue/jobQueue.js +275 -0
  210. package/dist/queue/jobQueue.js.map +1 -0
  211. package/dist/queue/validationJob.d.ts +69 -0
  212. package/dist/queue/validationJob.d.ts.map +1 -0
  213. package/dist/queue/validationJob.js +435 -0
  214. package/dist/queue/validationJob.js.map +1 -0
  215. package/dist/resources/index.d.ts +15 -0
  216. package/dist/resources/index.d.ts.map +1 -0
  217. package/dist/resources/index.js +328 -0
  218. package/dist/resources/index.js.map +1 -0
  219. package/dist/resources/validationReportStore.d.ts +170 -0
  220. package/dist/resources/validationReportStore.d.ts.map +1 -0
  221. package/dist/resources/validationReportStore.js +515 -0
  222. package/dist/resources/validationReportStore.js.map +1 -0
  223. package/dist/server.d.ts +12 -0
  224. package/dist/server.d.ts.map +1 -0
  225. package/dist/server.js +102 -0
  226. package/dist/server.js.map +1 -0
  227. package/dist/tools/asyncValidation.d.ts +19 -0
  228. package/dist/tools/asyncValidation.d.ts.map +1 -0
  229. package/dist/tools/asyncValidation.js +346 -0
  230. package/dist/tools/asyncValidation.js.map +1 -0
  231. package/dist/tools/buildContext.d.ts +17 -0
  232. package/dist/tools/buildContext.d.ts.map +1 -0
  233. package/dist/tools/buildContext.js +188 -0
  234. package/dist/tools/buildContext.js.map +1 -0
  235. package/dist/tools/getDependencyGraph.d.ts +16 -0
  236. package/dist/tools/getDependencyGraph.d.ts.map +1 -0
  237. package/dist/tools/getDependencyGraph.js +436 -0
  238. package/dist/tools/getDependencyGraph.js.map +1 -0
  239. package/dist/tools/incrementalValidation.d.ts +71 -0
  240. package/dist/tools/incrementalValidation.d.ts.map +1 -0
  241. package/dist/tools/incrementalValidation.js +203 -0
  242. package/dist/tools/incrementalValidation.js.map +1 -0
  243. package/dist/tools/index.d.ts +24 -0
  244. package/dist/tools/index.d.ts.map +1 -0
  245. package/dist/tools/index.js +106 -0
  246. package/dist/tools/index.js.map +1 -0
  247. package/dist/tools/validateCode.d.ts +17 -0
  248. package/dist/tools/validateCode.d.ts.map +1 -0
  249. package/dist/tools/validateCode.js +368 -0
  250. package/dist/tools/validateCode.js.map +1 -0
  251. package/dist/tools/validateCodeLite.d.ts +2 -0
  252. package/dist/tools/validateCodeLite.d.ts.map +1 -0
  253. package/dist/tools/validateCodeLite.js +2 -0
  254. package/dist/tools/validateCodeLite.js.map +1 -0
  255. package/dist/tools/validation/builtins.d.ts +92 -0
  256. package/dist/tools/validation/builtins.d.ts.map +1 -0
  257. package/dist/tools/validation/builtins.js +2184 -0
  258. package/dist/tools/validation/builtins.js.map +1 -0
  259. package/dist/tools/validation/contextualNaming.d.ts +99 -0
  260. package/dist/tools/validation/contextualNaming.d.ts.map +1 -0
  261. package/dist/tools/validation/contextualNaming.js +959 -0
  262. package/dist/tools/validation/contextualNaming.js.map +1 -0
  263. package/dist/tools/validation/deadCode.d.ts +115 -0
  264. package/dist/tools/validation/deadCode.d.ts.map +1 -0
  265. package/dist/tools/validation/deadCode.js +861 -0
  266. package/dist/tools/validation/deadCode.js.map +1 -0
  267. package/dist/tools/validation/extractors/index.d.ts +131 -0
  268. package/dist/tools/validation/extractors/index.d.ts.map +1 -0
  269. package/dist/tools/validation/extractors/index.js +233 -0
  270. package/dist/tools/validation/extractors/index.js.map +1 -0
  271. package/dist/tools/validation/extractors/javascript.d.ts +73 -0
  272. package/dist/tools/validation/extractors/javascript.d.ts.map +1 -0
  273. package/dist/tools/validation/extractors/javascript.js +1841 -0
  274. package/dist/tools/validation/extractors/javascript.js.map +1 -0
  275. package/dist/tools/validation/extractors/python.d.ts +93 -0
  276. package/dist/tools/validation/extractors/python.d.ts.map +1 -0
  277. package/dist/tools/validation/extractors/python.js +799 -0
  278. package/dist/tools/validation/extractors/python.js.map +1 -0
  279. package/dist/tools/validation/manifest.d.ts +45 -0
  280. package/dist/tools/validation/manifest.d.ts.map +1 -0
  281. package/dist/tools/validation/manifest.js +719 -0
  282. package/dist/tools/validation/manifest.js.map +1 -0
  283. package/dist/tools/validation/parser.d.ts +58 -0
  284. package/dist/tools/validation/parser.d.ts.map +1 -0
  285. package/dist/tools/validation/parser.js +232 -0
  286. package/dist/tools/validation/parser.js.map +1 -0
  287. package/dist/tools/validation/registry.d.ts +15 -0
  288. package/dist/tools/validation/registry.d.ts.map +1 -0
  289. package/dist/tools/validation/registry.js +169 -0
  290. package/dist/tools/validation/registry.js.map +1 -0
  291. package/dist/tools/validation/scoring.d.ts +54 -0
  292. package/dist/tools/validation/scoring.d.ts.map +1 -0
  293. package/dist/tools/validation/scoring.js +242 -0
  294. package/dist/tools/validation/scoring.js.map +1 -0
  295. package/dist/tools/validation/types.d.ts +120 -0
  296. package/dist/tools/validation/types.d.ts.map +1 -0
  297. package/dist/tools/validation/types.js +11 -0
  298. package/dist/tools/validation/types.js.map +1 -0
  299. package/dist/tools/validation/unusedLocals.d.ts +36 -0
  300. package/dist/tools/validation/unusedLocals.d.ts.map +1 -0
  301. package/dist/tools/validation/unusedLocals.js +333 -0
  302. package/dist/tools/validation/unusedLocals.js.map +1 -0
  303. package/dist/tools/validation/validation.d.ts +98 -0
  304. package/dist/tools/validation/validation.d.ts.map +1 -0
  305. package/dist/tools/validation/validation.js +1837 -0
  306. package/dist/tools/validation/validation.js.map +1 -0
  307. package/dist/types/codeGraph.d.ts +163 -0
  308. package/dist/types/codeGraph.d.ts.map +1 -0
  309. package/dist/types/codeGraph.js +9 -0
  310. package/dist/types/codeGraph.js.map +1 -0
  311. package/dist/types/symbolGraph.d.ts +68 -0
  312. package/dist/types/symbolGraph.d.ts.map +1 -0
  313. package/dist/types/symbolGraph.js +10 -0
  314. package/dist/types/symbolGraph.js.map +1 -0
  315. package/dist/types/tools.d.ts +43 -0
  316. package/dist/types/tools.d.ts.map +1 -0
  317. package/dist/types/tools.js +7 -0
  318. package/dist/types/tools.js.map +1 -0
  319. package/dist/utils/fileFilter.d.ts +37 -0
  320. package/dist/utils/fileFilter.d.ts.map +1 -0
  321. package/dist/utils/fileFilter.js +91 -0
  322. package/dist/utils/fileFilter.js.map +1 -0
  323. package/dist/utils/gitUtils.d.ts +28 -0
  324. package/dist/utils/gitUtils.d.ts.map +1 -0
  325. package/dist/utils/gitUtils.js +81 -0
  326. package/dist/utils/gitUtils.js.map +1 -0
  327. package/dist/utils/logger.d.ts +15 -0
  328. package/dist/utils/logger.d.ts.map +1 -0
  329. package/dist/utils/logger.js +38 -0
  330. package/dist/utils/logger.js.map +1 -0
  331. package/dist/utils/serialization.d.ts +25 -0
  332. package/dist/utils/serialization.d.ts.map +1 -0
  333. package/dist/utils/serialization.js +53 -0
  334. package/dist/utils/serialization.js.map +1 -0
  335. package/package.json +90 -0
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Usage Pattern Analyzer
3
+ *
4
+ * Secret #5: Usage Pattern Consistency (The Helpfulness Pattern)
5
+ *
6
+ * Learns "rituals" from the codebase:
7
+ * - Co-occurrence: Which functions are almost always called together?
8
+ * - Argument Rituals: Common arguments passed to specific functions.
9
+ * - Call Ordering: (Heuristic) Which symbols often appear in sequence.
10
+ *
11
+ * @format
12
+ */
13
+ import { logger } from "../utils/logger.js";
14
+ export class UsagePatternAnalyzer {
15
+ patterns = new Map();
16
+ /**
17
+ * Analyze the symbol graph to discover patterns
18
+ */
19
+ async analyze(graph) {
20
+ logger.debug(`Analyzing usage patterns for ${graph.usage.size} symbols...`);
21
+ for (const [symbolName, usage] of graph.usage.entries()) {
22
+ // We only care about symbols used at least 3 times to establish a pattern
23
+ if (usage.usageCount < 3)
24
+ continue;
25
+ const coOccurring = this.extractCoOccurrence(symbolName, graph);
26
+ // If we found significant co-occurrence, store the pattern
27
+ if (coOccurring.length > 0) {
28
+ this.patterns.set(symbolName, {
29
+ symbol: symbolName,
30
+ coOccurringSymbols: coOccurring,
31
+ commonArguments: [], // To be implemented with deeper AST mining
32
+ callConfidence: usage.usageCount > 10 ? 0.9 : 0.7,
33
+ });
34
+ }
35
+ }
36
+ logger.debug(`Established ${this.patterns.size} usage pattern rituals.`);
37
+ }
38
+ /**
39
+ * Check if new code deviates from established patterns
40
+ */
41
+ checkDeviations(symbolName, surroundingSymbols) {
42
+ const pattern = this.patterns.get(symbolName);
43
+ if (!pattern)
44
+ return [];
45
+ const deviations = [];
46
+ const surroundingSet = new Set(surroundingSymbols);
47
+ // If a symbol has a high co-occurrence (e.g. > 80% usage),
48
+ // it should probably be present
49
+ for (const ritual of pattern.coOccurringSymbols) {
50
+ if (ritual.frequency > 0.8 && !surroundingSet.has(ritual.name)) {
51
+ deviations.push(`When using '${symbolName}', projects usually also call '${ritual.name}'.`);
52
+ }
53
+ }
54
+ return deviations;
55
+ }
56
+ /**
57
+ * Extract co-occurrence statistics for a symbol
58
+ */
59
+ extractCoOccurrence(symbolName, graph) {
60
+ const results = [];
61
+ const coChanges = graph.coOccurrence.get(symbolName);
62
+ if (!coChanges)
63
+ return results;
64
+ const totalUsage = graph.usage.get(symbolName)?.usageCount || 1;
65
+ for (const [otherName, count] of coChanges.entries()) {
66
+ const frequency = count / totalUsage;
67
+ if (frequency > 0.5) { // Significant ritual if seen in >50% of cases
68
+ results.push({ name: otherName, frequency });
69
+ }
70
+ }
71
+ return results.sort((a, b) => b.frequency - a.frequency);
72
+ }
73
+ }
74
+ export const usagePatternAnalyzer = new UsagePatternAnalyzer();
75
+ //# sourceMappingURL=usagePatterns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usagePatterns.js","sourceRoot":"","sources":["../../src/analyzers/usagePatterns.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * API Contract Guardian - Backend Context Builder
3
+ *
4
+ * Builds the backend context by extracting routes, models, and configuration.
5
+ *
6
+ * @format
7
+ */
8
+ import type { BackendContext, BackendProject } from "../types.js";
9
+ /**
10
+ * Build backend context from a project path
11
+ * Extracts routes, models, and API configuration
12
+ */
13
+ export declare function buildBackendContext(project: BackendProject): Promise<BackendContext>;
14
+ /**
15
+ * Incrementally update backend context when a file changes
16
+ * Only re-extracts from the changed file
17
+ */
18
+ export declare function updateBackendContext(context: BackendContext, projectPath: string, changedFile: string): Promise<BackendContext>;
19
+ //# sourceMappingURL=backend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../../src/api-contract/context/backend.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAOlE;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,cAAc,CAAC,CAyBzB;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,cAAc,CAAC,CAwCzB"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * API Contract Guardian - Backend Context Builder
3
+ *
4
+ * Builds the backend context by extracting routes, models, and configuration.
5
+ *
6
+ * @format
7
+ */
8
+ import { logger } from "../../utils/logger.js";
9
+ import { extractRoutes, extractModels, extractApiConfig, } from "../extractors/python.js";
10
+ /**
11
+ * Build backend context from a project path
12
+ * Extracts routes, models, and API configuration
13
+ */
14
+ export async function buildBackendContext(project) {
15
+ logger.info(`Building backend context for ${project.framework} project...`);
16
+ const startTime = Date.now();
17
+ // Extract routes and models in parallel
18
+ const [routes, models, config] = await Promise.all([
19
+ extractRoutes(project.path, project.framework),
20
+ extractModels(project.path),
21
+ extractApiConfig(project.path),
22
+ ]);
23
+ const context = {
24
+ framework: project.framework,
25
+ routes,
26
+ models,
27
+ apiPrefix: config.apiPrefix,
28
+ };
29
+ logger.info(`Backend context built in ${Date.now() - startTime}ms ` +
30
+ `(${routes.length} routes, ${models.length} models)`);
31
+ return context;
32
+ }
33
+ /**
34
+ * Incrementally update backend context when a file changes
35
+ * Only re-extracts from the changed file
36
+ */
37
+ export async function updateBackendContext(context, projectPath, changedFile) {
38
+ logger.debug(`Updating backend context for changed file: ${changedFile}`);
39
+ // Remove old entries from this file
40
+ context.routes = context.routes.filter((r) => !r.file.includes(changedFile));
41
+ context.models = context.models.filter((m) => !m.file.includes(changedFile));
42
+ // Re-extract from changed file if it's a relevant file
43
+ if (changedFile.includes("/routes/") ||
44
+ changedFile.includes("/routers/") ||
45
+ changedFile.includes("/api/") ||
46
+ changedFile.includes("/models/") ||
47
+ changedFile.includes("/schemas/")) {
48
+ try {
49
+ const fs = await import("fs/promises");
50
+ const content = await fs.readFile(changedFile, "utf-8");
51
+ // Import extractors dynamically to avoid circular dependencies
52
+ const { extractRoutesFromFile, extractModelsFromFile, } = await import("../extractors/python.js");
53
+ const newRoutes = extractRoutesFromFile(content, changedFile, context.framework);
54
+ const newModels = extractModelsFromFile(content, changedFile);
55
+ context.routes.push(...newRoutes);
56
+ context.models.push(...newModels);
57
+ }
58
+ catch (err) {
59
+ logger.debug(`Failed to update context for ${changedFile}`);
60
+ }
61
+ }
62
+ return context;
63
+ }
64
+ //# sourceMappingURL=backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.js","sourceRoot":"","sources":["../../../src/api-contract/context/backend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * API Contract Guardian - Contract Context Builder
3
+ *
4
+ * Links frontend and backend contexts to create a unified contract view.
5
+ *
6
+ * @format
7
+ */
8
+ import type { FrontendContext, BackendContext, ContractContext, EndpointMapping, TypeMapping, ServiceDefinition, RouteDefinition } from "../types.js";
9
+ /**
10
+ * Build contract context by linking frontend and backend
11
+ * Matches services to routes and types to models
12
+ */
13
+ export declare function buildContractContext(frontendContext: FrontendContext, backendContext: BackendContext): Promise<ContractContext>;
14
+ /**
15
+ * Get contract context for a specific endpoint
16
+ */
17
+ export declare function getEndpointContract(context: ContractContext, endpoint: string): EndpointMapping | undefined;
18
+ /**
19
+ * Get type mapping for a specific type
20
+ */
21
+ export declare function getTypeContract(context: ContractContext, typeName: string): TypeMapping | undefined;
22
+ /**
23
+ * Check if a service has a matching backend route
24
+ */
25
+ export declare function hasMatchingRoute(context: ContractContext, service: ServiceDefinition): boolean;
26
+ /**
27
+ * Get all unmatched frontend services
28
+ */
29
+ export declare function getUnmatchedFrontendServices(context: ContractContext): ServiceDefinition[];
30
+ /**
31
+ * Get all unmatched backend routes
32
+ */
33
+ export declare function getUnmatchedBackendRoutes(context: ContractContext): RouteDefinition[];
34
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../../src/api-contract/context/contract.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,eAAe,EACf,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,eAAe,EAIhB,MAAM,aAAa,CAAC;AAErB;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,eAAe,EAAE,eAAe,EAChC,cAAc,EAAE,cAAc,GAC7B,OAAO,CAAC,eAAe,CAAC,CA8D1B;AA0SD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,MAAM,GACf,eAAe,GAAG,SAAS,CAE7B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,MAAM,GACf,WAAW,GAAG,SAAS,CAEzB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAET;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,eAAe,GACvB,iBAAiB,EAAE,CAErB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,eAAe,GACvB,eAAe,EAAE,CAEnB"}
@@ -0,0 +1,306 @@
1
+ /**
2
+ * API Contract Guardian - Contract Context Builder
3
+ *
4
+ * Links frontend and backend contexts to create a unified contract view.
5
+ *
6
+ * @format
7
+ */
8
+ import { logger } from "../../utils/logger.js";
9
+ /**
10
+ * Build contract context by linking frontend and backend
11
+ * Matches services to routes and types to models
12
+ */
13
+ export async function buildContractContext(frontendContext, backendContext) {
14
+ logger.info("Building contract context...");
15
+ const startTime = Date.now();
16
+ const endpoints = new Map();
17
+ const types = new Map();
18
+ const unmatchedFrontend = [];
19
+ const unmatchedBackend = [];
20
+ // Match frontend services to backend routes
21
+ for (const service of frontendContext.services) {
22
+ const matchingRoute = findMatchingRoute(service, backendContext.routes);
23
+ if (matchingRoute) {
24
+ const score = calculateEndpointMatchScore(service, matchingRoute);
25
+ endpoints.set(service.endpoint, {
26
+ frontend: service,
27
+ backend: matchingRoute,
28
+ score,
29
+ });
30
+ }
31
+ else {
32
+ unmatchedFrontend.push(service);
33
+ }
34
+ }
35
+ // Find unmatched backend routes
36
+ for (const route of backendContext.routes) {
37
+ const isMatched = Array.from(endpoints.values()).some((mapping) => mapping.backend === route);
38
+ if (!isMatched) {
39
+ unmatchedBackend.push(route);
40
+ }
41
+ }
42
+ // Match frontend types to backend models
43
+ for (const type of frontendContext.types) {
44
+ const matchingModel = findMatchingModel(type, backendContext.models);
45
+ if (matchingModel) {
46
+ const compatibility = calculateTypeCompatibility(type, matchingModel);
47
+ types.set(type.name, {
48
+ frontend: type,
49
+ backend: matchingModel,
50
+ compatibility,
51
+ });
52
+ }
53
+ }
54
+ const context = {
55
+ endpoints,
56
+ types,
57
+ unmatchedFrontend,
58
+ unmatchedBackend,
59
+ };
60
+ logger.info(`Contract context built in ${Date.now() - startTime}ms ` +
61
+ `(${endpoints.size} matched endpoints, ${types.size} matched types, ` +
62
+ `${unmatchedFrontend.length} unmatched frontend, ${unmatchedBackend.length} unmatched backend)`);
63
+ return context;
64
+ }
65
+ // ============================================================================
66
+ // Endpoint Matching
67
+ // ============================================================================
68
+ /**
69
+ * Find a matching backend route for a frontend service
70
+ */
71
+ function findMatchingRoute(service, routes) {
72
+ // Normalize the service endpoint
73
+ const normalizedEndpoint = normalizePath(service.endpoint);
74
+ // First try exact match
75
+ const exactMatch = routes.find((route) => {
76
+ const normalizedRoute = normalizePath(route.path);
77
+ return (normalizedRoute === normalizedEndpoint &&
78
+ route.method.toUpperCase() === service.method.toUpperCase());
79
+ });
80
+ if (exactMatch) {
81
+ return exactMatch;
82
+ }
83
+ // Try fuzzy match (handle API prefix differences)
84
+ // Frontend: /clients, Backend: /api/clients
85
+ const fuzzyMatch = routes.find((route) => {
86
+ const normalizedRoute = normalizePath(route.path);
87
+ const routeWithoutPrefix = removeApiPrefix(normalizedRoute);
88
+ const serviceWithoutPrefix = removeApiPrefix(normalizedEndpoint);
89
+ return (routeWithoutPrefix === serviceWithoutPrefix &&
90
+ route.method.toUpperCase() === service.method.toUpperCase());
91
+ });
92
+ return fuzzyMatch;
93
+ }
94
+ /**
95
+ * Calculate match score for endpoint mapping
96
+ */
97
+ function calculateEndpointMatchScore(service, route) {
98
+ let score = 100;
99
+ // Method match is critical
100
+ if (service.method.toUpperCase() !== route.method.toUpperCase()) {
101
+ score -= 50;
102
+ }
103
+ // Path match
104
+ const normalizedService = normalizePath(service.endpoint);
105
+ const normalizedRoute = normalizePath(route.path);
106
+ if (normalizedService === normalizedRoute) {
107
+ score += 10;
108
+ }
109
+ else if (removeApiPrefix(normalizedService) === removeApiPrefix(normalizedRoute)) {
110
+ score += 5;
111
+ }
112
+ // Type name match bonus
113
+ if (service.requestType && service.requestType === route.requestModel) {
114
+ score += 10;
115
+ }
116
+ if (service.responseType && service.responseType === route.responseModel) {
117
+ score += 10;
118
+ }
119
+ return Math.max(0, Math.min(100, score));
120
+ }
121
+ // ============================================================================
122
+ // Type Matching
123
+ // ============================================================================
124
+ /**
125
+ * Find a matching backend model for a frontend type
126
+ */
127
+ function findMatchingModel(type, models) {
128
+ // Try exact name match first
129
+ const exactMatch = models.find((m) => m.name === type.name);
130
+ if (exactMatch) {
131
+ return exactMatch;
132
+ }
133
+ // Try normalized name match (handle naming conventions)
134
+ // ClientCreate -> client_create, clientCreate
135
+ const normalizedTypeName = normalizeName(type.name);
136
+ const normalizedMatch = models.find((m) => normalizeName(m.name) === normalizedTypeName);
137
+ if (normalizedMatch) {
138
+ return normalizedMatch;
139
+ }
140
+ // Try fuzzy match based on field similarity
141
+ let bestMatch;
142
+ let bestScore = 0;
143
+ for (const model of models) {
144
+ const score = calculateFieldSimilarity(type, model);
145
+ if (score > bestScore && score > 0.7) {
146
+ // 70% threshold
147
+ bestScore = score;
148
+ bestMatch = model;
149
+ }
150
+ }
151
+ return bestMatch;
152
+ }
153
+ /**
154
+ * Calculate type compatibility between frontend and backend
155
+ */
156
+ function calculateTypeCompatibility(type, model) {
157
+ const issues = [];
158
+ let score = 100;
159
+ // Check for missing required fields in frontend
160
+ for (const modelField of model.fields) {
161
+ if (modelField.required) {
162
+ const frontendField = type.fields.find((f) => normalizeName(f.name) === normalizeName(modelField.name));
163
+ if (!frontendField) {
164
+ score -= 15;
165
+ issues.push(`Missing required field: ${modelField.name}`);
166
+ }
167
+ }
168
+ }
169
+ // Check for naming convention mismatches
170
+ for (const frontendField of type.fields) {
171
+ const backendField = model.fields.find((f) => normalizeName(f.name) === normalizeName(frontendField.name));
172
+ if (backendField && frontendField.name !== backendField.name) {
173
+ score -= 5;
174
+ issues.push(`Naming convention mismatch: ${frontendField.name} vs ${backendField.name}`);
175
+ }
176
+ }
177
+ // Check type compatibility
178
+ for (const frontendField of type.fields) {
179
+ const backendField = model.fields.find((f) => normalizeName(f.name) === normalizeName(frontendField.name));
180
+ if (backendField) {
181
+ const typeCompatible = areTypesCompatible(frontendField.type, backendField.type);
182
+ if (!typeCompatible) {
183
+ score -= 10;
184
+ issues.push(`Type mismatch: ${frontendField.name} (${frontendField.type} vs ${backendField.type})`);
185
+ }
186
+ }
187
+ }
188
+ return {
189
+ score: Math.max(0, score),
190
+ issues,
191
+ };
192
+ }
193
+ /**
194
+ * Calculate field similarity between type and model
195
+ */
196
+ function calculateFieldSimilarity(type, model) {
197
+ if (type.fields.length === 0 || model.fields.length === 0) {
198
+ return 0;
199
+ }
200
+ const typeFieldNames = new Set(type.fields.map((f) => normalizeName(f.name)));
201
+ const modelFieldNames = new Set(model.fields.map((f) => normalizeName(f.name)));
202
+ // Calculate Jaccard similarity
203
+ const intersection = new Set([...typeFieldNames].filter((x) => modelFieldNames.has(x)));
204
+ const union = new Set([...typeFieldNames, ...modelFieldNames]);
205
+ return intersection.size / union.size;
206
+ }
207
+ // ============================================================================
208
+ // Type Compatibility
209
+ // ============================================================================
210
+ /**
211
+ * Check if TypeScript and Python types are compatible
212
+ */
213
+ function areTypesCompatible(tsType, pyType) {
214
+ const typeMap = {
215
+ string: ["str", "String", "text"],
216
+ number: ["int", "float", "Number", "integer", "decimal"],
217
+ boolean: ["bool", "Boolean"],
218
+ Date: ["datetime", "date", "time"],
219
+ "string[]": ["list[str]", "List[str]", "Sequence[str]"],
220
+ "number[]": ["list[int]", "list[float]", "List[int]", "List[float]"],
221
+ object: ["dict", "Dict", "Mapping"],
222
+ "any[]": ["list", "List", "Sequence"],
223
+ };
224
+ // Normalize types
225
+ const normalizedTsType = tsType.toLowerCase().replace(/\s+/g, "");
226
+ const normalizedPyType = pyType.toLowerCase().replace(/\s+/g, "");
227
+ // Direct match
228
+ if (normalizedTsType === normalizedPyType) {
229
+ return true;
230
+ }
231
+ // Check type map
232
+ const compatibleTypes = typeMap[normalizedTsType] || [];
233
+ if (compatibleTypes.some((t) => normalizedPyType.includes(t.toLowerCase().replace(/\s+/g, "")))) {
234
+ return true;
235
+ }
236
+ // Handle optional types
237
+ if (tsType.includes("?") || tsType.includes("undefined")) {
238
+ return true; // Optional fields are always compatible
239
+ }
240
+ if (pyType.toLowerCase().includes("optional")) {
241
+ return true;
242
+ }
243
+ return false;
244
+ }
245
+ // ============================================================================
246
+ // Utility Functions
247
+ // ============================================================================
248
+ /**
249
+ * Normalize a path for comparison
250
+ * Removes trailing slashes and ensures consistent format
251
+ */
252
+ function normalizePath(path) {
253
+ return path
254
+ .replace(/\/+/g, "/") // Remove duplicate slashes
255
+ .replace(/\/$/, "") // Remove trailing slash
256
+ .replace(/^\//, ""); // Remove leading slash
257
+ }
258
+ /**
259
+ * Remove API prefix from path for fuzzy matching
260
+ */
261
+ function removeApiPrefix(path) {
262
+ return path.replace(/^(api|v\d+|rest)\//, "");
263
+ }
264
+ /**
265
+ * Normalize a name for comparison
266
+ * Handles different naming conventions (camelCase, snake_case, PascalCase)
267
+ */
268
+ function normalizeName(name) {
269
+ return (name
270
+ // Convert camelCase/PascalCase to snake_case
271
+ .replace(/([a-z])([A-Z])/g, "$1_$2")
272
+ .toLowerCase()
273
+ // Remove underscores for comparison
274
+ .replace(/_/g, ""));
275
+ }
276
+ /**
277
+ * Get contract context for a specific endpoint
278
+ */
279
+ export function getEndpointContract(context, endpoint) {
280
+ return context.endpoints.get(endpoint);
281
+ }
282
+ /**
283
+ * Get type mapping for a specific type
284
+ */
285
+ export function getTypeContract(context, typeName) {
286
+ return context.types.get(typeName);
287
+ }
288
+ /**
289
+ * Check if a service has a matching backend route
290
+ */
291
+ export function hasMatchingRoute(context, service) {
292
+ return context.endpoints.has(service.endpoint);
293
+ }
294
+ /**
295
+ * Get all unmatched frontend services
296
+ */
297
+ export function getUnmatchedFrontendServices(context) {
298
+ return context.unmatchedFrontend;
299
+ }
300
+ /**
301
+ * Get all unmatched backend routes
302
+ */
303
+ export function getUnmatchedBackendRoutes(context) {
304
+ return context.unmatchedBackend;
305
+ }
306
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../../../src/api-contract/context/contract.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAc/C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,eAAgC,EAChC,cAA8B;IAE9B,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAE5C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,MAAM,SAAS,GAAG,IAAI,GAAG,EAA2B,CAAC;IACrD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC7C,MAAM,iBAAiB,GAAwB,EAAE,CAAC;IAClD,MAAM,gBAAgB,GAAsB,EAAE,CAAC;IAE/C,4CAA4C;IAC5C,KAAK,MAAM,OAAO,IAAI,eAAe,CAAC,QAAQ,EAAE,CAAC;QAC/C,MAAM,aAAa,GAAG,iBAAiB,CAAC,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;QACxE,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,KAAK,GAAG,2BAA2B,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YAClE,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE;gBAC9B,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,aAAa;gBACtB,KAAK;aACN,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,gCAAgC;IAChC,KAAK,MAAM,KAAK,IAAI,cAAc,CAAC,MAAM,EAAE,CAAC;QAC1C,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CACnD,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,KAAK,KAAK,CACvC,CAAC;QACF,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,yCAAyC;IACzC,KAAK,MAAM,IAAI,IAAI,eAAe,CAAC,KAAK,EAAE,CAAC;QACzC,MAAM,aAAa,GAAG,iBAAiB,CAAC,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;QACrE,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,aAAa,GAAG,0BAA0B,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;YACtE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE;gBACnB,QAAQ,EAAE,IAAI;gBACd,OAAO,EAAE,aAAa;gBACtB,aAAa;aACd,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAoB;QAC/B,SAAS;QACT,KAAK;QACL,iBAAiB;QACjB,gBAAgB;KACjB,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,6BAA6B,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,KAAK;QACtD,IAAI,SAAS,CAAC,IAAI,uBAAuB,KAAK,CAAC,IAAI,kBAAkB;QACrE,GAAG,iBAAiB,CAAC,MAAM,wBAAwB,gBAAgB,CAAC,MAAM,qBAAqB,CAClG,CAAC;IAEF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E;;GAEG;AACH,SAAS,iBAAiB,CACxB,OAA0B,EAC1B,MAAyB;IAEzB,iCAAiC;IACjC,MAAM,kBAAkB,GAAG,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE3D,wBAAwB;IACxB,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;QACvC,MAAM,eAAe,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClD,OAAO,CACL,eAAe,KAAK,kBAAkB;YACtC,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAC5D,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,kDAAkD;IAClD,4CAA4C;IAC5C,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;QACvC,MAAM,eAAe,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,kBAAkB,GAAG,eAAe,CAAC,eAAe,CAAC,CAAC;QAC5D,MAAM,oBAAoB,GAAG,eAAe,CAAC,kBAAkB,CAAC,CAAC;QAEjE,OAAO,CACL,kBAAkB,KAAK,oBAAoB;YAC3C,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAC5D,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,SAAS,2BAA2B,CAClC,OAA0B,EAC1B,KAAsB;IAEtB,IAAI,KAAK,GAAG,GAAG,CAAC;IAEhB,2BAA2B;IAC3B,IAAI,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;QAChE,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;IAED,aAAa;IACb,MAAM,iBAAiB,GAAG,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1D,MAAM,eAAe,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElD,IAAI,iBAAiB,KAAK,eAAe,EAAE,CAAC;QAC1C,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;SAAM,IAAI,eAAe,CAAC,iBAAiB,CAAC,KAAK,eAAe,CAAC,eAAe,CAAC,EAAE,CAAC;QACnF,KAAK,IAAI,CAAC,CAAC;IACb,CAAC;IAED,wBAAwB;IACxB,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,KAAK,KAAK,CAAC,YAAY,EAAE,CAAC;QACtE,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;IACD,IAAI,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,YAAY,KAAK,KAAK,CAAC,aAAa,EAAE,CAAC;QACzE,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;IAED,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,+EAA+E;AAC/E,gBAAgB;AAChB,+EAA+E;AAE/E;;GAEG;AACH,SAAS,iBAAiB,CACxB,IAAoB,EACpB,MAAyB;IAEzB,6BAA6B;IAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5D,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,wDAAwD;IACxD,8CAA8C;IAC9C,MAAM,kBAAkB,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CACjC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,kBAAkB,CACpD,CAAC;IAEF,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,4CAA4C;IAC5C,IAAI,SAAsC,CAAC;IAC3C,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,wBAAwB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACpD,IAAI,KAAK,GAAG,SAAS,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;YACrC,gBAAgB;YAChB,SAAS,GAAG,KAAK,CAAC;YAClB,SAAS,GAAG,KAAK,CAAC;QACpB,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,0BAA0B,CACjC,IAAoB,EACpB,KAAsB;IAEtB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,GAAG,GAAG,CAAC;IAEhB,gDAAgD;IAChD,KAAK,MAAM,UAAU,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACtC,IAAI,UAAU,CAAC,QAAQ,EAAE,CAAC;YACxB,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CACpC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,CAChE,CAAC;YAEF,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,KAAK,IAAI,EAAE,CAAC;gBACZ,MAAM,CAAC,IAAI,CAAC,2BAA2B,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;IACH,CAAC;IAED,yCAAyC;IACzC,KAAK,MAAM,aAAa,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QACxC,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CACpC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,aAAa,CAAC,aAAa,CAAC,IAAI,CAAC,CACnE,CAAC;QAEF,IAAI,YAAY,IAAI,aAAa,CAAC,IAAI,KAAK,YAAY,CAAC,IAAI,EAAE,CAAC;YAC7D,KAAK,IAAI,CAAC,CAAC;YACX,MAAM,CAAC,IAAI,CACT,+BAA+B,aAAa,CAAC,IAAI,OAAO,YAAY,CAAC,IAAI,EAAE,CAC5E,CAAC;QACJ,CAAC;IACH,CAAC;IAED,2BAA2B;IAC3B,KAAK,MAAM,aAAa,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QACxC,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CACpC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,aAAa,CAAC,aAAa,CAAC,IAAI,CAAC,CACnE,CAAC;QAEF,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,cAAc,GAAG,kBAAkB,CACvC,aAAa,CAAC,IAAI,EAClB,YAAY,CAAC,IAAI,CAClB,CAAC;YACF,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,KAAK,IAAI,EAAE,CAAC;gBACZ,MAAM,CAAC,IAAI,CACT,kBAAkB,aAAa,CAAC,IAAI,KAAK,aAAa,CAAC,IAAI,OAAO,YAAY,CAAC,IAAI,GAAG,CACvF,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC;QACzB,MAAM;KACP,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,wBAAwB,CAC/B,IAAoB,EACpB,KAAsB;IAEtB,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1D,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9E,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEhF,+BAA+B;IAC/B,MAAM,YAAY,GAAG,IAAI,GAAG,CAC1B,CAAC,GAAG,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAC1D,CAAC;IACF,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,cAAc,EAAE,GAAG,eAAe,CAAC,CAAC,CAAC;IAE/D,OAAO,YAAY,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;AACxC,CAAC;AAED,+EAA+E;AAC/E,qBAAqB;AACrB,+EAA+E;AAE/E;;GAEG;AACH,SAAS,kBAAkB,CAAC,MAAc,EAAE,MAAc;IACxD,MAAM,OAAO,GAA6B;QACxC,MAAM,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC;QACjC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC;QACxD,OAAO,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC;QAC5B,IAAI,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC;QAClC,UAAU,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,eAAe,CAAC;QACvD,UAAU,EAAE,CAAC,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,CAAC;QACpE,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC;QACnC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC;KACtC,CAAC;IAEF,kBAAkB;IAClB,MAAM,gBAAgB,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAClE,MAAM,gBAAgB,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAElE,eAAe;IACf,IAAI,gBAAgB,KAAK,gBAAgB,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,iBAAiB;IACjB,MAAM,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;IACxD,IACE,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CACzB,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAC/D,EACD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,wBAAwB;IACxB,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QACzD,OAAO,IAAI,CAAC,CAAC,wCAAwC;IACvD,CAAC;IAED,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E;;;GAGG;AACH,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,IAAI;SACR,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,2BAA2B;SAChD,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,wBAAwB;SAC3C,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,uBAAuB;AAChD,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,IAAY;IACnC,OAAO,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;AAChD,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,CACL,IAAI;QACF,6CAA6C;SAC5C,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC;SACnC,WAAW,EAAE;QACd,oCAAoC;SACnC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CACrB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAwB,EACxB,QAAgB;IAEhB,OAAO,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAwB,EACxB,QAAgB;IAEhB,OAAO,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAwB,EACxB,OAA0B;IAE1B,OAAO,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,4BAA4B,CAC1C,OAAwB;IAExB,OAAO,OAAO,CAAC,iBAAiB,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CACvC,OAAwB;IAExB,OAAO,OAAO,CAAC,gBAAgB,CAAC;AAClC,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * API Contract Guardian - Frontend Context Builder
3
+ *
4
+ * Builds the frontend context by extracting services, types, and configuration.
5
+ *
6
+ * @format
7
+ */
8
+ import type { FrontendContext, FrontendProject } from "../types.js";
9
+ /**
10
+ * Build frontend context from a project path
11
+ * Extracts services, types, and API configuration
12
+ */
13
+ export declare function buildFrontendContext(project: FrontendProject): Promise<FrontendContext>;
14
+ /**
15
+ * Incrementally update frontend context when a file changes
16
+ * Only re-extracts from the changed file
17
+ */
18
+ export declare function updateFrontendContext(context: FrontendContext, projectPath: string, changedFile: string): Promise<FrontendContext>;
19
+ //# sourceMappingURL=frontend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontend.d.ts","sourceRoot":"","sources":["../../../src/api-contract/context/frontend.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAOpE;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,eAAe,CAAC,CA0B1B;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,eAAe,EACxB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CAoC1B"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * API Contract Guardian - Frontend Context Builder
3
+ *
4
+ * Builds the frontend context by extracting services, types, and configuration.
5
+ *
6
+ * @format
7
+ */
8
+ import { logger } from "../../utils/logger.js";
9
+ import { extractServices, extractTypes, extractApiConfig, } from "../extractors/typescript.js";
10
+ /**
11
+ * Build frontend context from a project path
12
+ * Extracts services, types, and API configuration
13
+ */
14
+ export async function buildFrontendContext(project) {
15
+ logger.info(`Building frontend context for ${project.framework} project...`);
16
+ const startTime = Date.now();
17
+ // Extract services and types in parallel
18
+ const [services, types, config] = await Promise.all([
19
+ extractServices(project.path),
20
+ extractTypes(project.path),
21
+ extractApiConfig(project.path),
22
+ ]);
23
+ const context = {
24
+ framework: project.framework,
25
+ services,
26
+ types,
27
+ apiBaseUrl: config.apiBaseUrl,
28
+ httpClient: config.httpClient,
29
+ };
30
+ logger.info(`Frontend context built in ${Date.now() - startTime}ms ` +
31
+ `(${services.length} services, ${types.length} types)`);
32
+ return context;
33
+ }
34
+ /**
35
+ * Incrementally update frontend context when a file changes
36
+ * Only re-extracts from the changed file
37
+ */
38
+ export async function updateFrontendContext(context, projectPath, changedFile) {
39
+ logger.debug(`Updating frontend context for changed file: ${changedFile}`);
40
+ // Remove old entries from this file
41
+ context.services = context.services.filter((s) => !s.file.includes(changedFile));
42
+ context.types = context.types.filter((t) => !t.file.includes(changedFile));
43
+ // Re-extract from changed file if it's a relevant file
44
+ if (changedFile.includes("/services/") ||
45
+ changedFile.includes("/api/") ||
46
+ changedFile.includes("/types/") ||
47
+ changedFile.includes("/interfaces/")) {
48
+ try {
49
+ const fs = await import("fs/promises");
50
+ const content = await fs.readFile(changedFile, "utf-8");
51
+ // Import extractors dynamically to avoid circular dependencies
52
+ const { extractServicesFromFile, extractTypesFromFile } = await import("../extractors/typescript.js");
53
+ const newServices = extractServicesFromFile(content, changedFile);
54
+ const newTypes = extractTypesFromFile(content, changedFile);
55
+ context.services.push(...newServices);
56
+ context.types.push(...newTypes);
57
+ }
58
+ catch (err) {
59
+ logger.debug(`Failed to update context for ${changedFile}`);
60
+ }
61
+ }
62
+ return context;
63
+ }
64
+ //# sourceMappingURL=frontend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontend.js","sourceRoot":"","sources":["../../../src/api-contract/context/frontend.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C,OAAO,EACL,eAAe,EACf,YAAY,EACZ,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AAErC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAwB;IAExB,MAAM,CAAC,IAAI,CAAC,iCAAiC,OAAO,CAAC,SAAS,aAAa,CAAC,CAAC;IAE7E,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,yCAAyC;IACzC,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAClD,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC;QAC7B,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC;QAC1B,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC;KAC/B,CAAC,CAAC;IAEH,MAAM,OAAO,GAAoB;QAC/B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,QAAQ;QACR,KAAK;QACL,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,UAAU,EAAE,MAAM,CAAC,UAAU;KAC9B,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,6BAA6B,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,KAAK;QACtD,IAAI,QAAQ,CAAC,MAAM,cAAc,KAAK,CAAC,MAAM,SAAS,CACzD,CAAC;IAEF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAAwB,EACxB,WAAmB,EACnB,WAAmB;IAEnB,MAAM,CAAC,KAAK,CAAC,+CAA+C,WAAW,EAAE,CAAC,CAAC;IAE3E,oCAAoC;IACpC,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CACxC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CACrC,CAAC;IACF,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;IAE3E,uDAAuD;IACvD,IACE,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC;QAClC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC;QAC7B,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC/B,WAAW,CAAC,QAAQ,CAAC,cAAc,CAAC,EACpC,CAAC;QACD,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;YACvC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YAExD,+DAA+D;YAC/D,MAAM,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CACpE,6BAA6B,CAC9B,CAAC;YAEF,MAAM,WAAW,GAAG,uBAAuB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YAClE,MAAM,QAAQ,GAAG,oBAAoB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YAE5D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;YACtC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;QAClC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,KAAK,CAAC,gCAAgC,WAAW,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * API Contract Guardian - Project Detector
3
+ *
4
+ * Auto-detects project structure (frontend/backend) without configuration.
5
+ *
6
+ * @format
7
+ */
8
+ import type { ProjectStructure, FrontendFramework, BackendFramework } from "./types.js";
9
+ /**
10
+ * Detect project structure automatically
11
+ * Scans for frontend and backend projects in the given root path
12
+ */
13
+ export declare function detectProjectStructure(rootPath: string): Promise<ProjectStructure>;
14
+ /**
15
+ * Create project structure from manual configuration
16
+ * Used when auto-detection fails or is disabled
17
+ */
18
+ export declare function createProjectStructureFromConfig(config: {
19
+ frontend?: {
20
+ path: string;
21
+ framework: FrontendFramework;
22
+ };
23
+ backend?: {
24
+ path: string;
25
+ framework: BackendFramework;
26
+ };
27
+ }): ProjectStructure;
28
+ //# sourceMappingURL=detector.d.ts.map