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,55 @@
1
+ /**
2
+ * Database Schema Analysis
3
+ * Parses SQL migrations, Prisma schemas, Drizzle definitions,
4
+ * SQLAlchemy models, TypeORM entities, and Sequelize models.
5
+ */
6
+ export interface DBColumn {
7
+ name: string;
8
+ type: string;
9
+ nullable?: boolean;
10
+ primary?: boolean;
11
+ unique?: boolean;
12
+ default?: string;
13
+ /** FK target */
14
+ references?: string;
15
+ }
16
+ export interface DBTable {
17
+ name: string;
18
+ columns: DBColumn[];
19
+ indexes?: string[];
20
+ /** File where defined */
21
+ source: string;
22
+ orm?: string;
23
+ }
24
+ export interface DBSchemaResult {
25
+ tables: DBTable[];
26
+ relationships: {
27
+ from: string;
28
+ to: string;
29
+ type: 'one-to-one' | 'one-to-many' | 'many-to-many';
30
+ through?: string;
31
+ }[];
32
+ migrations: {
33
+ file: string;
34
+ timestamp?: string;
35
+ description?: string;
36
+ }[];
37
+ summary: {
38
+ totalTables: number;
39
+ totalColumns: number;
40
+ totalRelationships: number;
41
+ orms: string[];
42
+ };
43
+ scannedPatterns: string[];
44
+ }
45
+ /**
46
+ * Analyze database schema from SQL, ORM, and migration files.
47
+ * @param cwd - The working directory to scan.
48
+ * @param options - Configuration options.
49
+ * @param options.directory - The directory to analyze.
50
+ * @returns The database schema analysis result.
51
+ */
52
+ export declare function analyzeDBSchema(cwd: string, options?: {
53
+ directory?: string;
54
+ }): Promise<DBSchemaResult>;
55
+ //# sourceMappingURL=db-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-schema.d.ts","sourceRoot":"","sources":["../../src/analyzers/db-schema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,QAAQ,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,aAAa,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,YAAY,GAAG,aAAa,GAAG,cAAc,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACrH,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACzE,OAAO,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACnG,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AA+FD;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAkI5G"}
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Database Schema Analysis
3
+ * Parses SQL migrations, Prisma schemas, Drizzle definitions,
4
+ * SQLAlchemy models, TypeORM entities, and Sequelize models.
5
+ */
6
+ import { listFiles } from '../search/fast-search.js';
7
+ import { readFile } from 'node:fs/promises';
8
+ import path from 'node:path';
9
+ function parseSQLCreateTable(sql, file) {
10
+ const tables = [];
11
+ const createMatches = sql.matchAll(/CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?[`"']?(\w+)[`"']?\s*\(([\s\S]*?)\)\s*;/gi);
12
+ for (const match of createMatches) {
13
+ const tableName = match[1];
14
+ const columnsBlock = match[2];
15
+ const columns = [];
16
+ for (const line of columnsBlock.split('\n')) {
17
+ const trimmed = line.trim().replace(/,$/, '');
18
+ if (!trimmed || /^(PRIMARY|UNIQUE|INDEX|KEY|CONSTRAINT|CHECK|FOREIGN)/i.test(trimmed))
19
+ continue;
20
+ const colMatch = trimmed.match(/^[`"']?(\w+)[`"']?\s+(\w+(?:\([^)]+\))?)/i);
21
+ if (colMatch) {
22
+ const col = { name: colMatch[1], type: colMatch[2] };
23
+ if (/NOT\s+NULL/i.test(trimmed))
24
+ col.nullable = false;
25
+ if (/\bNULL\b/i.test(trimmed) && !/NOT\s+NULL/i.test(trimmed))
26
+ col.nullable = true;
27
+ if (/PRIMARY\s+KEY/i.test(trimmed))
28
+ col.primary = true;
29
+ if (/UNIQUE/i.test(trimmed))
30
+ col.unique = true;
31
+ if (/DEFAULT\s+(.+?)(?:,|$)/i.test(trimmed))
32
+ col.default = trimmed.match(/DEFAULT\s+(.+?)(?:,|$)/i)?.[1];
33
+ if (/REFERENCES\s+[`"']?(\w+)/i.test(trimmed))
34
+ col.references = trimmed.match(/REFERENCES\s+[`"']?(\w+)/i)?.[1];
35
+ columns.push(col);
36
+ }
37
+ }
38
+ tables.push({ name: tableName, columns, source: file, orm: 'sql' });
39
+ }
40
+ return tables;
41
+ }
42
+ function parsePrismaSchema(content, file) {
43
+ const tables = [];
44
+ const modelMatches = content.matchAll(/model\s+(\w+)\s*\{([\s\S]*?)\}/g);
45
+ for (const match of modelMatches) {
46
+ const tableName = match[1];
47
+ const body = match[2];
48
+ const columns = [];
49
+ for (const line of body.split('\n')) {
50
+ const trimmed = line.trim();
51
+ if (!trimmed || trimmed.startsWith('//') || trimmed.startsWith('@@'))
52
+ continue;
53
+ const fieldMatch = trimmed.match(/^(\w+)\s+(\w+)(\?|\[\])?/);
54
+ if (fieldMatch) {
55
+ const col = {
56
+ name: fieldMatch[1],
57
+ type: fieldMatch[2] + (fieldMatch[3] || ''),
58
+ nullable: fieldMatch[3] === '?',
59
+ };
60
+ if (/@id/.test(trimmed))
61
+ col.primary = true;
62
+ if (/@unique/.test(trimmed))
63
+ col.unique = true;
64
+ if (/@default\((.+?)\)/.test(trimmed))
65
+ col.default = trimmed.match(/@default\((.+?)\)/)?.[1];
66
+ if (/@relation/.test(trimmed)) {
67
+ const refMatch = trimmed.match(/references:\s*\[(\w+)\]/);
68
+ if (refMatch)
69
+ col.references = fieldMatch[2];
70
+ }
71
+ columns.push(col);
72
+ }
73
+ }
74
+ tables.push({ name: tableName, columns, source: file, orm: 'prisma' });
75
+ }
76
+ return tables;
77
+ }
78
+ function parseDrizzleSchema(content, file) {
79
+ const tables = [];
80
+ const tableMatches = content.matchAll(/(?:export\s+const\s+)?(\w+)\s*=\s*(?:pg|mysql|sqlite)Table\s*\(\s*['"](\w+)['"]\s*,\s*\{([\s\S]*?)\}\s*\)/g);
81
+ for (const match of tableMatches) {
82
+ const tableName = match[2];
83
+ const body = match[3];
84
+ const columns = [];
85
+ const colMatches = body.matchAll(/(\w+)\s*:\s*(\w+)\s*\(\s*['"]?(\w+)['"]?\s*\)/g);
86
+ for (const col of colMatches) {
87
+ const column = { name: col[3] || col[1], type: col[2] };
88
+ const fullLine = body.slice(body.indexOf(col[0]));
89
+ if (/\.primaryKey\(\)/.test(fullLine))
90
+ column.primary = true;
91
+ if (/\.notNull\(\)/.test(fullLine))
92
+ column.nullable = false;
93
+ if (/\.unique\(\)/.test(fullLine))
94
+ column.unique = true;
95
+ if (/\.references\(\)/.test(fullLine))
96
+ column.references = 'foreign_key';
97
+ columns.push(column);
98
+ }
99
+ tables.push({ name: tableName, columns, source: file, orm: 'drizzle' });
100
+ }
101
+ return tables;
102
+ }
103
+ /**
104
+ * Analyze database schema from SQL, ORM, and migration files.
105
+ * @param cwd - The working directory to scan.
106
+ * @param options - Configuration options.
107
+ * @param options.directory - The directory to analyze.
108
+ * @returns The database schema analysis result.
109
+ */
110
+ export async function analyzeDBSchema(cwd, options) {
111
+ const dir = path.resolve(cwd, options?.directory || '.');
112
+ const allTables = [];
113
+ const migrations = [];
114
+ const orms = new Set();
115
+ // 1. SQL migration files
116
+ const sqlGlobs = ['**/*.sql', '**/migrations/**/*.sql', '**/migrate/**/*.sql'];
117
+ for (const glob of sqlGlobs) {
118
+ const files = await listFiles(dir, { glob }).catch(() => []);
119
+ for (const file of files.slice(0, 100)) {
120
+ try {
121
+ const content = await readFile(path.resolve(dir, file), 'utf-8');
122
+ const tables = parseSQLCreateTable(content, file);
123
+ allTables.push(...tables);
124
+ if (tables.length > 0)
125
+ orms.add('sql');
126
+ // Track as migration
127
+ const tsMatch = file.match(/(\d{10,14})/);
128
+ migrations.push({ file, timestamp: tsMatch?.[1], description: path.basename(file) });
129
+ }
130
+ catch {
131
+ /* skip */
132
+ }
133
+ }
134
+ }
135
+ // 2. Prisma schema
136
+ const prismaFiles = await listFiles(dir, { glob: '**/schema.prisma' }).catch(() => []);
137
+ for (const file of prismaFiles) {
138
+ try {
139
+ const content = await readFile(path.resolve(dir, file), 'utf-8');
140
+ const tables = parsePrismaSchema(content, file);
141
+ allTables.push(...tables);
142
+ if (tables.length > 0)
143
+ orms.add('prisma');
144
+ }
145
+ catch {
146
+ /* skip */
147
+ }
148
+ }
149
+ // 3. Drizzle schemas
150
+ const drizzleFiles = await listFiles(dir, { glob: '**/schema.{ts,js}' }).catch(() => []);
151
+ for (const file of drizzleFiles) {
152
+ try {
153
+ const content = await readFile(path.resolve(dir, file), 'utf-8');
154
+ if (/pgTable|mysqlTable|sqliteTable/.test(content)) {
155
+ const tables = parseDrizzleSchema(content, file);
156
+ allTables.push(...tables);
157
+ if (tables.length > 0)
158
+ orms.add('drizzle');
159
+ }
160
+ }
161
+ catch {
162
+ /* skip */
163
+ }
164
+ }
165
+ // 4. TypeORM / Sequelize entities (basic detection)
166
+ const entityFiles = await listFiles(dir, { glob: '**/*.entity.{ts,js}' }).catch(() => []);
167
+ const modelFiles = await listFiles(dir, { glob: '**/models/**/*.{ts,js}' }).catch(() => []);
168
+ for (const file of [...entityFiles, ...modelFiles].slice(0, 100)) {
169
+ try {
170
+ const content = await readFile(path.resolve(dir, file), 'utf-8');
171
+ if (/@Entity/.test(content) || /sequelize/.test(content)) {
172
+ const classMatch = content.match(/class\s+(\w+)/);
173
+ if (classMatch) {
174
+ const columns = [];
175
+ const colMatches = content.matchAll(/@Column\s*\(?\s*(?:\{[^}]*type:\s*['"]?(\w+)['"]?)?[^)]*\)?\s*\n?\s*(\w+)/g);
176
+ for (const col of colMatches) {
177
+ columns.push({ name: col[2], type: col[1] || 'unknown' });
178
+ }
179
+ allTables.push({
180
+ name: classMatch[1],
181
+ columns,
182
+ source: file,
183
+ orm: /@Entity/.test(content) ? 'typeorm' : 'sequelize',
184
+ });
185
+ orms.add(/@Entity/.test(content) ? 'typeorm' : 'sequelize');
186
+ }
187
+ }
188
+ }
189
+ catch {
190
+ /* skip */
191
+ }
192
+ }
193
+ // Detect relationships from foreign keys / references
194
+ const relationships = [];
195
+ for (const table of allTables) {
196
+ for (const col of table.columns) {
197
+ if (col.references) {
198
+ relationships.push({ from: table.name, to: col.references, type: 'one-to-many' });
199
+ }
200
+ }
201
+ }
202
+ // Detect many-to-many join tables
203
+ for (const table of allTables) {
204
+ const fkCols = table.columns.filter((c) => c.references);
205
+ if (fkCols.length >= 2 && table.columns.length <= fkCols.length + 2) {
206
+ relationships.push({
207
+ from: fkCols[0].references,
208
+ to: fkCols[1].references,
209
+ type: 'many-to-many',
210
+ through: table.name,
211
+ });
212
+ }
213
+ }
214
+ const totalColumns = allTables.reduce((sum, t) => sum + t.columns.length, 0);
215
+ const scannedPatterns = [
216
+ '**/*.sql',
217
+ '**/migrations/**/*.sql',
218
+ '**/migrate/**/*.sql',
219
+ '**/schema.prisma',
220
+ '**/schema.{ts,js} (Drizzle)',
221
+ '**/*.entity.{ts,js} (TypeORM)',
222
+ '**/models/**/*.{ts,js} (Sequelize)',
223
+ ];
224
+ return {
225
+ tables: allTables,
226
+ relationships,
227
+ migrations: migrations.slice(0, 50),
228
+ summary: {
229
+ totalTables: allTables.length,
230
+ totalColumns,
231
+ totalRelationships: relationships.length,
232
+ orms: [...orms],
233
+ },
234
+ scannedPatterns,
235
+ };
236
+ }
237
+ //# sourceMappingURL=db-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-schema.js","sourceRoot":"","sources":["../../src/analyzers/db-schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Dead Code Detection
3
+ * Finds unused exports, unreferenced symbols, and orphan files.
4
+ */
5
+ export interface DeadCodeResult {
6
+ unusedExports: {
7
+ file: string;
8
+ symbol: string;
9
+ line: number;
10
+ type: string;
11
+ }[];
12
+ orphanFiles: {
13
+ file: string;
14
+ reason: string;
15
+ }[];
16
+ summary: {
17
+ totalUnusedExports: number;
18
+ totalOrphanFiles: number;
19
+ filesScanned: number;
20
+ };
21
+ }
22
+ /**
23
+ * Detect dead code including unused exports and orphan files in a directory.
24
+ * @param cwd - The working directory to scan
25
+ * @param options - Configuration options
26
+ * @param options.directory - Subdirectory to scan
27
+ * @param options.fileGlob - Glob pattern for files to include
28
+ * @returns Dead code analysis results including unused exports and orphan files
29
+ */
30
+ export declare function detectDeadCode(cwd: string, options?: {
31
+ directory?: string;
32
+ fileGlob?: string;
33
+ }): Promise<DeadCodeResult>;
34
+ //# sourceMappingURL=dead-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dead-code.d.ts","sourceRoot":"","sources":["../../src/analyzers/dead-code.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC9E,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAChD,OAAO,EAAE;QAAE,kBAAkB,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;CACzF;AAsCD;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAClD,OAAO,CAAC,cAAc,CAAC,CAiFzB"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Dead Code Detection
3
+ * Finds unused exports, unreferenced symbols, and orphan files.
4
+ */
5
+ import { searchCode, listFiles } from '../search/fast-search.js';
6
+ import { extractSymbols } from '../analyzers/symbols.js';
7
+ import { readFile } from 'node:fs/promises';
8
+ import path from 'node:path';
9
+ function parseImportDetails(content) {
10
+ const results = [];
11
+ // JS/TS imports
12
+ const jsMatches = content.matchAll(/import\s+(?:\{([^}]+)\}|(\w+))\s+from\s+['"]([^'"]+)['"]/g);
13
+ for (const m of jsMatches) {
14
+ const names = m[1]
15
+ ? m[1]
16
+ .split(',')
17
+ .map((n) => n
18
+ .trim()
19
+ .split(/\s+as\s+/)[0]
20
+ .trim())
21
+ .filter(Boolean)
22
+ : m[2]
23
+ ? [m[2]]
24
+ : [];
25
+ results.push({ from: m[3], names });
26
+ }
27
+ // Python imports
28
+ const pyMatches = content.matchAll(/from\s+(\S+)\s+import\s+(.+)/g);
29
+ for (const m of pyMatches) {
30
+ results.push({
31
+ from: m[1],
32
+ names: m[2].split(',').map((n) => n
33
+ .trim()
34
+ .split(/\s+as\s+/)[0]
35
+ .trim()),
36
+ });
37
+ }
38
+ return results;
39
+ }
40
+ /**
41
+ * Detect dead code including unused exports and orphan files in a directory.
42
+ * @param cwd - The working directory to scan
43
+ * @param options - Configuration options
44
+ * @param options.directory - Subdirectory to scan
45
+ * @param options.fileGlob - Glob pattern for files to include
46
+ * @returns Dead code analysis results including unused exports and orphan files
47
+ */
48
+ export async function detectDeadCode(cwd, options) {
49
+ const glob = options?.fileGlob || '**/*.{ts,tsx,js,jsx,py,java,go,rs,rb,php}';
50
+ const dir = path.resolve(cwd, options?.directory || '.');
51
+ const files = await listFiles(dir, { glob });
52
+ const sourceFiles = files.filter((f) => !/(test|spec|__test__|\.d\.ts)/i.test(f)).slice(0, 300);
53
+ // Collect all exported symbols
54
+ const allExports = [];
55
+ const allImportedNames = new Set();
56
+ const importedModules = new Set();
57
+ for (const file of sourceFiles) {
58
+ try {
59
+ const absPath = path.resolve(dir, file);
60
+ const content = await readFile(absPath, 'utf-8');
61
+ // Get symbols and mark exported ones
62
+ const symbols = await extractSymbols(absPath);
63
+ const lines = content.split('\n');
64
+ for (const sym of symbols) {
65
+ const line = lines[sym.line - 1] || '';
66
+ if (/^export\b/.test(line.trim()) || /\bexport\b/.test(line)) {
67
+ allExports.push({ file, symbol: sym.name, line: sym.line, type: sym.kind });
68
+ }
69
+ }
70
+ // Parse imports to build reference set
71
+ const imports = parseImportDetails(content);
72
+ for (const imp of imports) {
73
+ importedModules.add(imp.from);
74
+ for (const name of imp.names)
75
+ allImportedNames.add(name);
76
+ }
77
+ }
78
+ catch {
79
+ /* skip */
80
+ }
81
+ }
82
+ // Find unused exports
83
+ const unusedExports = [];
84
+ for (const exp of allExports) {
85
+ if (['main', 'default', 'index', 'app', 'handler', 'setup', 'init'].includes(exp.symbol.toLowerCase()))
86
+ continue;
87
+ if (/\/(index|main|app|server|cli)\.[^/]+$/.test(exp.file))
88
+ continue;
89
+ if (!allImportedNames.has(exp.symbol)) {
90
+ // Double-check with search
91
+ try {
92
+ const refs = await searchCode({ cwd: dir, pattern: exp.symbol, maxResults: 5 });
93
+ const external = refs.filter((r) => r.file !== exp.file);
94
+ if (external.length === 0)
95
+ unusedExports.push(exp);
96
+ }
97
+ catch {
98
+ unusedExports.push(exp);
99
+ }
100
+ }
101
+ }
102
+ // Find orphan files
103
+ const orphanFiles = [];
104
+ const normalizedImports = new Set([...importedModules].map((f) => f.replace(/^[./]+/, '').replace(/\.[^.]+$/, '')));
105
+ for (const file of sourceFiles.slice(0, 200)) {
106
+ if (/\/(index|main|app|server|cli|config)\.[^/]+$/.test(file))
107
+ continue;
108
+ if (/(test|spec|\.config)/i.test(file))
109
+ continue;
110
+ const normalized = file.replace(/^[./]+/, '').replace(/\.[^.]+$/, '');
111
+ let isImported = false;
112
+ for (const imp of normalizedImports) {
113
+ if (imp.endsWith(path.basename(normalized)) || normalized.endsWith(imp)) {
114
+ isImported = true;
115
+ break;
116
+ }
117
+ }
118
+ if (!isImported)
119
+ orphanFiles.push({ file, reason: 'Not imported by any other file' });
120
+ }
121
+ return {
122
+ unusedExports: unusedExports.slice(0, 100),
123
+ orphanFiles: orphanFiles.slice(0, 50),
124
+ summary: {
125
+ totalUnusedExports: unusedExports.length,
126
+ totalOrphanFiles: orphanFiles.length,
127
+ filesScanned: sourceFiles.length,
128
+ },
129
+ };
130
+ }
131
+ //# sourceMappingURL=dead-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dead-code.js","sourceRoot":"","sources":["../../src/analyzers/dead-code.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Dependency Vulnerability Scanner
3
+ * Cross-references package lock files (package-lock.json, yarn.lock, pnpm-lock.yaml,
4
+ * Cargo.lock, Pipfile.lock, go.sum) against known vulnerability patterns.
5
+ * Checks for outdated packages, known-vulnerable version ranges, and security advisories.
6
+ */
7
+ export interface VulnDependency {
8
+ name: string;
9
+ version: string;
10
+ severity: 'critical' | 'high' | 'medium' | 'low' | 'info';
11
+ reason: string;
12
+ file: string;
13
+ ecosystem: 'npm' | 'cargo' | 'pip' | 'go' | 'unknown';
14
+ recommendation?: string;
15
+ }
16
+ export interface DepVulnResult {
17
+ vulnerabilities: VulnDependency[];
18
+ totalDeps: number;
19
+ outdatedCount: number;
20
+ ecosystems: string[];
21
+ lockFiles: string[];
22
+ summary: {
23
+ critical: number;
24
+ high: number;
25
+ medium: number;
26
+ low: number;
27
+ info: number;
28
+ };
29
+ }
30
+ /**
31
+ * Main vulnerability scan function.
32
+ * @param cwd - The working directory to scan
33
+ * @returns Vulnerability scan results with findings and summary
34
+ */
35
+ export declare function scanDependencyVulns(cwd: string): Promise<DepVulnResult>;
36
+ //# sourceMappingURL=dep-vuln.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dep-vuln.d.ts","sourceRoot":"","sources":["../../src/analyzers/dep-vuln.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,KAAK,GAAG,OAAO,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACxF;AAwLD;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAqJ7E"}