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.
Files changed (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +125 -0
  3. package/dist/cli.d.ts +16 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +295 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/core/indexer.d.ts +21 -0
  8. package/dist/core/indexer.d.ts.map +1 -0
  9. package/dist/core/indexer.js +96 -0
  10. package/dist/core/indexer.js.map +1 -0
  11. package/dist/graph/dependency-graph.d.ts +37 -0
  12. package/dist/graph/dependency-graph.d.ts.map +1 -0
  13. package/dist/graph/dependency-graph.js +94 -0
  14. package/dist/graph/dependency-graph.js.map +1 -0
  15. package/dist/graph/impact-resolver.d.ts +40 -0
  16. package/dist/graph/impact-resolver.d.ts.map +1 -0
  17. package/dist/graph/impact-resolver.js +108 -0
  18. package/dist/graph/impact-resolver.js.map +1 -0
  19. package/dist/index.d.ts +8 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +299 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/parsers/base-parser.d.ts +111 -0
  24. package/dist/parsers/base-parser.d.ts.map +1 -0
  25. package/dist/parsers/base-parser.js +7 -0
  26. package/dist/parsers/base-parser.js.map +1 -0
  27. package/dist/parsers/detector.d.ts +10 -0
  28. package/dist/parsers/detector.d.ts.map +1 -0
  29. package/dist/parsers/detector.js +61 -0
  30. package/dist/parsers/detector.js.map +1 -0
  31. package/dist/parsers/extractors/api-calls.d.ts +10 -0
  32. package/dist/parsers/extractors/api-calls.d.ts.map +1 -0
  33. package/dist/parsers/extractors/api-calls.js +99 -0
  34. package/dist/parsers/extractors/api-calls.js.map +1 -0
  35. package/dist/parsers/extractors/auth-guards.d.ts +8 -0
  36. package/dist/parsers/extractors/auth-guards.d.ts.map +1 -0
  37. package/dist/parsers/extractors/auth-guards.js +23 -0
  38. package/dist/parsers/extractors/auth-guards.js.map +1 -0
  39. package/dist/parsers/prisma-parser.d.ts +45 -0
  40. package/dist/parsers/prisma-parser.d.ts.map +1 -0
  41. package/dist/parsers/prisma-parser.js +197 -0
  42. package/dist/parsers/prisma-parser.js.map +1 -0
  43. package/dist/parsers/typescript-parser.d.ts +28 -0
  44. package/dist/parsers/typescript-parser.d.ts.map +1 -0
  45. package/dist/parsers/typescript-parser.js +374 -0
  46. package/dist/parsers/typescript-parser.js.map +1 -0
  47. package/dist/setup.d.ts +10 -0
  48. package/dist/setup.d.ts.map +1 -0
  49. package/dist/setup.js +135 -0
  50. package/dist/setup.js.map +1 -0
  51. package/dist/storage/index-store.d.ts +36 -0
  52. package/dist/storage/index-store.d.ts.map +1 -0
  53. package/dist/storage/index-store.js +108 -0
  54. package/dist/storage/index-store.js.map +1 -0
  55. package/dist/tools/changelog.d.ts +36 -0
  56. package/dist/tools/changelog.d.ts.map +1 -0
  57. package/dist/tools/changelog.js +212 -0
  58. package/dist/tools/changelog.js.map +1 -0
  59. package/dist/tools/check.d.ts +31 -0
  60. package/dist/tools/check.d.ts.map +1 -0
  61. package/dist/tools/check.js +180 -0
  62. package/dist/tools/check.js.map +1 -0
  63. package/dist/tools/graph.d.ts +20 -0
  64. package/dist/tools/graph.d.ts.map +1 -0
  65. package/dist/tools/graph.js +192 -0
  66. package/dist/tools/graph.js.map +1 -0
  67. package/dist/tools/guard.d.ts +30 -0
  68. package/dist/tools/guard.d.ts.map +1 -0
  69. package/dist/tools/guard.js +132 -0
  70. package/dist/tools/guard.js.map +1 -0
  71. package/dist/tools/health.d.ts +33 -0
  72. package/dist/tools/health.d.ts.map +1 -0
  73. package/dist/tools/health.js +241 -0
  74. package/dist/tools/health.js.map +1 -0
  75. package/dist/tools/impact.d.ts +10 -0
  76. package/dist/tools/impact.d.ts.map +1 -0
  77. package/dist/tools/impact.js +45 -0
  78. package/dist/tools/impact.js.map +1 -0
  79. package/dist/tools/regression.d.ts +29 -0
  80. package/dist/tools/regression.d.ts.map +1 -0
  81. package/dist/tools/regression.js +151 -0
  82. package/dist/tools/regression.js.map +1 -0
  83. package/dist/tools/routes.d.ts +40 -0
  84. package/dist/tools/routes.d.ts.map +1 -0
  85. package/dist/tools/routes.js +203 -0
  86. package/dist/tools/routes.js.map +1 -0
  87. package/dist/tools/schema.d.ts +37 -0
  88. package/dist/tools/schema.d.ts.map +1 -0
  89. package/dist/tools/schema.js +214 -0
  90. package/dist/tools/schema.js.map +1 -0
  91. package/dist/tools/search.d.ts +18 -0
  92. package/dist/tools/search.d.ts.map +1 -0
  93. package/dist/tools/search.js +99 -0
  94. package/dist/tools/search.js.map +1 -0
  95. package/dist/tools/tool-definitions.d.ts +15 -0
  96. package/dist/tools/tool-definitions.d.ts.map +1 -0
  97. package/dist/tools/tool-definitions.js +157 -0
  98. package/dist/tools/tool-definitions.js.map +1 -0
  99. package/dist/utils/import-resolver.d.ts +33 -0
  100. package/dist/utils/import-resolver.d.ts.map +1 -0
  101. package/dist/utils/import-resolver.js +150 -0
  102. package/dist/utils/import-resolver.js.map +1 -0
  103. package/dist/utils/logger.d.ts +15 -0
  104. package/dist/utils/logger.d.ts.map +1 -0
  105. package/dist/utils/logger.js +49 -0
  106. package/dist/utils/logger.js.map +1 -0
  107. package/dist/utils/path.d.ts +6 -0
  108. package/dist/utils/path.d.ts.map +1 -0
  109. package/dist/utils/path.js +12 -0
  110. package/dist/utils/path.js.map +1 -0
  111. package/dist/utils/scanner.d.ts +13 -0
  112. package/dist/utils/scanner.d.ts.map +1 -0
  113. package/dist/utils/scanner.js +55 -0
  114. package/dist/utils/scanner.js.map +1 -0
  115. package/dist/utils/validators.d.ts +45 -0
  116. package/dist/utils/validators.d.ts.map +1 -0
  117. package/dist/utils/validators.js +54 -0
  118. package/dist/utils/validators.js.map +1 -0
  119. 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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"}
@@ -0,0 +1,8 @@
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
+ export {};
8
+ //# sourceMappingURL=index.d.ts.map
@@ -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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"}