skhaall-codeguard 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +125 -0
- package/dist/cli.d.ts +16 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +295 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/indexer.d.ts +21 -0
- package/dist/core/indexer.d.ts.map +1 -0
- package/dist/core/indexer.js +96 -0
- package/dist/core/indexer.js.map +1 -0
- package/dist/graph/dependency-graph.d.ts +37 -0
- package/dist/graph/dependency-graph.d.ts.map +1 -0
- package/dist/graph/dependency-graph.js +94 -0
- package/dist/graph/dependency-graph.js.map +1 -0
- package/dist/graph/impact-resolver.d.ts +40 -0
- package/dist/graph/impact-resolver.d.ts.map +1 -0
- package/dist/graph/impact-resolver.js +108 -0
- package/dist/graph/impact-resolver.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +299 -0
- package/dist/index.js.map +1 -0
- package/dist/parsers/base-parser.d.ts +111 -0
- package/dist/parsers/base-parser.d.ts.map +1 -0
- package/dist/parsers/base-parser.js +7 -0
- package/dist/parsers/base-parser.js.map +1 -0
- package/dist/parsers/detector.d.ts +10 -0
- package/dist/parsers/detector.d.ts.map +1 -0
- package/dist/parsers/detector.js +61 -0
- package/dist/parsers/detector.js.map +1 -0
- package/dist/parsers/extractors/api-calls.d.ts +10 -0
- package/dist/parsers/extractors/api-calls.d.ts.map +1 -0
- package/dist/parsers/extractors/api-calls.js +99 -0
- package/dist/parsers/extractors/api-calls.js.map +1 -0
- package/dist/parsers/extractors/auth-guards.d.ts +8 -0
- package/dist/parsers/extractors/auth-guards.d.ts.map +1 -0
- package/dist/parsers/extractors/auth-guards.js +23 -0
- package/dist/parsers/extractors/auth-guards.js.map +1 -0
- package/dist/parsers/prisma-parser.d.ts +45 -0
- package/dist/parsers/prisma-parser.d.ts.map +1 -0
- package/dist/parsers/prisma-parser.js +197 -0
- package/dist/parsers/prisma-parser.js.map +1 -0
- package/dist/parsers/typescript-parser.d.ts +28 -0
- package/dist/parsers/typescript-parser.d.ts.map +1 -0
- package/dist/parsers/typescript-parser.js +374 -0
- package/dist/parsers/typescript-parser.js.map +1 -0
- package/dist/setup.d.ts +10 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +135 -0
- package/dist/setup.js.map +1 -0
- package/dist/storage/index-store.d.ts +36 -0
- package/dist/storage/index-store.d.ts.map +1 -0
- package/dist/storage/index-store.js +108 -0
- package/dist/storage/index-store.js.map +1 -0
- package/dist/tools/changelog.d.ts +36 -0
- package/dist/tools/changelog.d.ts.map +1 -0
- package/dist/tools/changelog.js +212 -0
- package/dist/tools/changelog.js.map +1 -0
- package/dist/tools/check.d.ts +31 -0
- package/dist/tools/check.d.ts.map +1 -0
- package/dist/tools/check.js +180 -0
- package/dist/tools/check.js.map +1 -0
- package/dist/tools/graph.d.ts +20 -0
- package/dist/tools/graph.d.ts.map +1 -0
- package/dist/tools/graph.js +192 -0
- package/dist/tools/graph.js.map +1 -0
- package/dist/tools/guard.d.ts +30 -0
- package/dist/tools/guard.d.ts.map +1 -0
- package/dist/tools/guard.js +132 -0
- package/dist/tools/guard.js.map +1 -0
- package/dist/tools/health.d.ts +33 -0
- package/dist/tools/health.d.ts.map +1 -0
- package/dist/tools/health.js +241 -0
- package/dist/tools/health.js.map +1 -0
- package/dist/tools/impact.d.ts +10 -0
- package/dist/tools/impact.d.ts.map +1 -0
- package/dist/tools/impact.js +45 -0
- package/dist/tools/impact.js.map +1 -0
- package/dist/tools/regression.d.ts +29 -0
- package/dist/tools/regression.d.ts.map +1 -0
- package/dist/tools/regression.js +151 -0
- package/dist/tools/regression.js.map +1 -0
- package/dist/tools/routes.d.ts +40 -0
- package/dist/tools/routes.d.ts.map +1 -0
- package/dist/tools/routes.js +203 -0
- package/dist/tools/routes.js.map +1 -0
- package/dist/tools/schema.d.ts +37 -0
- package/dist/tools/schema.d.ts.map +1 -0
- package/dist/tools/schema.js +214 -0
- package/dist/tools/schema.js.map +1 -0
- package/dist/tools/search.d.ts +18 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +99 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/tool-definitions.d.ts +15 -0
- package/dist/tools/tool-definitions.d.ts.map +1 -0
- package/dist/tools/tool-definitions.js +157 -0
- package/dist/tools/tool-definitions.js.map +1 -0
- package/dist/utils/import-resolver.d.ts +33 -0
- package/dist/utils/import-resolver.d.ts.map +1 -0
- package/dist/utils/import-resolver.js +150 -0
- package/dist/utils/import-resolver.js.map +1 -0
- package/dist/utils/logger.d.ts +15 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +49 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/path.d.ts +6 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/path.js +12 -0
- package/dist/utils/path.js.map +1 -0
- package/dist/utils/scanner.d.ts +13 -0
- package/dist/utils/scanner.d.ts.map +1 -0
- package/dist/utils/scanner.js +55 -0
- package/dist/utils/scanner.js.map +1 -0
- package/dist/utils/validators.d.ts +45 -0
- package/dist/utils/validators.d.ts.map +1 -0
- package/dist/utils/validators.js +54 -0
- package/dist/utils/validators.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graphe de dependances oriente.
|
|
3
|
+
* Chaque fichier est un noeud, chaque import est une arete.
|
|
4
|
+
* Permet de naviguer dans les deux sens :
|
|
5
|
+
* - dependsOn : "ce fichier depend de..."
|
|
6
|
+
* - dependedBy : "ce fichier est utilise par..."
|
|
7
|
+
*/
|
|
8
|
+
import { resolveImportPath } from '../utils/import-resolver.js';
|
|
9
|
+
export class DependencyGraph {
|
|
10
|
+
/** Fichier → fichiers dont il depend */
|
|
11
|
+
dependsOn = new Map();
|
|
12
|
+
/** Fichier → fichiers qui l'utilisent */
|
|
13
|
+
dependedBy = new Map();
|
|
14
|
+
/** Aretes indexees par cle "from|||to" pour lookup O(1) */
|
|
15
|
+
edgeMap = new Map();
|
|
16
|
+
/** Construit le graphe a partir de l'index du projet */
|
|
17
|
+
static fromIndex(index) {
|
|
18
|
+
const graph = new DependencyGraph();
|
|
19
|
+
for (const [filePath, node] of Object.entries(index.files)) {
|
|
20
|
+
for (const imp of node.imports) {
|
|
21
|
+
// Imports relatifs ET aliases (pas juste les ./)
|
|
22
|
+
const resolvedTarget = resolveImportPath(filePath, imp.source, index.files, index.projectRoot);
|
|
23
|
+
if (!resolvedTarget)
|
|
24
|
+
continue;
|
|
25
|
+
graph.addEdge(filePath, resolvedTarget, imp.name);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return graph;
|
|
29
|
+
}
|
|
30
|
+
addEdge(from, to, importName) {
|
|
31
|
+
// dependsOn
|
|
32
|
+
if (!this.dependsOn.has(from))
|
|
33
|
+
this.dependsOn.set(from, new Set());
|
|
34
|
+
this.dependsOn.get(from).add(to);
|
|
35
|
+
// dependedBy (inverse)
|
|
36
|
+
if (!this.dependedBy.has(to))
|
|
37
|
+
this.dependedBy.set(to, new Set());
|
|
38
|
+
this.dependedBy.get(to).add(from);
|
|
39
|
+
// Edge detail — lookup O(1) via Map
|
|
40
|
+
const key = `${from}|||${to}`;
|
|
41
|
+
const existing = this.edgeMap.get(key);
|
|
42
|
+
if (existing) {
|
|
43
|
+
existing.imports.push(importName);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
this.edgeMap.set(key, { from, to, imports: [importName] });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** Fichiers dont `filePath` depend directement */
|
|
50
|
+
getDependencies(filePath) {
|
|
51
|
+
return [...(this.dependsOn.get(filePath) ?? [])];
|
|
52
|
+
}
|
|
53
|
+
/** Fichiers qui importent `filePath` directement */
|
|
54
|
+
getDependents(filePath) {
|
|
55
|
+
return [...(this.dependedBy.get(filePath) ?? [])];
|
|
56
|
+
}
|
|
57
|
+
/** Tous les fichiers qui importent `filePath`, directement ou en cascade (BFS) */
|
|
58
|
+
getTransitiveDependents(filePath) {
|
|
59
|
+
const visited = new Set();
|
|
60
|
+
const queue = [filePath];
|
|
61
|
+
while (queue.length > 0) {
|
|
62
|
+
const current = queue.shift();
|
|
63
|
+
const dependents = this.dependedBy.get(current);
|
|
64
|
+
if (!dependents)
|
|
65
|
+
continue;
|
|
66
|
+
for (const dep of dependents) {
|
|
67
|
+
if (!visited.has(dep)) {
|
|
68
|
+
visited.add(dep);
|
|
69
|
+
queue.push(dep);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return [...visited];
|
|
74
|
+
}
|
|
75
|
+
/** Toutes les aretes du graphe */
|
|
76
|
+
getEdges() {
|
|
77
|
+
return [...this.edgeMap.values()];
|
|
78
|
+
}
|
|
79
|
+
/** Nombre de noeuds uniques */
|
|
80
|
+
getNodeCount() {
|
|
81
|
+
const nodes = new Set();
|
|
82
|
+
for (const [from, deps] of this.dependsOn) {
|
|
83
|
+
nodes.add(from);
|
|
84
|
+
for (const d of deps)
|
|
85
|
+
nodes.add(d);
|
|
86
|
+
}
|
|
87
|
+
return nodes.size;
|
|
88
|
+
}
|
|
89
|
+
/** Nombre d'aretes */
|
|
90
|
+
getEdgeCount() {
|
|
91
|
+
return this.edgeMap.size;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=dependency-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependency-graph.js","sourceRoot":"","sources":["../../src/graph/dependency-graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calcul d'impact — "je modifie X, qu'est-ce qui casse ?"
|
|
3
|
+
* Utilise le graphe de dependances pour un BFS transitif
|
|
4
|
+
* et enrichit avec le contexte (routes, types, score de risque).
|
|
5
|
+
*/
|
|
6
|
+
import type { ProjectIndex } from '../storage/index-store.js';
|
|
7
|
+
import type { RouteInfo } from '../parsers/base-parser.js';
|
|
8
|
+
export type RiskLevel = 'low' | 'medium' | 'high' | 'critical';
|
|
9
|
+
export interface ImpactResult {
|
|
10
|
+
/** Fichier source de la modification */
|
|
11
|
+
sourceFile: string;
|
|
12
|
+
/** Fichiers impactes directement (1 niveau) */
|
|
13
|
+
directDependents: string[];
|
|
14
|
+
/** Tous les fichiers impactes (transitif) */
|
|
15
|
+
allDependents: string[];
|
|
16
|
+
/** Routes API affectees */
|
|
17
|
+
affectedRoutes: RouteInfo[];
|
|
18
|
+
/** Types/interfaces exportes qui changent potentiellement */
|
|
19
|
+
affectedExports: string[];
|
|
20
|
+
/** Score de risque global */
|
|
21
|
+
risk: RiskLevel;
|
|
22
|
+
/** Raisons du score de risque */
|
|
23
|
+
riskReasons: string[];
|
|
24
|
+
/** Nombre total de fichiers impactes */
|
|
25
|
+
impactCount: number;
|
|
26
|
+
}
|
|
27
|
+
export declare class ImpactResolver {
|
|
28
|
+
private graph;
|
|
29
|
+
private index;
|
|
30
|
+
constructor(index: ProjectIndex);
|
|
31
|
+
/** Calcule l'impact complet d'une modification sur un fichier */
|
|
32
|
+
resolve(filePath: string): ImpactResult;
|
|
33
|
+
/** Trouve toutes les routes API dans les fichiers impactes */
|
|
34
|
+
private findAffectedRoutes;
|
|
35
|
+
/** Liste les exports du fichier modifie (ce qui peut casser les dependants) */
|
|
36
|
+
private findAffectedExports;
|
|
37
|
+
/** Calcule le score de risque */
|
|
38
|
+
private calculateRisk;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=impact-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"impact-resolver.d.ts","sourceRoot":"","sources":["../../src/graph/impact-resolver.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAG3D,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAE/D,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,6CAA6C;IAC7C,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,2BAA2B;IAC3B,cAAc,EAAE,SAAS,EAAE,CAAC;IAC5B,6DAA6D;IAC7D,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,6BAA6B;IAC7B,IAAI,EAAE,SAAS,CAAC;IAChB,iCAAiC;IACjC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,KAAK,CAAe;gBAEhB,KAAK,EAAE,YAAY;IAK/B,iEAAiE;IACjE,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY;IAmBvC,8DAA8D;IAC9D,OAAO,CAAC,kBAAkB;IAW1B,+EAA+E;IAC/E,OAAO,CAAC,mBAAmB;IAM3B,iCAAiC;IACjC,OAAO,CAAC,aAAa;CA4DtB"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calcul d'impact — "je modifie X, qu'est-ce qui casse ?"
|
|
3
|
+
* Utilise le graphe de dependances pour un BFS transitif
|
|
4
|
+
* et enrichit avec le contexte (routes, types, score de risque).
|
|
5
|
+
*/
|
|
6
|
+
import { DependencyGraph } from './dependency-graph.js';
|
|
7
|
+
export class ImpactResolver {
|
|
8
|
+
graph;
|
|
9
|
+
index;
|
|
10
|
+
constructor(index) {
|
|
11
|
+
this.index = index;
|
|
12
|
+
this.graph = DependencyGraph.fromIndex(index);
|
|
13
|
+
}
|
|
14
|
+
/** Calcule l'impact complet d'une modification sur un fichier */
|
|
15
|
+
resolve(filePath) {
|
|
16
|
+
const directDependents = this.graph.getDependents(filePath);
|
|
17
|
+
const allDependents = this.graph.getTransitiveDependents(filePath);
|
|
18
|
+
const affectedRoutes = this.findAffectedRoutes(allDependents);
|
|
19
|
+
const affectedExports = this.findAffectedExports(filePath);
|
|
20
|
+
const { risk, riskReasons } = this.calculateRisk(filePath, allDependents, affectedRoutes);
|
|
21
|
+
return {
|
|
22
|
+
sourceFile: filePath,
|
|
23
|
+
directDependents,
|
|
24
|
+
allDependents,
|
|
25
|
+
affectedRoutes,
|
|
26
|
+
affectedExports,
|
|
27
|
+
risk,
|
|
28
|
+
riskReasons,
|
|
29
|
+
impactCount: allDependents.length,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/** Trouve toutes les routes API dans les fichiers impactes */
|
|
33
|
+
findAffectedRoutes(dependents) {
|
|
34
|
+
const routes = [];
|
|
35
|
+
for (const dep of dependents) {
|
|
36
|
+
const node = this.index.files[dep];
|
|
37
|
+
if (node?.routes.length) {
|
|
38
|
+
routes.push(...node.routes);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return routes;
|
|
42
|
+
}
|
|
43
|
+
/** Liste les exports du fichier modifie (ce qui peut casser les dependants) */
|
|
44
|
+
findAffectedExports(filePath) {
|
|
45
|
+
const node = this.index.files[filePath];
|
|
46
|
+
if (!node)
|
|
47
|
+
return [];
|
|
48
|
+
return node.exports.map((e) => e.name);
|
|
49
|
+
}
|
|
50
|
+
/** Calcule le score de risque */
|
|
51
|
+
calculateRisk(filePath, allDependents, affectedRoutes) {
|
|
52
|
+
const reasons = [];
|
|
53
|
+
let score = 0;
|
|
54
|
+
// Nombre de fichiers impactes
|
|
55
|
+
if (allDependents.length >= 20) {
|
|
56
|
+
score += 3;
|
|
57
|
+
reasons.push(`${allDependents.length} fichiers impactes (cascade large)`);
|
|
58
|
+
}
|
|
59
|
+
else if (allDependents.length >= 10) {
|
|
60
|
+
score += 2;
|
|
61
|
+
reasons.push(`${allDependents.length} fichiers impactes`);
|
|
62
|
+
}
|
|
63
|
+
else if (allDependents.length >= 3) {
|
|
64
|
+
score += 1;
|
|
65
|
+
reasons.push(`${allDependents.length} fichiers impactes`);
|
|
66
|
+
}
|
|
67
|
+
// Routes API touchees
|
|
68
|
+
if (affectedRoutes.length >= 5) {
|
|
69
|
+
score += 3;
|
|
70
|
+
reasons.push(`${affectedRoutes.length} routes API affectees`);
|
|
71
|
+
}
|
|
72
|
+
else if (affectedRoutes.length >= 1) {
|
|
73
|
+
score += 1;
|
|
74
|
+
reasons.push(`${affectedRoutes.length} route(s) API affectee(s)`);
|
|
75
|
+
}
|
|
76
|
+
// Fichier partage (beaucoup d'imports directs)
|
|
77
|
+
const directDeps = this.graph.getDependents(filePath);
|
|
78
|
+
if (directDeps.length >= 10) {
|
|
79
|
+
score += 2;
|
|
80
|
+
reasons.push(`Fichier tres partage (${directDeps.length} imports directs)`);
|
|
81
|
+
}
|
|
82
|
+
// Fichiers sensibles
|
|
83
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
84
|
+
if (normalized.includes('/auth') || normalized.includes('/middleware')) {
|
|
85
|
+
score += 2;
|
|
86
|
+
reasons.push('Fichier dans un domaine sensible (auth/middleware)');
|
|
87
|
+
}
|
|
88
|
+
if (normalized.includes('schema.prisma') || normalized.includes('/models/')) {
|
|
89
|
+
score += 2;
|
|
90
|
+
reasons.push('Fichier lie au schema de donnees');
|
|
91
|
+
}
|
|
92
|
+
// Calcul du niveau
|
|
93
|
+
let risk;
|
|
94
|
+
if (score >= 6)
|
|
95
|
+
risk = 'critical';
|
|
96
|
+
else if (score >= 4)
|
|
97
|
+
risk = 'high';
|
|
98
|
+
else if (score >= 2)
|
|
99
|
+
risk = 'medium';
|
|
100
|
+
else
|
|
101
|
+
risk = 'low';
|
|
102
|
+
if (reasons.length === 0) {
|
|
103
|
+
reasons.push('Impact limite');
|
|
104
|
+
}
|
|
105
|
+
return { risk, riskReasons: reasons };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=impact-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"impact-resolver.js","sourceRoot":"","sources":["../../src/graph/impact-resolver.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;GAIG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CodeGuard — MCP Server
|
|
4
|
+
* Carte du projet + impact analysis pour Claude Code.
|
|
5
|
+
* Communication via stdio (protocole MCP standard).
|
|
6
|
+
*/
|
|
7
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
8
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
9
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
10
|
+
import { resolve } from 'node:path';
|
|
11
|
+
import { statSync } from 'node:fs';
|
|
12
|
+
import { IndexStore } from './storage/index-store.js';
|
|
13
|
+
import { initLogger, logger } from './utils/logger.js';
|
|
14
|
+
import { indexProject as runIndexProject } from './core/indexer.js';
|
|
15
|
+
import { runImpactAnalysis, formatImpactResult } from './tools/impact.js';
|
|
16
|
+
import { searchIndex, formatSearchResult } from './tools/search.js';
|
|
17
|
+
import { runGuard, formatGuardResult } from './tools/guard.js';
|
|
18
|
+
import { runCheck, formatCheckResult } from './tools/check.js';
|
|
19
|
+
import { runHealth, formatHealthResult } from './tools/health.js';
|
|
20
|
+
import { runRegressionMap, formatRegressionResult } from './tools/regression.js';
|
|
21
|
+
import { generateGraph, formatGraphResult } from './tools/graph.js';
|
|
22
|
+
import { runSchemaCheck, formatSchemaResult } from './tools/schema.js';
|
|
23
|
+
import { runRouteGuard, formatRouteGuardResult } from './tools/routes.js';
|
|
24
|
+
import { runChangelog, formatChangelogResult } from './tools/changelog.js';
|
|
25
|
+
import { TOOL_DEFINITIONS } from './tools/tool-definitions.js';
|
|
26
|
+
import { DependencyGraph } from './graph/dependency-graph.js';
|
|
27
|
+
// --- Configuration ---
|
|
28
|
+
const PROJECT_ROOT = process.argv[2] ?? process.cwd();
|
|
29
|
+
const resolvedRoot = resolve(PROJECT_ROOT);
|
|
30
|
+
// Valider que le dossier existe
|
|
31
|
+
try {
|
|
32
|
+
const rootStat = statSync(resolvedRoot);
|
|
33
|
+
if (!rootStat.isDirectory()) {
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
initLogger(resolvedRoot, 'info');
|
|
41
|
+
logger.info('CodeGuard demarre', { projectRoot: resolvedRoot });
|
|
42
|
+
// --- State ---
|
|
43
|
+
let currentIndex = null;
|
|
44
|
+
let currentGraph = null;
|
|
45
|
+
const store = new IndexStore(resolvedRoot);
|
|
46
|
+
/** Reconstruit le graphe a partir de l'index courant */
|
|
47
|
+
function rebuildGraph(index) {
|
|
48
|
+
currentGraph = DependencyGraph.fromIndex(index);
|
|
49
|
+
return currentGraph;
|
|
50
|
+
}
|
|
51
|
+
/** Retourne le graphe cache ou le reconstruit */
|
|
52
|
+
function getGraph() {
|
|
53
|
+
if (currentGraph)
|
|
54
|
+
return currentGraph;
|
|
55
|
+
return rebuildGraph(getIndex());
|
|
56
|
+
}
|
|
57
|
+
// --- Indexation ---
|
|
58
|
+
async function indexProject(incremental = false) {
|
|
59
|
+
const result = await runIndexProject(resolvedRoot, { incremental, store });
|
|
60
|
+
currentIndex = result.index;
|
|
61
|
+
rebuildGraph(result.index);
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
function getIndex() {
|
|
65
|
+
if (currentIndex)
|
|
66
|
+
return currentIndex;
|
|
67
|
+
const loaded = store.load();
|
|
68
|
+
if (loaded) {
|
|
69
|
+
currentIndex = loaded;
|
|
70
|
+
rebuildGraph(loaded);
|
|
71
|
+
return loaded;
|
|
72
|
+
}
|
|
73
|
+
throw new Error('Aucun index disponible. Lancez "reindex" d\'abord.');
|
|
74
|
+
}
|
|
75
|
+
// --- Serveur MCP ---
|
|
76
|
+
const server = new Server({
|
|
77
|
+
name: 'skhaall-codeguard',
|
|
78
|
+
version: '0.1.0',
|
|
79
|
+
}, {
|
|
80
|
+
capabilities: {
|
|
81
|
+
tools: {},
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
// Liste des outils disponibles
|
|
85
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
86
|
+
tools: TOOL_DEFINITIONS,
|
|
87
|
+
}));
|
|
88
|
+
// Execution des outils
|
|
89
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
90
|
+
const { name, arguments: args } = request.params;
|
|
91
|
+
try {
|
|
92
|
+
switch (name) {
|
|
93
|
+
case 'impact': {
|
|
94
|
+
const index = getIndex();
|
|
95
|
+
const filePath = resolveFilePath(requireString(args?.filePath, 'filePath'));
|
|
96
|
+
const result = runImpactAnalysis(index, filePath);
|
|
97
|
+
return {
|
|
98
|
+
content: [{ type: 'text', text: formatImpactResult(result) }],
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
case 'search': {
|
|
102
|
+
const index = getIndex();
|
|
103
|
+
const result = searchIndex(index, requireString(args?.query, 'query'));
|
|
104
|
+
return {
|
|
105
|
+
content: [{ type: 'text', text: formatSearchResult(result) }],
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
case 'reindex': {
|
|
109
|
+
const incremental = args?.incremental === true;
|
|
110
|
+
const { index, stats } = await indexProject(incremental);
|
|
111
|
+
const graph = getGraph();
|
|
112
|
+
const mode = incremental ? 'incremental' : 'complet';
|
|
113
|
+
return {
|
|
114
|
+
content: [
|
|
115
|
+
{
|
|
116
|
+
type: 'text',
|
|
117
|
+
text: [
|
|
118
|
+
`Indexation terminee (${mode}).`,
|
|
119
|
+
`- Fichiers indexes : ${index.fileCount}`,
|
|
120
|
+
`- Noeuds dans le graphe : ${graph.getNodeCount()}`,
|
|
121
|
+
`- Aretes (dependances) : ${graph.getEdgeCount()}`,
|
|
122
|
+
...(incremental ? [
|
|
123
|
+
`- Re-parses : ${stats.parsed} | Inchanges : ${stats.skipped} | Supprimes : ${stats.removed}`,
|
|
124
|
+
] : []),
|
|
125
|
+
`- Date : ${new Date(index.indexedAt).toLocaleString('fr-FR')}`,
|
|
126
|
+
].join('\n'),
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
case 'status': {
|
|
132
|
+
const index = store.load();
|
|
133
|
+
if (!index) {
|
|
134
|
+
return {
|
|
135
|
+
content: [
|
|
136
|
+
{ type: 'text', text: 'Aucun index. Lancez "reindex" pour indexer le projet.' },
|
|
137
|
+
],
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
const age = Date.now() - index.indexedAt;
|
|
141
|
+
const ageMin = Math.round(age / 60000);
|
|
142
|
+
return {
|
|
143
|
+
content: [
|
|
144
|
+
{
|
|
145
|
+
type: 'text',
|
|
146
|
+
text: [
|
|
147
|
+
`## CodeGuard — Status`,
|
|
148
|
+
`- Projet : ${index.projectRoot}`,
|
|
149
|
+
`- Fichiers indexes : ${index.fileCount}`,
|
|
150
|
+
`- Derniere indexation : ${new Date(index.indexedAt).toLocaleString('fr-FR')}`,
|
|
151
|
+
`- Age : ${ageMin < 60 ? `${ageMin} min` : `${Math.round(ageMin / 60)}h`}`,
|
|
152
|
+
].join('\n'),
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
case 'dependencies': {
|
|
158
|
+
getIndex();
|
|
159
|
+
const filePath = resolveFilePath(requireString(args?.filePath, 'filePath'));
|
|
160
|
+
const graph = getGraph();
|
|
161
|
+
const deps = graph.getDependencies(filePath);
|
|
162
|
+
const dependents = graph.getDependents(filePath);
|
|
163
|
+
return {
|
|
164
|
+
content: [
|
|
165
|
+
{
|
|
166
|
+
type: 'text',
|
|
167
|
+
text: [
|
|
168
|
+
`## Dependances : ${filePath}`,
|
|
169
|
+
'',
|
|
170
|
+
`### Ce fichier depend de (${deps.length})`,
|
|
171
|
+
...deps.map((d) => `- ${d}`),
|
|
172
|
+
'',
|
|
173
|
+
`### Utilise par (${dependents.length})`,
|
|
174
|
+
...dependents.map((d) => `- ${d}`),
|
|
175
|
+
].join('\n'),
|
|
176
|
+
},
|
|
177
|
+
],
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
case 'guard': {
|
|
181
|
+
const index = getIndex();
|
|
182
|
+
const filePath = resolveFilePath(requireString(args?.filePath, 'filePath'));
|
|
183
|
+
const result = runGuard(index, filePath);
|
|
184
|
+
return {
|
|
185
|
+
content: [{ type: 'text', text: formatGuardResult(result) }],
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
case 'check': {
|
|
189
|
+
const index = getIndex();
|
|
190
|
+
const filePath = resolveFilePath(requireString(args?.filePath, 'filePath'));
|
|
191
|
+
const result = await runCheck(index, filePath);
|
|
192
|
+
// Appliquer l'index mis a jour et reconstruire le graphe
|
|
193
|
+
currentIndex = result.updatedIndex;
|
|
194
|
+
store.save(result.updatedIndex);
|
|
195
|
+
rebuildGraph(result.updatedIndex);
|
|
196
|
+
return {
|
|
197
|
+
content: [{ type: 'text', text: formatCheckResult(result) }],
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
case 'health': {
|
|
201
|
+
const index = getIndex();
|
|
202
|
+
const result = runHealth(index);
|
|
203
|
+
return {
|
|
204
|
+
content: [{ type: 'text', text: formatHealthResult(result) }],
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
case 'regression_map': {
|
|
208
|
+
const index = getIndex();
|
|
209
|
+
const filePath = resolveFilePath(requireString(args?.filePath, 'filePath'));
|
|
210
|
+
const result = runRegressionMap(index, filePath);
|
|
211
|
+
return {
|
|
212
|
+
content: [{ type: 'text', text: formatRegressionResult(result) }],
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
case 'graph': {
|
|
216
|
+
const index = getIndex();
|
|
217
|
+
const focusFile = args?.filePath ? resolveFilePath(requireString(args.filePath, 'filePath')) : undefined;
|
|
218
|
+
const result = generateGraph(index, focusFile);
|
|
219
|
+
return {
|
|
220
|
+
content: [{ type: 'text', text: formatGraphResult(result) }],
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
case 'schema_check': {
|
|
224
|
+
const index = getIndex();
|
|
225
|
+
const result = runSchemaCheck(index);
|
|
226
|
+
return {
|
|
227
|
+
content: [{ type: 'text', text: formatSchemaResult(result) }],
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
case 'route_guard': {
|
|
231
|
+
const index = getIndex();
|
|
232
|
+
const result = runRouteGuard(index);
|
|
233
|
+
return {
|
|
234
|
+
content: [{ type: 'text', text: formatRouteGuardResult(result) }],
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
case 'changelog': {
|
|
238
|
+
const index = getIndex();
|
|
239
|
+
const snapshot = store.loadSnapshot();
|
|
240
|
+
const result = runChangelog(index, snapshot);
|
|
241
|
+
return {
|
|
242
|
+
content: [{ type: 'text', text: formatChangelogResult(result) }],
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
default:
|
|
246
|
+
return {
|
|
247
|
+
content: [{ type: 'text', text: `Outil inconnu : ${name}` }],
|
|
248
|
+
isError: true,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
254
|
+
logger.error('Erreur outil', { tool: name, error: message });
|
|
255
|
+
return {
|
|
256
|
+
content: [{ type: 'text', text: `Erreur : ${message}` }],
|
|
257
|
+
isError: true,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
function requireString(value, name) {
|
|
262
|
+
if (typeof value !== 'string' || value.length === 0) {
|
|
263
|
+
throw new Error(`Parametre "${name}" requis (string non vide)`);
|
|
264
|
+
}
|
|
265
|
+
return value;
|
|
266
|
+
}
|
|
267
|
+
function resolveFilePath(input) {
|
|
268
|
+
if (!input)
|
|
269
|
+
throw new Error('Chemin de fichier requis');
|
|
270
|
+
// Resoudre par rapport a la racine du projet
|
|
271
|
+
const resolved = input.startsWith('/') || input.match(/^[A-Z]:\\/i)
|
|
272
|
+
? resolve(input)
|
|
273
|
+
: resolve(resolvedRoot, input);
|
|
274
|
+
// Bloquer le path traversal — le chemin doit rester dans le projet
|
|
275
|
+
const normalizedResolved = resolved.replace(/\\/g, '/').toLowerCase();
|
|
276
|
+
const normalizedRoot = resolvedRoot.replace(/\\/g, '/').toLowerCase();
|
|
277
|
+
if (!normalizedResolved.startsWith(normalizedRoot)) {
|
|
278
|
+
throw new Error(`Chemin hors du projet interdit : ${input}`);
|
|
279
|
+
}
|
|
280
|
+
return resolved;
|
|
281
|
+
}
|
|
282
|
+
// --- Demarrage ---
|
|
283
|
+
async function main() {
|
|
284
|
+
// Charger l'index existant s'il y en a un
|
|
285
|
+
const existing = store.load();
|
|
286
|
+
if (existing) {
|
|
287
|
+
currentIndex = existing;
|
|
288
|
+
rebuildGraph(existing);
|
|
289
|
+
logger.info('Index charge depuis le cache', { fileCount: existing.fileCount });
|
|
290
|
+
}
|
|
291
|
+
const transport = new StdioServerTransport();
|
|
292
|
+
await server.connect(transport);
|
|
293
|
+
logger.info('Serveur MCP connecte (stdio)');
|
|
294
|
+
}
|
|
295
|
+
main().catch((error) => {
|
|
296
|
+
logger.error('Crash serveur', { error: String(error) });
|
|
297
|
+
process.exit(1);
|
|
298
|
+
});
|
|
299
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|