codedev-mcp 3.2.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 (229) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/LICENSE +21 -0
  3. package/README.md +760 -0
  4. package/dist/analyzers/api-contract.d.ts +46 -0
  5. package/dist/analyzers/api-contract.d.ts.map +1 -0
  6. package/dist/analyzers/api-contract.js +319 -0
  7. package/dist/analyzers/api-contract.js.map +1 -0
  8. package/dist/analyzers/architecture.d.ts +37 -0
  9. package/dist/analyzers/architecture.d.ts.map +1 -0
  10. package/dist/analyzers/architecture.js +149 -0
  11. package/dist/analyzers/architecture.js.map +1 -0
  12. package/dist/analyzers/branch-compare.d.ts +46 -0
  13. package/dist/analyzers/branch-compare.d.ts.map +1 -0
  14. package/dist/analyzers/branch-compare.js +128 -0
  15. package/dist/analyzers/branch-compare.js.map +1 -0
  16. package/dist/analyzers/cicd.d.ts +42 -0
  17. package/dist/analyzers/cicd.d.ts.map +1 -0
  18. package/dist/analyzers/cicd.js +237 -0
  19. package/dist/analyzers/cicd.js.map +1 -0
  20. package/dist/analyzers/codebase.d.ts +64 -0
  21. package/dist/analyzers/codebase.d.ts.map +1 -0
  22. package/dist/analyzers/codebase.js +354 -0
  23. package/dist/analyzers/codebase.js.map +1 -0
  24. package/dist/analyzers/complexity-heatmap.d.ts +50 -0
  25. package/dist/analyzers/complexity-heatmap.d.ts.map +1 -0
  26. package/dist/analyzers/complexity-heatmap.js +156 -0
  27. package/dist/analyzers/complexity-heatmap.js.map +1 -0
  28. package/dist/analyzers/context-pack.d.ts +43 -0
  29. package/dist/analyzers/context-pack.d.ts.map +1 -0
  30. package/dist/analyzers/context-pack.js +232 -0
  31. package/dist/analyzers/context-pack.js.map +1 -0
  32. package/dist/analyzers/coverage.d.ts +70 -0
  33. package/dist/analyzers/coverage.d.ts.map +1 -0
  34. package/dist/analyzers/coverage.js +313 -0
  35. package/dist/analyzers/coverage.js.map +1 -0
  36. package/dist/analyzers/db-schema.d.ts +55 -0
  37. package/dist/analyzers/db-schema.d.ts.map +1 -0
  38. package/dist/analyzers/db-schema.js +237 -0
  39. package/dist/analyzers/db-schema.js.map +1 -0
  40. package/dist/analyzers/dead-code.d.ts +34 -0
  41. package/dist/analyzers/dead-code.d.ts.map +1 -0
  42. package/dist/analyzers/dead-code.js +131 -0
  43. package/dist/analyzers/dead-code.js.map +1 -0
  44. package/dist/analyzers/dep-vuln.d.ts +36 -0
  45. package/dist/analyzers/dep-vuln.d.ts.map +1 -0
  46. package/dist/analyzers/dep-vuln.js +342 -0
  47. package/dist/analyzers/dep-vuln.js.map +1 -0
  48. package/dist/analyzers/docs.d.ts +47 -0
  49. package/dist/analyzers/docs.d.ts.map +1 -0
  50. package/dist/analyzers/docs.js +473 -0
  51. package/dist/analyzers/docs.js.map +1 -0
  52. package/dist/analyzers/git.d.ts +115 -0
  53. package/dist/analyzers/git.d.ts.map +1 -0
  54. package/dist/analyzers/git.js +214 -0
  55. package/dist/analyzers/git.js.map +1 -0
  56. package/dist/analyzers/iac.d.ts +39 -0
  57. package/dist/analyzers/iac.d.ts.map +1 -0
  58. package/dist/analyzers/iac.js +233 -0
  59. package/dist/analyzers/iac.js.map +1 -0
  60. package/dist/analyzers/impact.d.ts +51 -0
  61. package/dist/analyzers/impact.d.ts.map +1 -0
  62. package/dist/analyzers/impact.js +235 -0
  63. package/dist/analyzers/impact.js.map +1 -0
  64. package/dist/analyzers/monorepo.d.ts +36 -0
  65. package/dist/analyzers/monorepo.d.ts.map +1 -0
  66. package/dist/analyzers/monorepo.js +233 -0
  67. package/dist/analyzers/monorepo.js.map +1 -0
  68. package/dist/analyzers/notebook.d.ts +53 -0
  69. package/dist/analyzers/notebook.d.ts.map +1 -0
  70. package/dist/analyzers/notebook.js +149 -0
  71. package/dist/analyzers/notebook.js.map +1 -0
  72. package/dist/analyzers/perf-profile.d.ts +39 -0
  73. package/dist/analyzers/perf-profile.d.ts.map +1 -0
  74. package/dist/analyzers/perf-profile.js +222 -0
  75. package/dist/analyzers/perf-profile.js.map +1 -0
  76. package/dist/analyzers/scaffold.d.ts +46 -0
  77. package/dist/analyzers/scaffold.d.ts.map +1 -0
  78. package/dist/analyzers/scaffold.js +313 -0
  79. package/dist/analyzers/scaffold.js.map +1 -0
  80. package/dist/analyzers/security.d.ts +42 -0
  81. package/dist/analyzers/security.d.ts.map +1 -0
  82. package/dist/analyzers/security.js +281 -0
  83. package/dist/analyzers/security.js.map +1 -0
  84. package/dist/analyzers/symbols.d.ts +49 -0
  85. package/dist/analyzers/symbols.d.ts.map +1 -0
  86. package/dist/analyzers/symbols.js +212 -0
  87. package/dist/analyzers/symbols.js.map +1 -0
  88. package/dist/analyzers/tree-sitter.d.ts +71 -0
  89. package/dist/analyzers/tree-sitter.d.ts.map +1 -0
  90. package/dist/analyzers/tree-sitter.js +333 -0
  91. package/dist/analyzers/tree-sitter.js.map +1 -0
  92. package/dist/analyzers/type-flow.d.ts +39 -0
  93. package/dist/analyzers/type-flow.d.ts.map +1 -0
  94. package/dist/analyzers/type-flow.js +75 -0
  95. package/dist/analyzers/type-flow.js.map +1 -0
  96. package/dist/cache/memory-cache.d.ts +130 -0
  97. package/dist/cache/memory-cache.d.ts.map +1 -0
  98. package/dist/cache/memory-cache.js +273 -0
  99. package/dist/cache/memory-cache.js.map +1 -0
  100. package/dist/config.d.ts +32 -0
  101. package/dist/config.d.ts.map +1 -0
  102. package/dist/config.js +57 -0
  103. package/dist/config.js.map +1 -0
  104. package/dist/constants/instructions.d.ts +2 -0
  105. package/dist/constants/instructions.d.ts.map +1 -0
  106. package/dist/constants/instructions.js +82 -0
  107. package/dist/constants/instructions.js.map +1 -0
  108. package/dist/db/connection.d.ts +12 -0
  109. package/dist/db/connection.d.ts.map +1 -0
  110. package/dist/db/connection.js +34 -0
  111. package/dist/db/connection.js.map +1 -0
  112. package/dist/db/json-store.d.ts +111 -0
  113. package/dist/db/json-store.d.ts.map +1 -0
  114. package/dist/db/json-store.js +201 -0
  115. package/dist/db/json-store.js.map +1 -0
  116. package/dist/db/sqlite-store.d.ts +153 -0
  117. package/dist/db/sqlite-store.d.ts.map +1 -0
  118. package/dist/db/sqlite-store.js +388 -0
  119. package/dist/db/sqlite-store.js.map +1 -0
  120. package/dist/index.d.ts +17 -0
  121. package/dist/index.d.ts.map +1 -0
  122. package/dist/index.js +116 -0
  123. package/dist/index.js.map +1 -0
  124. package/dist/resources/health.d.ts +35 -0
  125. package/dist/resources/health.d.ts.map +1 -0
  126. package/dist/resources/health.js +81 -0
  127. package/dist/resources/health.js.map +1 -0
  128. package/dist/schemas/output-schemas.d.ts +517 -0
  129. package/dist/schemas/output-schemas.d.ts.map +1 -0
  130. package/dist/schemas/output-schemas.js +296 -0
  131. package/dist/schemas/output-schemas.js.map +1 -0
  132. package/dist/search/fast-search.d.ts +90 -0
  133. package/dist/search/fast-search.d.ts.map +1 -0
  134. package/dist/search/fast-search.js +387 -0
  135. package/dist/search/fast-search.js.map +1 -0
  136. package/dist/search/semantic.d.ts +26 -0
  137. package/dist/search/semantic.d.ts.map +1 -0
  138. package/dist/search/semantic.js +458 -0
  139. package/dist/search/semantic.js.map +1 -0
  140. package/dist/tools/analysis.d.ts +7 -0
  141. package/dist/tools/analysis.d.ts.map +1 -0
  142. package/dist/tools/analysis.js +491 -0
  143. package/dist/tools/analysis.js.map +1 -0
  144. package/dist/tools/architecture.d.ts +7 -0
  145. package/dist/tools/architecture.d.ts.map +1 -0
  146. package/dist/tools/architecture.js +176 -0
  147. package/dist/tools/architecture.js.map +1 -0
  148. package/dist/tools/devops.d.ts +7 -0
  149. package/dist/tools/devops.d.ts.map +1 -0
  150. package/dist/tools/devops.js +179 -0
  151. package/dist/tools/devops.js.map +1 -0
  152. package/dist/tools/docs.d.ts +7 -0
  153. package/dist/tools/docs.d.ts.map +1 -0
  154. package/dist/tools/docs.js +102 -0
  155. package/dist/tools/docs.js.map +1 -0
  156. package/dist/tools/git.d.ts +7 -0
  157. package/dist/tools/git.d.ts.map +1 -0
  158. package/dist/tools/git.js +475 -0
  159. package/dist/tools/git.js.map +1 -0
  160. package/dist/tools/nav.d.ts +7 -0
  161. package/dist/tools/nav.d.ts.map +1 -0
  162. package/dist/tools/nav.js +275 -0
  163. package/dist/tools/nav.js.map +1 -0
  164. package/dist/tools/notebook.d.ts +7 -0
  165. package/dist/tools/notebook.d.ts.map +1 -0
  166. package/dist/tools/notebook.js +102 -0
  167. package/dist/tools/notebook.js.map +1 -0
  168. package/dist/tools/performance.d.ts +7 -0
  169. package/dist/tools/performance.d.ts.map +1 -0
  170. package/dist/tools/performance.js +59 -0
  171. package/dist/tools/performance.js.map +1 -0
  172. package/dist/tools/quality.d.ts +7 -0
  173. package/dist/tools/quality.d.ts.map +1 -0
  174. package/dist/tools/quality.js +279 -0
  175. package/dist/tools/quality.js.map +1 -0
  176. package/dist/tools/scaffold.d.ts +7 -0
  177. package/dist/tools/scaffold.d.ts.map +1 -0
  178. package/dist/tools/scaffold.js +80 -0
  179. package/dist/tools/scaffold.js.map +1 -0
  180. package/dist/tools/search.d.ts +7 -0
  181. package/dist/tools/search.d.ts.map +1 -0
  182. package/dist/tools/search.js +308 -0
  183. package/dist/tools/search.js.map +1 -0
  184. package/dist/tools/security.d.ts +7 -0
  185. package/dist/tools/security.d.ts.map +1 -0
  186. package/dist/tools/security.js +138 -0
  187. package/dist/tools/security.js.map +1 -0
  188. package/dist/utils/analytics.d.ts +69 -0
  189. package/dist/utils/analytics.d.ts.map +1 -0
  190. package/dist/utils/analytics.js +144 -0
  191. package/dist/utils/analytics.js.map +1 -0
  192. package/dist/utils/concurrency.d.ts +43 -0
  193. package/dist/utils/concurrency.d.ts.map +1 -0
  194. package/dist/utils/concurrency.js +78 -0
  195. package/dist/utils/concurrency.js.map +1 -0
  196. package/dist/utils/fallback.d.ts +52 -0
  197. package/dist/utils/fallback.d.ts.map +1 -0
  198. package/dist/utils/fallback.js +137 -0
  199. package/dist/utils/fallback.js.map +1 -0
  200. package/dist/utils/git-hooks.d.ts +24 -0
  201. package/dist/utils/git-hooks.d.ts.map +1 -0
  202. package/dist/utils/git-hooks.js +108 -0
  203. package/dist/utils/git-hooks.js.map +1 -0
  204. package/dist/utils/languages.d.ts +72 -0
  205. package/dist/utils/languages.d.ts.map +1 -0
  206. package/dist/utils/languages.js +463 -0
  207. package/dist/utils/languages.js.map +1 -0
  208. package/dist/utils/logger.d.ts +13 -0
  209. package/dist/utils/logger.d.ts.map +1 -0
  210. package/dist/utils/logger.js +34 -0
  211. package/dist/utils/logger.js.map +1 -0
  212. package/dist/utils/plugins.d.ts +105 -0
  213. package/dist/utils/plugins.d.ts.map +1 -0
  214. package/dist/utils/plugins.js +325 -0
  215. package/dist/utils/plugins.js.map +1 -0
  216. package/dist/utils/security.d.ts +17 -0
  217. package/dist/utils/security.d.ts.map +1 -0
  218. package/dist/utils/security.js +48 -0
  219. package/dist/utils/security.js.map +1 -0
  220. package/dist/utils/streaming.d.ts +56 -0
  221. package/dist/utils/streaming.d.ts.map +1 -0
  222. package/dist/utils/streaming.js +95 -0
  223. package/dist/utils/streaming.js.map +1 -0
  224. package/dist/version.d.ts +3 -0
  225. package/dist/version.d.ts.map +1 -0
  226. package/dist/version.js +3 -0
  227. package/dist/version.js.map +1 -0
  228. package/mcp.json +100 -0
  229. package/package.json +89 -0
@@ -0,0 +1,46 @@
1
+ /**
2
+ * API Contract Analysis
3
+ * Parses OpenAPI/Swagger specs, GraphQL schemas, tRPC routers,
4
+ * and Express/FastAPI route definitions.
5
+ */
6
+ export interface ApiEndpoint {
7
+ /** GET, POST, PUT, DELETE, QUERY, MUTATION, SUBSCRIPTION */
8
+ method: string;
9
+ /** /api/users/:id or User.name */
10
+ path: string;
11
+ file: string;
12
+ line: number;
13
+ parameters?: {
14
+ name: string;
15
+ in: string;
16
+ type: string;
17
+ required?: boolean;
18
+ }[];
19
+ requestBody?: string;
20
+ responseType?: string;
21
+ description?: string;
22
+ source: 'openapi' | 'graphql' | 'trpc' | 'express' | 'fastapi' | 'nestjs';
23
+ }
24
+ export interface ApiContractResult {
25
+ endpoints: ApiEndpoint[];
26
+ totalEndpoints: number;
27
+ sources: string[];
28
+ specFiles: string[];
29
+ summary: {
30
+ get: number;
31
+ post: number;
32
+ put: number;
33
+ delete: number;
34
+ query: number;
35
+ mutation: number;
36
+ other: number;
37
+ };
38
+ scannedPatterns: string[];
39
+ }
40
+ /**
41
+ * Main API contract analysis function.
42
+ * @param cwd - The working directory to scan.
43
+ * @returns The API contract analysis result.
44
+ */
45
+ export declare function analyzeApiContracts(cwd: string): Promise<ApiContractResult>;
46
+ //# sourceMappingURL=api-contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-contract.d.ts","sourceRoot":"","sources":["../../src/analyzers/api-contract.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,MAAM,WAAW,WAAW;IAC1B,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;CAC3E;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACpH,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AA2MD;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA+HjF"}
@@ -0,0 +1,319 @@
1
+ /**
2
+ * API Contract Analysis
3
+ * Parses OpenAPI/Swagger specs, GraphQL schemas, tRPC routers,
4
+ * and Express/FastAPI route definitions.
5
+ */
6
+ import { listFiles } from '../search/fast-search.js';
7
+ import { readFile } from 'node:fs/promises';
8
+ import path from 'node:path';
9
+ import { logger } from '../utils/logger.js';
10
+ /**
11
+ * Parse OpenAPI/Swagger JSON/YAML.
12
+ * @param content - The file content to parse.
13
+ * @param file - The file path.
14
+ * @returns Parsed API endpoints.
15
+ */
16
+ function parseOpenAPI(content, file) {
17
+ const endpoints = [];
18
+ try {
19
+ const spec = JSON.parse(content);
20
+ const paths = spec.paths || {};
21
+ for (const [urlPath, methods] of Object.entries(paths)) {
22
+ for (const [method, rawDetails] of Object.entries(methods)) {
23
+ if (['get', 'post', 'put', 'delete', 'patch', 'options', 'head'].includes(method)) {
24
+ const details = rawDetails;
25
+ const paramsList = (details.parameters || []);
26
+ const params = paramsList.map((p) => ({
27
+ name: p.name,
28
+ in: p.in,
29
+ type: p.schema?.type || 'unknown',
30
+ required: p.required,
31
+ }));
32
+ const requestBody = details.requestBody;
33
+ const responses = details.responses;
34
+ endpoints.push({
35
+ method: method.toUpperCase(),
36
+ path: urlPath,
37
+ file,
38
+ line: 0,
39
+ parameters: params,
40
+ requestBody: requestBody?.content?.['application/json']?.schema?.$ref || undefined,
41
+ responseType: responses?.['200']?.content?.['application/json']?.schema?.$ref || undefined,
42
+ description: (details.summary || details.description),
43
+ source: 'openapi',
44
+ });
45
+ }
46
+ }
47
+ }
48
+ }
49
+ catch (error) {
50
+ logger.debug(`Failed to parse OpenAPI spec: ${file}`, { error });
51
+ }
52
+ return endpoints;
53
+ }
54
+ /**
55
+ * Parse GraphQL schema definitions.
56
+ * @param content - The file content to parse.
57
+ * @param file - The file path.
58
+ * @returns Parsed API endpoints.
59
+ */
60
+ function parseGraphQL(content, file) {
61
+ const endpoints = [];
62
+ // Find type Query, Mutation, Subscription blocks
63
+ const typeBlockRegex = /type\s+(Query|Mutation|Subscription)\s*\{([^}]+)\}/gs;
64
+ let match;
65
+ while ((match = typeBlockRegex.exec(content)) !== null) {
66
+ const blockType = match[1];
67
+ const body = match[2];
68
+ const blockLine = content.substring(0, match.index).split('\n').length;
69
+ const methodMap = { Query: 'QUERY', Mutation: 'MUTATION', Subscription: 'SUBSCRIPTION' };
70
+ for (const fieldLine of body.split('\n')) {
71
+ const trimmed = fieldLine.trim();
72
+ if (!trimmed || trimmed.startsWith('#'))
73
+ continue;
74
+ const fieldMatch = trimmed.match(/(\w+)\s*(?:\(([^)]*)\))?\s*:\s*(.+)/);
75
+ if (fieldMatch) {
76
+ const params = fieldMatch[2]
77
+ ? fieldMatch[2].split(',').map((p) => {
78
+ const [name, type] = p.trim().split(/\s*:\s*/);
79
+ return {
80
+ name: name.replace('!', ''),
81
+ in: 'argument',
82
+ type: (type || 'unknown').replace('!', ''),
83
+ required: p.includes('!'),
84
+ };
85
+ })
86
+ : [];
87
+ endpoints.push({
88
+ method: methodMap[blockType] || 'QUERY',
89
+ path: `${blockType}.${fieldMatch[1]}`,
90
+ file,
91
+ line: blockLine,
92
+ parameters: params,
93
+ responseType: fieldMatch[3].trim().replace('!', ''),
94
+ source: 'graphql',
95
+ });
96
+ }
97
+ }
98
+ }
99
+ return endpoints;
100
+ }
101
+ /**
102
+ * Parse Express/Fastify route definitions.
103
+ * @param content - The file content to parse.
104
+ * @param file - The file path.
105
+ * @returns Parsed API endpoints.
106
+ */
107
+ function parseExpressRoutes(content, file) {
108
+ const endpoints = [];
109
+ const routeRegex = /(?:app|router)\.(get|post|put|delete|patch)\s*\(\s*['"`]([^'"`]+)['"`]/gi;
110
+ let match;
111
+ while ((match = routeRegex.exec(content)) !== null) {
112
+ const line = content.substring(0, match.index).split('\n').length;
113
+ endpoints.push({
114
+ method: match[1].toUpperCase(),
115
+ path: match[2],
116
+ file,
117
+ line,
118
+ source: 'express',
119
+ });
120
+ }
121
+ return endpoints;
122
+ }
123
+ /**
124
+ * Parse FastAPI route decorators.
125
+ * @param content - The file content to parse.
126
+ * @param file - The file path.
127
+ * @returns Parsed API endpoints.
128
+ */
129
+ function parseFastAPIRoutes(content, file) {
130
+ const endpoints = [];
131
+ const routeRegex = /@(?:app|router)\.(get|post|put|delete|patch)\s*\(\s*['"]([^'"]+)['"]/gi;
132
+ let match;
133
+ while ((match = routeRegex.exec(content)) !== null) {
134
+ const line = content.substring(0, match.index).split('\n').length;
135
+ // Try to extract the function signature
136
+ const afterDeco = content.substring(match.index + match[0].length);
137
+ const funcMatch = afterDeco.match(/(?:async\s+)?def\s+\w+\s*\(([^)]*)\)/);
138
+ const params = funcMatch?.[1]
139
+ ?.split(',')
140
+ .map((p) => p.trim())
141
+ .filter((p) => p && !p.startsWith('self') && !p.startsWith('request'))
142
+ .map((p) => {
143
+ const [name, type] = p.split(/\s*:\s*/);
144
+ return { name, in: 'parameter', type: type || 'unknown' };
145
+ }) || [];
146
+ endpoints.push({
147
+ method: match[1].toUpperCase(),
148
+ path: match[2],
149
+ file,
150
+ line,
151
+ parameters: params,
152
+ source: 'fastapi',
153
+ });
154
+ }
155
+ return endpoints;
156
+ }
157
+ /**
158
+ * Parse NestJS controller decorators.
159
+ * @param content - The file content to parse.
160
+ * @param file - The file path.
161
+ * @returns Parsed API endpoints.
162
+ */
163
+ function parseNestJSRoutes(content, file) {
164
+ const endpoints = [];
165
+ if (!/@Controller/.test(content))
166
+ return endpoints;
167
+ const controllerPath = content.match(/@Controller\s*\(\s*['"]([^'"]*)['"]\s*\)/)?.[1] || '';
168
+ const routeRegex = /@(Get|Post|Put|Delete|Patch)\s*\(\s*(?:['"]([^'"]*)['"]\s*)?\)/gi;
169
+ let match;
170
+ while ((match = routeRegex.exec(content)) !== null) {
171
+ const line = content.substring(0, match.index).split('\n').length;
172
+ const methodPath = match[2] || '';
173
+ endpoints.push({
174
+ method: match[1].toUpperCase(),
175
+ path: `/${controllerPath}/${methodPath}`.replace(/\/+/g, '/'),
176
+ file,
177
+ line,
178
+ source: 'nestjs',
179
+ });
180
+ }
181
+ return endpoints;
182
+ }
183
+ /**
184
+ * Main API contract analysis function.
185
+ * @param cwd - The working directory to scan.
186
+ * @returns The API contract analysis result.
187
+ */
188
+ export async function analyzeApiContracts(cwd) {
189
+ const allEndpoints = [];
190
+ const specFiles = [];
191
+ const sources = new Set();
192
+ // Find spec files
193
+ const jsonFiles = await listFiles(cwd, { glob: '**/*.{json,yaml,yml}' });
194
+ const gqlFiles = await listFiles(cwd, { glob: '**/*.{graphql,gql}' });
195
+ const tsFiles = await listFiles(cwd, { glob: '**/*.{ts,tsx,js,jsx}' });
196
+ const pyFiles = await listFiles(cwd, { glob: '**/*.py' });
197
+ // OpenAPI specs
198
+ for (const f of jsonFiles.filter((f) => /swagger|openapi/i.test(f)).slice(0, 10)) {
199
+ try {
200
+ const content = await readFile(path.join(cwd, f), 'utf-8');
201
+ const eps = parseOpenAPI(content, f);
202
+ if (eps.length > 0) {
203
+ allEndpoints.push(...eps);
204
+ specFiles.push(f);
205
+ sources.add('openapi');
206
+ }
207
+ }
208
+ catch (error) {
209
+ logger.debug(`Failed to parse possible OpenAPI spec: ${f}`, { error });
210
+ }
211
+ }
212
+ // GraphQL schemas
213
+ for (const f of gqlFiles.slice(0, 20)) {
214
+ try {
215
+ const content = await readFile(path.join(cwd, f), 'utf-8');
216
+ const eps = parseGraphQL(content, f);
217
+ if (eps.length > 0) {
218
+ allEndpoints.push(...eps);
219
+ specFiles.push(f);
220
+ sources.add('graphql');
221
+ }
222
+ }
223
+ catch (error) {
224
+ logger.debug(`Failed to parse possible OpenAPI spec: ${f}`, { error });
225
+ }
226
+ }
227
+ // Express/NestJS routes
228
+ for (const f of tsFiles.slice(0, 300)) {
229
+ try {
230
+ const content = await readFile(path.join(cwd, f), 'utf-8');
231
+ if (/(?:app|router)\.(get|post|put|delete|patch)\s*\(/i.test(content)) {
232
+ const eps = parseExpressRoutes(content, f);
233
+ if (eps.length > 0) {
234
+ allEndpoints.push(...eps);
235
+ specFiles.push(f);
236
+ sources.add('express');
237
+ }
238
+ }
239
+ if (/@Controller/.test(content)) {
240
+ const eps = parseNestJSRoutes(content, f);
241
+ if (eps.length > 0) {
242
+ allEndpoints.push(...eps);
243
+ specFiles.push(f);
244
+ sources.add('nestjs');
245
+ }
246
+ }
247
+ }
248
+ catch (error) {
249
+ logger.debug(`Failed to parse possible OpenAPI spec: ${f}`, { error });
250
+ }
251
+ }
252
+ // FastAPI routes
253
+ for (const f of pyFiles.slice(0, 200)) {
254
+ try {
255
+ const content = await readFile(path.join(cwd, f), 'utf-8');
256
+ if (/@(?:app|router)\.(get|post|put|delete)/.test(content)) {
257
+ const eps = parseFastAPIRoutes(content, f);
258
+ if (eps.length > 0) {
259
+ allEndpoints.push(...eps);
260
+ specFiles.push(f);
261
+ sources.add('fastapi');
262
+ }
263
+ }
264
+ }
265
+ catch (error) {
266
+ logger.debug(`Failed to parse possible OpenAPI spec: ${f}`, { error });
267
+ }
268
+ }
269
+ // Also check for GraphQL in TS/JS files
270
+ for (const f of tsFiles.filter((f) => /schema|graphql|typeDefs/i.test(f)).slice(0, 20)) {
271
+ try {
272
+ const content = await readFile(path.join(cwd, f), 'utf-8');
273
+ if (/type\s+(?:Query|Mutation)\s*\{/.test(content)) {
274
+ const eps = parseGraphQL(content, f);
275
+ if (eps.length > 0) {
276
+ allEndpoints.push(...eps);
277
+ specFiles.push(f);
278
+ sources.add('graphql');
279
+ }
280
+ }
281
+ }
282
+ catch (error) {
283
+ logger.debug(`Failed to parse possible OpenAPI spec: ${f}`, { error });
284
+ }
285
+ }
286
+ const summary = { get: 0, post: 0, put: 0, delete: 0, query: 0, mutation: 0, other: 0 };
287
+ for (const ep of allEndpoints) {
288
+ const m = ep.method.toLowerCase();
289
+ if (m === 'get')
290
+ summary.get++;
291
+ else if (m === 'post')
292
+ summary.post++;
293
+ else if (m === 'put' || m === 'patch')
294
+ summary.put++;
295
+ else if (m === 'delete')
296
+ summary.delete++;
297
+ else if (m === 'query')
298
+ summary.query++;
299
+ else if (m === 'mutation')
300
+ summary.mutation++;
301
+ else
302
+ summary.other++;
303
+ }
304
+ const scannedPatterns = [
305
+ '**/*.{json,yaml,yml} (OpenAPI/Swagger containing swagger|openapi)',
306
+ '**/*.{graphql,gql} (GraphQL schemas)',
307
+ '**/*.{ts,tsx,js,jsx} (Express/NestJS routes with router.get/post/decorators)',
308
+ '**/*.py (FastAPI routes with @app.get/post)',
309
+ ];
310
+ return {
311
+ endpoints: allEndpoints,
312
+ totalEndpoints: allEndpoints.length,
313
+ sources: Array.from(sources),
314
+ specFiles: [...new Set(specFiles)],
315
+ summary,
316
+ scannedPatterns,
317
+ };
318
+ }
319
+ //# sourceMappingURL=api-contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-contract.js","sourceRoot":"","sources":["../../src/analyzers/api-contract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Architecture Rule Enforcement
3
+ * Verify layer boundaries, dependency constraints, circular imports.
4
+ */
5
+ export interface ArchViolation {
6
+ rule: string;
7
+ file: string;
8
+ line?: number;
9
+ message: string;
10
+ severity: 'error' | 'warning';
11
+ importPath?: string;
12
+ }
13
+ export interface ArchResult {
14
+ violations: ArchViolation[];
15
+ rulesChecked: number;
16
+ filesTested: number;
17
+ passed: boolean;
18
+ summary: {
19
+ errors: number;
20
+ warnings: number;
21
+ };
22
+ }
23
+ /**
24
+ * Check architecture rules and detect violations.
25
+ * @param cwd - The working directory to scan.
26
+ * @param options - Configuration options.
27
+ * @param options.builtinRules - Whether to use built-in rules.
28
+ * @param options.directory - The directory to check.
29
+ * @param options.fileGlob - Glob pattern for files to check.
30
+ * @returns The architecture check result with any violations.
31
+ */
32
+ export declare function checkArchitecture(cwd: string, options?: {
33
+ builtinRules?: boolean;
34
+ directory?: string;
35
+ fileGlob?: string;
36
+ }): Promise<ArchResult>;
37
+ //# sourceMappingURL=architecture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"architecture.d.ts","sourceRoot":"","sources":["../../src/analyzers/architecture.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAgGD;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1E,OAAO,CAAC,UAAU,CAAC,CAmDrB"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Architecture Rule Enforcement
3
+ * Verify layer boundaries, dependency constraints, circular imports.
4
+ */
5
+ import { listFiles } from '../search/fast-search.js';
6
+ import { readFile } from 'node:fs/promises';
7
+ import path from 'node:path';
8
+ const BUILTIN_RULES = [
9
+ { name: 'no-circular-imports', type: 'no-circular', description: 'No circular import chains' },
10
+ {
11
+ name: 'controllers-no-direct-db',
12
+ type: 'no-import',
13
+ description: 'Controllers should not import from database layer',
14
+ source: '**/controllers/**',
15
+ forbidden: ['models', 'database', 'db/', 'repositories'],
16
+ },
17
+ {
18
+ name: 'utils-no-domain',
19
+ type: 'no-import',
20
+ description: 'Utils should not import domain logic',
21
+ source: '**/utils/**',
22
+ forbidden: ['services', 'controllers', 'routes', 'handlers'],
23
+ },
24
+ ];
25
+ function matchGlob(p, pattern) {
26
+ const re = pattern.replace(/\*\*/g, '.*').replace(/\*/g, '[^/]*');
27
+ return new RegExp(re).test(p);
28
+ }
29
+ function parseFileImports(content) {
30
+ const imports = [];
31
+ const jsMatches = content.matchAll(/(?:import|from)\s+['"]([^'"]+)['"]/g);
32
+ for (const m of jsMatches)
33
+ imports.push(m[1]);
34
+ const pyMatches = content.matchAll(/(?:from\s+(\S+)\s+import|import\s+(\S+))/g);
35
+ for (const m of pyMatches)
36
+ imports.push(m[1] || m[2]);
37
+ return imports;
38
+ }
39
+ async function detectCircular(dir, files) {
40
+ const violations = [];
41
+ const graph = new Map();
42
+ for (const file of files.slice(0, 300)) {
43
+ try {
44
+ const content = await readFile(path.resolve(dir, file), 'utf-8');
45
+ const imports = parseFileImports(content)
46
+ .filter((i) => i.startsWith('.'))
47
+ .map((i) => path
48
+ .normalize(path.join(path.dirname(file), i))
49
+ .replace(/\\/g, '/')
50
+ .replace(/\.[^.]+$/, ''));
51
+ graph.set(file.replace(/\.[^.]+$/, ''), imports);
52
+ }
53
+ catch {
54
+ /* skip */
55
+ }
56
+ }
57
+ const visited = new Set();
58
+ const stack = new Set();
59
+ function dfs(node, trail) {
60
+ if (stack.has(node)) {
61
+ const idx = trail.indexOf(node);
62
+ if (idx >= 0) {
63
+ violations.push({
64
+ rule: 'no-circular-imports',
65
+ file: node,
66
+ message: `Circular: ${trail.slice(idx).join(' → ')} → ${node}`,
67
+ severity: 'error',
68
+ });
69
+ }
70
+ return;
71
+ }
72
+ if (visited.has(node))
73
+ return;
74
+ visited.add(node);
75
+ stack.add(node);
76
+ for (const dep of graph.get(node) || []) {
77
+ if (graph.has(dep))
78
+ dfs(dep, [...trail, node]);
79
+ }
80
+ stack.delete(node);
81
+ }
82
+ for (const node of graph.keys()) {
83
+ visited.clear();
84
+ stack.clear();
85
+ dfs(node, []);
86
+ }
87
+ return violations.slice(0, 20);
88
+ }
89
+ /**
90
+ * Check architecture rules and detect violations.
91
+ * @param cwd - The working directory to scan.
92
+ * @param options - Configuration options.
93
+ * @param options.builtinRules - Whether to use built-in rules.
94
+ * @param options.directory - The directory to check.
95
+ * @param options.fileGlob - Glob pattern for files to check.
96
+ * @returns The architecture check result with any violations.
97
+ */
98
+ export async function checkArchitecture(cwd, options) {
99
+ const dir = path.resolve(cwd, options?.directory || '.');
100
+ const files = await listFiles(dir, { glob: options?.fileGlob || '**/*.{ts,tsx,js,jsx,py,java,go,rs}' });
101
+ const rules = options?.builtinRules !== false ? BUILTIN_RULES : [];
102
+ const violations = [];
103
+ for (const rule of rules) {
104
+ if (rule.type === 'no-circular') {
105
+ violations.push(...(await detectCircular(dir, files)));
106
+ continue;
107
+ }
108
+ if (rule.type === 'no-import' && rule.forbidden) {
109
+ for (const file of files.slice(0, 300)) {
110
+ if (rule.source && !matchGlob(file, rule.source))
111
+ continue;
112
+ try {
113
+ const content = await readFile(path.resolve(dir, file), 'utf-8');
114
+ const imports = parseFileImports(content);
115
+ const lines = content.split('\n');
116
+ for (const imp of imports) {
117
+ for (const fb of rule.forbidden) {
118
+ if (imp.includes(fb)) {
119
+ const line = lines.findIndex((l) => l.includes(imp)) + 1;
120
+ violations.push({
121
+ rule: rule.name,
122
+ file,
123
+ line,
124
+ message: `${rule.description}: "${file}" imports "${imp}"`,
125
+ severity: 'error',
126
+ importPath: imp,
127
+ });
128
+ }
129
+ }
130
+ }
131
+ }
132
+ catch {
133
+ /* skip */
134
+ }
135
+ }
136
+ }
137
+ }
138
+ return {
139
+ violations: violations.slice(0, 100),
140
+ rulesChecked: rules.length,
141
+ filesTested: Math.min(files.length, 300),
142
+ passed: violations.filter((v) => v.severity === 'error').length === 0,
143
+ summary: {
144
+ errors: violations.filter((v) => v.severity === 'error').length,
145
+ warnings: violations.filter((v) => v.severity === 'warning').length,
146
+ },
147
+ };
148
+ }
149
+ //# sourceMappingURL=architecture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"architecture.js","sourceRoot":"","sources":["../../src/analyzers/architecture.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AA4B7B,MAAM,aAAa,GAAe;IAChC,EAAE,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,2BAA2B,EAAE;IAC9F;QACE,IAAI,EAAE,0BAA0B;QAChC,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,mDAAmD;QAChE,MAAM,EAAE,mBAAmB;QAC3B,SAAS,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,CAAC;KACzD;IACD;QACE,IAAI,EAAE,iBAAiB;QACvB,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,sCAAsC;QACnD,MAAM,EAAE,aAAa;QACrB,SAAS,EAAE,CAAC,UAAU,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,CAAC;KAC7D;CACF,CAAC;AAEF,SAAS,SAAS,CAAC,CAAS,EAAE,OAAe;IAC3C,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAClE,OAAO,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAe;IACvC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,qCAAqC,CAAC,CAAC;IAC1E,KAAK,MAAM,CAAC,IAAI,SAAS;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,2CAA2C,CAAC,CAAC;IAChF,KAAK,MAAM,CAAC,IAAI,SAAS;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,GAAW,EAAE,KAAe;IACxD,MAAM,UAAU,GAAoB,EAAE,CAAC;IACvC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE1C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;YACjE,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC;iBACtC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;iBAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACT,IAAI;iBACD,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;iBAC3C,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;iBACnB,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAC3B,CAAC;YACJ,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,UAAU;QACZ,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,SAAS,GAAG,CAAC,IAAY,EAAE,KAAe;QACxC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACpB,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;gBACb,UAAU,CAAC,IAAI,CAAC;oBACd,IAAI,EAAE,qBAAqB;oBAC3B,IAAI,EAAE,IAAI;oBACV,OAAO,EAAE,aAAa,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE;oBAC9D,QAAQ,EAAE,OAAO;iBAClB,CAAC,CAAC;YACL,CAAC;YACD,OAAO;QACT,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO;QAC9B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChB,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YACxC,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QACjD,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAChC,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACjC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAW,EACX,OAA2E;IAE3E,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,IAAI,GAAG,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,IAAI,oCAAoC,EAAE,CAAC,CAAC;IACxG,MAAM,KAAK,GAAG,OAAO,EAAE,YAAY,KAAK,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,MAAM,UAAU,GAAoB,EAAE,CAAC;IAEvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YAChC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,cAAc,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;YACvD,SAAS;QACX,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAChD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;gBACvC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;oBAAE,SAAS;gBAC3D,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;oBACjE,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;oBAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAClC,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;wBAC1B,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,SAAU,EAAE,CAAC;4BACjC,IAAI,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;gCACrB,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;gCACzD,UAAU,CAAC,IAAI,CAAC;oCACd,IAAI,EAAE,IAAI,CAAC,IAAI;oCACf,IAAI;oCACJ,IAAI;oCACJ,OAAO,EAAE,GAAG,IAAI,CAAC,WAAW,MAAM,IAAI,cAAc,GAAG,GAAG;oCAC1D,QAAQ,EAAE,OAAO;oCACjB,UAAU,EAAE,GAAG;iCAChB,CAAC,CAAC;4BACL,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,UAAU;gBACZ,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,UAAU,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;QACpC,YAAY,EAAE,KAAK,CAAC,MAAM;QAC1B,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC;QACxC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC;QACrE,OAAO,EAAE;YACP,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM;YAC/D,QAAQ,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,MAAM;SACpE;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Branch Compare
3
+ * Structural diff between two git branches — new files, changed symbols,
4
+ * removed exports, stats summary.
5
+ */
6
+ export interface BranchCompareResult {
7
+ base: string;
8
+ compare: string;
9
+ stats: {
10
+ filesAdded: number;
11
+ filesModified: number;
12
+ filesDeleted: number;
13
+ filesRenamed: number;
14
+ totalChanges: number;
15
+ };
16
+ added: string[];
17
+ modified: string[];
18
+ deleted: string[];
19
+ renamed: {
20
+ from: string;
21
+ to: string;
22
+ }[];
23
+ diffStat: {
24
+ file: string;
25
+ insertions: number;
26
+ deletions: number;
27
+ }[];
28
+ commitsBehind: number;
29
+ commitsAhead: number;
30
+ conflictFiles: string[];
31
+ }
32
+ /**
33
+ * Compare two git branches and return structural diff information.
34
+ * @param cwd - The working directory of the git repository.
35
+ * @param base - The base branch name.
36
+ * @param compare - The comparison branch name.
37
+ * @param options - Configuration options.
38
+ * @param options.includeStats - Whether to include diff stats.
39
+ * @param options.showConflicts - Whether to detect potential merge conflicts.
40
+ * @returns The branch comparison result.
41
+ */
42
+ export declare function compareBranches(cwd: string, base: string, compare?: string, options?: {
43
+ includeStats?: boolean;
44
+ showConflicts?: boolean;
45
+ }): Promise<BranchCompareResult>;
46
+ //# sourceMappingURL=branch-compare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-compare.d.ts","sourceRoot":"","sources":["../../src/analyzers/branch-compare.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE;QACL,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACxC,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACpE,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5D,OAAO,CAAC,mBAAmB,CAAC,CAiH9B"}