docstodev 1.0.2 → 1.0.3
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/package.json +1 -1
- package/src/ai/analyzer.ts +3 -1
- package/src/analyzers/languageAnalyzer.ts +297 -5
- package/src/commands/generateSummary.ts +129 -39
- package/src/exporters/html.ts +134 -52
- package/.env +0 -1
- package/dist/ai/analyzer.d.ts +0 -3
- package/dist/ai/analyzer.d.ts.map +0 -1
- package/dist/ai/analyzer.js +0 -43
- package/dist/ai/analyzer.js.map +0 -1
- package/dist/analyzers/languageAnalyzer.d.ts +0 -18
- package/dist/analyzers/languageAnalyzer.d.ts.map +0 -1
- package/dist/analyzers/languageAnalyzer.js +0 -251
- package/dist/analyzers/languageAnalyzer.js.map +0 -1
- package/dist/cache/cacheManager.d.ts +0 -38
- package/dist/cache/cacheManager.d.ts.map +0 -1
- package/dist/cache/cacheManager.js +0 -141
- package/dist/cache/cacheManager.js.map +0 -1
- package/dist/cli/index.d.ts +0 -3
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -316
- package/dist/cli/index.js.map +0 -1
- package/dist/commands/classify.d.ts +0 -2
- package/dist/commands/classify.d.ts.map +0 -1
- package/dist/commands/classify.js +0 -37
- package/dist/commands/classify.js.map +0 -1
- package/dist/commands/generateSummary.d.ts +0 -5
- package/dist/commands/generateSummary.d.ts.map +0 -1
- package/dist/commands/generateSummary.js +0 -54
- package/dist/commands/generateSummary.js.map +0 -1
- package/dist/commands/run.d.ts +0 -5
- package/dist/commands/run.d.ts.map +0 -1
- package/dist/commands/run.js +0 -326
- package/dist/commands/run.js.map +0 -1
- package/dist/exporters/html.d.ts +0 -6
- package/dist/exporters/html.d.ts.map +0 -1
- package/dist/exporters/html.js +0 -517
- package/dist/exporters/html.js.map +0 -1
- package/src/commands/classify.ts +0 -40
package/package.json
CHANGED
package/src/ai/analyzer.ts
CHANGED
|
@@ -19,7 +19,9 @@ Instructions :
|
|
|
19
19
|
- Vous allez recevoir une liste de fichiers, leurs rôles et leurs exports.
|
|
20
20
|
- Pour chaque fichier, rédigez UNE SEULE phrase concise expliquant sa responsabilité métier.
|
|
21
21
|
- Soyez pro, mais gardez votre touche amicale et votre pointe d'humour du Congo-Brazzaville.
|
|
22
|
-
-
|
|
22
|
+
- mentionnez les imports, technique ( "il y a une fonction X"), expliquez le BUT du fichier.
|
|
23
|
+
- selon le nombre d'occurance précisez les couleurs qui reviennen souvent eu suggérez un design systèm , pallette de couleur.
|
|
24
|
+
- donnez une très bref description du but de l'ensemble du projet.
|
|
23
25
|
`;
|
|
24
26
|
|
|
25
27
|
try {
|
|
@@ -9,6 +9,7 @@ export interface FileAnalysisResult {
|
|
|
9
9
|
types: string[];
|
|
10
10
|
imports: Array<{ name: string; type: string; usage?: string | undefined }>;
|
|
11
11
|
exports: string[];
|
|
12
|
+
structure?: Record<string, any>; // Pour les fichiers non-standards
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
// Analyseur TypeScript/JavaScript
|
|
@@ -25,7 +26,6 @@ class TSJSAnalyzer implements LanguageAnalyzer {
|
|
|
25
26
|
|
|
26
27
|
const functions: string[] = [];
|
|
27
28
|
const funcRegex = /(?:export\s+)?(?:async\s+)?function\s+([a-zA-Z0-9_]+)/g;
|
|
28
|
-
// Resetting regex because of global flag
|
|
29
29
|
funcRegex.lastIndex = 0;
|
|
30
30
|
while ((match = funcRegex.exec(content)) !== null) {
|
|
31
31
|
if (match[1]) functions.push(match[1]);
|
|
@@ -266,6 +266,282 @@ class RustAnalyzer implements LanguageAnalyzer {
|
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
+
// Analyseur HTML
|
|
270
|
+
class HTMLAnalyzer implements LanguageAnalyzer {
|
|
271
|
+
extensions = [".html", ".htm"];
|
|
272
|
+
|
|
273
|
+
analyzeFile(content: string): FileAnalysisResult {
|
|
274
|
+
const structure: Record<string, any> = {
|
|
275
|
+
tags: new Set<string>(),
|
|
276
|
+
ids: [] as string[],
|
|
277
|
+
classes: [] as string[],
|
|
278
|
+
scripts: [] as string[],
|
|
279
|
+
styles: [] as string[]
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
// Extraire les balises
|
|
283
|
+
const tagRegex = /<(\w+)/g;
|
|
284
|
+
let match: RegExpExecArray | null;
|
|
285
|
+
while ((match = tagRegex.exec(content)) !== null) {
|
|
286
|
+
if (match[1]) structure.tags.add(match[1].toLowerCase());
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Extraire les IDs
|
|
290
|
+
const idRegex = /id=["']([^"']+)["']/g;
|
|
291
|
+
while ((match = idRegex.exec(content)) !== null) {
|
|
292
|
+
if (match[1]) structure.ids.push(match[1]);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Extraire les classes
|
|
296
|
+
const classRegex = /class=["']([^"']+)["']/g;
|
|
297
|
+
while ((match = classRegex.exec(content)) !== null) {
|
|
298
|
+
if (match[1]) {
|
|
299
|
+
structure.classes.push(...match[1].split(/\s+/).filter(Boolean));
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Extraire les scripts externes
|
|
304
|
+
const scriptRegex = /<script[^>]+src=["']([^"']+)["']/g;
|
|
305
|
+
while ((match = scriptRegex.exec(content)) !== null) {
|
|
306
|
+
if (match[1]) structure.scripts.push(match[1]);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Extraire les stylesheets externes
|
|
310
|
+
const linkRegex = /<link[^>]+href=["']([^"']+\.css)["']/g;
|
|
311
|
+
while ((match = linkRegex.exec(content)) !== null) {
|
|
312
|
+
if (match[1]) structure.styles.push(match[1]);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
structure.tags = Array.from(structure.tags);
|
|
316
|
+
|
|
317
|
+
return {
|
|
318
|
+
functions: [],
|
|
319
|
+
classes: structure.classes,
|
|
320
|
+
types: [],
|
|
321
|
+
imports: [
|
|
322
|
+
...structure.scripts.map((s : string) => ({ name: s, type: 'Script' })),
|
|
323
|
+
...structure.styles.map((s:string) => ({ name: s, type: 'Stylesheet' }))
|
|
324
|
+
],
|
|
325
|
+
exports: [],
|
|
326
|
+
structure
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Analyseur CSS/SCSS/SASS
|
|
332
|
+
class CSSAnalyzer implements LanguageAnalyzer {
|
|
333
|
+
extensions = [".css", ".scss", ".sass", ".less"];
|
|
334
|
+
|
|
335
|
+
analyzeFile(content: string): FileAnalysisResult {
|
|
336
|
+
const structure: Record<string, any> = {
|
|
337
|
+
selectors: [] as string[],
|
|
338
|
+
ids: [] as string[],
|
|
339
|
+
classes: [] as string[],
|
|
340
|
+
variables: [] as string[],
|
|
341
|
+
mixins: [] as string[],
|
|
342
|
+
imports: [] as string[]
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
// Classes CSS
|
|
346
|
+
const classRegex = /\.([a-zA-Z0-9_-]+)/g;
|
|
347
|
+
let match: RegExpExecArray | null;
|
|
348
|
+
while ((match = classRegex.exec(content)) !== null) {
|
|
349
|
+
if (match[1] && !structure.classes.includes(match[1])) {
|
|
350
|
+
structure.classes.push(match[1]);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// IDs CSS
|
|
355
|
+
const idRegex = /#([a-zA-Z0-9_-]+)/g;
|
|
356
|
+
while ((match = idRegex.exec(content)) !== null) {
|
|
357
|
+
if (match[1] && !structure.ids.includes(match[1])) {
|
|
358
|
+
structure.ids.push(match[1]);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Variables CSS/SCSS
|
|
363
|
+
const varRegex = /(?:--|\$)([a-zA-Z0-9_-]+)/g;
|
|
364
|
+
while ((match = varRegex.exec(content)) !== null) {
|
|
365
|
+
if (match[1] && !structure.variables.includes(match[1])) {
|
|
366
|
+
structure.variables.push(match[1]);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Mixins SCSS
|
|
371
|
+
const mixinRegex = /@mixin\s+([a-zA-Z0-9_-]+)/g;
|
|
372
|
+
while ((match = mixinRegex.exec(content)) !== null) {
|
|
373
|
+
if (match[1]) structure.mixins.push(match[1]);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Imports
|
|
377
|
+
const importRegex = /@import\s+['"]([^'"]+)['"]/g;
|
|
378
|
+
while ((match = importRegex.exec(content)) !== null) {
|
|
379
|
+
if (match[1]) structure.imports.push(match[1]);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
return {
|
|
383
|
+
functions: structure.mixins,
|
|
384
|
+
classes: structure.classes,
|
|
385
|
+
types: [],
|
|
386
|
+
imports: structure.imports.map((i:string) => ({ name: i, type: 'CSS' })),
|
|
387
|
+
exports: [],
|
|
388
|
+
structure
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// Analyseur PHP
|
|
394
|
+
class PHPAnalyzer implements LanguageAnalyzer {
|
|
395
|
+
extensions = [".php"];
|
|
396
|
+
|
|
397
|
+
analyzeFile(content: string): FileAnalysisResult {
|
|
398
|
+
const functions: string[] = [];
|
|
399
|
+
const funcRegex = /function\s+([a-zA-Z0-9_]+)\s*\(/g;
|
|
400
|
+
let match: RegExpExecArray | null;
|
|
401
|
+
while ((match = funcRegex.exec(content)) !== null) {
|
|
402
|
+
if (match[1]) functions.push(match[1]);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
const classes: string[] = [];
|
|
406
|
+
const classRegex = /class\s+([a-zA-Z0-9_]+)/g;
|
|
407
|
+
while ((match = classRegex.exec(content)) !== null) {
|
|
408
|
+
if (match[1]) classes.push(match[1]);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
const imports: Array<{ name: string; type: string; usage?: string | undefined }> = [];
|
|
412
|
+
const useRegex = /use\s+([a-zA-Z0-9_\\]+)/g;
|
|
413
|
+
while ((match = useRegex.exec(content)) !== null) {
|
|
414
|
+
if (match[1]) {
|
|
415
|
+
imports.push({ name: match[1], type: 'Composer' });
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const requireRegex = /(?:require|include)(?:_once)?\s*['"]([^'"]+)['"]/g;
|
|
420
|
+
while ((match = requireRegex.exec(content)) !== null) {
|
|
421
|
+
if (match[1]) {
|
|
422
|
+
imports.push({ name: match[1], type: 'Local' });
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
return { functions, classes, types: [], imports, exports: [] };
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// Analyseur Ruby
|
|
431
|
+
class RubyAnalyzer implements LanguageAnalyzer {
|
|
432
|
+
extensions = [".rb"];
|
|
433
|
+
|
|
434
|
+
analyzeFile(content: string): FileAnalysisResult {
|
|
435
|
+
const functions: string[] = [];
|
|
436
|
+
const funcRegex = /def\s+([a-zA-Z0-9_?!]+)/g;
|
|
437
|
+
let match: RegExpExecArray | null;
|
|
438
|
+
while ((match = funcRegex.exec(content)) !== null) {
|
|
439
|
+
if (match[1]) functions.push(match[1]);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
const classes: string[] = [];
|
|
443
|
+
const classRegex = /class\s+([a-zA-Z0-9_]+)/g;
|
|
444
|
+
while ((match = classRegex.exec(content)) !== null) {
|
|
445
|
+
if (match[1]) classes.push(match[1]);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
const imports: Array<{ name: string; type: string; usage?: string | undefined }> = [];
|
|
449
|
+
const requireRegex = /require\s+['"]([^'"]+)['"]/g;
|
|
450
|
+
while ((match = requireRegex.exec(content)) !== null) {
|
|
451
|
+
if (match[1]) {
|
|
452
|
+
imports.push({ name: match[1], type: 'Gem' });
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
return { functions, classes, types: [], imports, exports: [] };
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Analyseur SQL
|
|
461
|
+
class SQLAnalyzer implements LanguageAnalyzer {
|
|
462
|
+
extensions = [".sql"];
|
|
463
|
+
|
|
464
|
+
analyzeFile(content: string): FileAnalysisResult {
|
|
465
|
+
const structure: Record<string, any> = {
|
|
466
|
+
tables: [] as string[],
|
|
467
|
+
procedures: [] as string[],
|
|
468
|
+
functions: [] as string[],
|
|
469
|
+
views: [] as string[]
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
const tableRegex = /CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?([a-zA-Z0-9_]+)/gi;
|
|
473
|
+
let match: RegExpExecArray | null;
|
|
474
|
+
while ((match = tableRegex.exec(content)) !== null) {
|
|
475
|
+
if (match[1]) structure.tables.push(match[1]);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const procRegex = /CREATE\s+(?:OR\s+REPLACE\s+)?PROCEDURE\s+([a-zA-Z0-9_]+)/gi;
|
|
479
|
+
while ((match = procRegex.exec(content)) !== null) {
|
|
480
|
+
if (match[1]) structure.procedures.push(match[1]);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
const funcRegex = /CREATE\s+(?:OR\s+REPLACE\s+)?FUNCTION\s+([a-zA-Z0-9_]+)/gi;
|
|
484
|
+
while ((match = funcRegex.exec(content)) !== null) {
|
|
485
|
+
if (match[1]) structure.functions.push(match[1]);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
const viewRegex = /CREATE\s+(?:OR\s+REPLACE\s+)?VIEW\s+([a-zA-Z0-9_]+)/gi;
|
|
489
|
+
while ((match = viewRegex.exec(content)) !== null) {
|
|
490
|
+
if (match[1]) structure.views.push(match[1]);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
return {
|
|
494
|
+
functions: structure.functions,
|
|
495
|
+
classes: structure.tables,
|
|
496
|
+
types: structure.views,
|
|
497
|
+
imports: [],
|
|
498
|
+
exports: [],
|
|
499
|
+
structure
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// Analyseur par défaut pour tous les autres fichiers
|
|
505
|
+
class DefaultAnalyzer implements LanguageAnalyzer {
|
|
506
|
+
extensions = ["*"]; // Wildcard pour tous les fichiers
|
|
507
|
+
|
|
508
|
+
analyzeFile(content: string): FileAnalysisResult {
|
|
509
|
+
const lines = content.split(/\r?\n/);
|
|
510
|
+
const structure: Record<string, any> = {
|
|
511
|
+
lineCount: lines.length,
|
|
512
|
+
nonEmptyLines: lines.filter(l => l.trim().length > 0).length,
|
|
513
|
+
size: content.length,
|
|
514
|
+
hasCode: /[a-zA-Z0-9_]+\s*[=:({]/.test(content),
|
|
515
|
+
encoding: 'UTF-8'
|
|
516
|
+
};
|
|
517
|
+
|
|
518
|
+
// Détection basique de patterns communs
|
|
519
|
+
const patterns = {
|
|
520
|
+
functions: [] as string[],
|
|
521
|
+
variables: [] as string[],
|
|
522
|
+
comments: [] as string[]
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
// Détection générique de fonctions (pattern commun à beaucoup de langages)
|
|
526
|
+
const genericFuncRegex = /(?:function|func|def|fn|sub|procedure)\s+([a-zA-Z0-9_]+)/gi;
|
|
527
|
+
let match: RegExpExecArray | null;
|
|
528
|
+
while ((match = genericFuncRegex.exec(content)) !== null) {
|
|
529
|
+
if (match[1]) patterns.functions.push(match[1]);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
structure.patterns = patterns;
|
|
533
|
+
|
|
534
|
+
return {
|
|
535
|
+
functions: patterns.functions,
|
|
536
|
+
classes: [],
|
|
537
|
+
types: [],
|
|
538
|
+
imports: [],
|
|
539
|
+
exports: [],
|
|
540
|
+
structure
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
|
|
269
545
|
// Registry des analyseurs
|
|
270
546
|
const analyzers: LanguageAnalyzer[] = [
|
|
271
547
|
new TSJSAnalyzer(),
|
|
@@ -273,16 +549,32 @@ const analyzers: LanguageAnalyzer[] = [
|
|
|
273
549
|
new JavaAnalyzer(),
|
|
274
550
|
new CSharpAnalyzer(),
|
|
275
551
|
new GoAnalyzer(),
|
|
276
|
-
new RustAnalyzer()
|
|
552
|
+
new RustAnalyzer(),
|
|
553
|
+
new HTMLAnalyzer(),
|
|
554
|
+
new CSSAnalyzer(),
|
|
555
|
+
new PHPAnalyzer(),
|
|
556
|
+
new RubyAnalyzer(),
|
|
557
|
+
new SQLAnalyzer()
|
|
277
558
|
];
|
|
278
559
|
|
|
279
|
-
|
|
560
|
+
const defaultAnalyzer = new DefaultAnalyzer();
|
|
561
|
+
|
|
562
|
+
export function getAnalyzer(filePath: string): LanguageAnalyzer {
|
|
280
563
|
const lastDotIndex = filePath.lastIndexOf('.');
|
|
281
|
-
if (lastDotIndex === -1) return
|
|
564
|
+
if (lastDotIndex === -1) return defaultAnalyzer;
|
|
565
|
+
|
|
282
566
|
const ext = filePath.substring(lastDotIndex).toLowerCase();
|
|
283
|
-
return analyzers.find(a => a.extensions.includes(ext)) ||
|
|
567
|
+
return analyzers.find(a => a.extensions.includes(ext)) || defaultAnalyzer;
|
|
284
568
|
}
|
|
285
569
|
|
|
286
570
|
export function getSupportedExtensions(): string[] {
|
|
287
571
|
return analyzers.flatMap(a => a.extensions);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
export function isExplicitlySupported(filePath: string): boolean {
|
|
575
|
+
const lastDotIndex = filePath.lastIndexOf('.');
|
|
576
|
+
if (lastDotIndex === -1) return false;
|
|
577
|
+
|
|
578
|
+
const ext = filePath.substring(lastDotIndex).toLowerCase();
|
|
579
|
+
return analyzers.some(a => a.extensions.includes(ext));
|
|
288
580
|
}
|
|
@@ -3,55 +3,145 @@
|
|
|
3
3
|
import { writeFileSync, mkdirSync } from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
|
|
6
|
+
interface SummaryData {
|
|
7
|
+
totalFiles: number;
|
|
8
|
+
sourceFiles?: number;
|
|
9
|
+
totalComplexity?: number;
|
|
10
|
+
avgComplexity?: number;
|
|
11
|
+
totalDeps?: number;
|
|
12
|
+
topLanguages?: { lang: string; count: number }[];
|
|
13
|
+
criticalFiles?: string[];
|
|
14
|
+
}
|
|
15
|
+
|
|
6
16
|
/**
|
|
7
17
|
* Génère un résumé global du projet avec un ton humain et bilingue.
|
|
8
18
|
*/
|
|
9
|
-
export function generateSummary(
|
|
19
|
+
export function generateSummary(
|
|
20
|
+
docsDir: string,
|
|
21
|
+
data: SummaryData | number,
|
|
22
|
+
lang: "fr" | "en" = "fr"
|
|
23
|
+
) {
|
|
10
24
|
mkdirSync(docsDir, { recursive: true });
|
|
11
25
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
? `# 📊 Vue d'ensemble du Projet – DocsToDev
|
|
17
|
-
|
|
18
|
-
> 📅 **Rapport généré le :** ${dateStr}
|
|
19
|
-
|
|
20
|
-
## 🚀 État des lieux
|
|
21
|
-
Salut ! J'ai passé ton projet au peigne fin. Voici un résumé rapide de ce que j'ai trouvé :
|
|
22
|
-
- **Volume traité :** ${totalFiles} fichiers analysés avec succès.
|
|
23
|
-
- **Diagnostic :** La structure est claire et l'analyse est complète. ✅
|
|
24
|
-
|
|
25
|
-
## 🧭 Navigation Rapide
|
|
26
|
-
Pour aller plus loin, tu peux consulter les documents suivants :
|
|
27
|
-
- **[📂 Arborescence & Analyse](../docs/docs-to-dev.md)** : Pour comprendre la vocation de chaque fichier et les capacités du système.
|
|
28
|
-
- **[💻 Code Source](../)** : Pour retourner explorer la racine de ton projet.
|
|
29
|
-
|
|
30
|
-
---
|
|
31
|
-
*DocsToDev – Ton allié pour une documentation technique vivante et intelligente.*
|
|
32
|
-
`
|
|
33
|
-
: `# 📊 Project Overview – DocsToDev
|
|
26
|
+
// Support de l'ancien format (juste un nombre) et du nouveau format (objet complet)
|
|
27
|
+
const summaryData: SummaryData = typeof data === 'number'
|
|
28
|
+
? { totalFiles: data }
|
|
29
|
+
: data;
|
|
34
30
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
31
|
+
const dateStr = new Date().toLocaleString(lang === "fr" ? "fr-FR" : "en-US", {
|
|
32
|
+
dateStyle: "full",
|
|
33
|
+
timeStyle: "short"
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const t = lang === "fr" ? {
|
|
37
|
+
title: "📊 Vue d'ensemble du Projet – DocsToDev",
|
|
38
|
+
genOn: "Rapport généré le",
|
|
39
|
+
status: "🚀 État des lieux",
|
|
40
|
+
intro: "Salut ! J'ai passé ton projet au peigne fin. Voici un résumé rapide de ce que j'ai trouvé :",
|
|
41
|
+
volume: "Volume traité",
|
|
42
|
+
filesAnalyzed: "fichiers analysés avec succès",
|
|
43
|
+
sourceFiles: "fichiers sources détectés",
|
|
44
|
+
diagnosis: "Diagnostic",
|
|
45
|
+
structureClear: "La structure est claire et l'analyse est complète. ✅",
|
|
46
|
+
metrics: "📈 Métriques clés",
|
|
47
|
+
complexity: "Complexité totale",
|
|
48
|
+
avgComplexity: "Complexité moyenne",
|
|
49
|
+
dependencies: "Dépendances uniques",
|
|
50
|
+
topLangs: "🔤 Langages détectés",
|
|
51
|
+
criticalFiles: "⚠️ Fichiers critiques (haute complexité)",
|
|
52
|
+
navigation: "🧭 Navigation Rapide",
|
|
53
|
+
navDesc: "Pour aller plus loin, tu peux consulter les documents suivants :",
|
|
54
|
+
treeLink: "📂 Arborescence & Analyse",
|
|
55
|
+
treeDesc: "Pour comprendre la vocation de chaque fichier et les capacités du système.",
|
|
56
|
+
codeLink: "💻 Code Source",
|
|
57
|
+
codeDesc: "Pour retourner explorer la racine de ton projet.",
|
|
58
|
+
footer: "DocsToDev – Ton allié pour une documentation technique vivante et intelligente."
|
|
59
|
+
} : {
|
|
60
|
+
title: "📊 Project Overview – DocsToDev",
|
|
61
|
+
genOn: "Generated on",
|
|
62
|
+
status: "🚀 Project Status",
|
|
63
|
+
intro: "Hey! I've scanned your entire codebase. Here's a quick summary of the findings:",
|
|
64
|
+
volume: "Volume processed",
|
|
65
|
+
filesAnalyzed: "files successfully analyzed",
|
|
66
|
+
sourceFiles: "source files detected",
|
|
67
|
+
diagnosis: "Diagnosis",
|
|
68
|
+
structureClear: "The structure is clear and the analysis is complete. ✅",
|
|
69
|
+
metrics: "📈 Key Metrics",
|
|
70
|
+
complexity: "Total complexity",
|
|
71
|
+
avgComplexity: "Average complexity",
|
|
72
|
+
dependencies: "Unique dependencies",
|
|
73
|
+
topLangs: "🔤 Languages Detected",
|
|
74
|
+
criticalFiles: "⚠️ Critical Files (high complexity)",
|
|
75
|
+
navigation: "🧭 Quick Navigation",
|
|
76
|
+
navDesc: "To dive deeper, check out these documents:",
|
|
77
|
+
treeLink: "📂 Tree & Analysis",
|
|
78
|
+
treeDesc: "Explore file purposes and system capabilities.",
|
|
79
|
+
codeLink: "💻 Source Code",
|
|
80
|
+
codeDesc: "Head back to the project root.",
|
|
81
|
+
footer: "DocsToDev – Your partner for living and intelligent technical documentation."
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
let content = `# ${t.title}\n\n`;
|
|
85
|
+
content += `> 📅 **${t.genOn} :** ${dateStr}\n\n`;
|
|
86
|
+
|
|
87
|
+
content += `## ${t.status}\n`;
|
|
88
|
+
content += `${t.intro}\n`;
|
|
89
|
+
content += `- **${t.volume} :** ${summaryData.totalFiles} ${t.filesAnalyzed}.\n`;
|
|
90
|
+
|
|
91
|
+
if (summaryData.sourceFiles) {
|
|
92
|
+
content += `- **${t.sourceFiles} :** ${summaryData.sourceFiles} ${t.sourceFiles.toLowerCase()}.\n`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
content += `- **${t.diagnosis} :** ${t.structureClear}\n\n`;
|
|
96
|
+
|
|
97
|
+
// Métriques additionnelles si disponibles
|
|
98
|
+
if (summaryData.totalComplexity || summaryData.avgComplexity || summaryData.totalDeps) {
|
|
99
|
+
content += `## ${t.metrics}\n`;
|
|
100
|
+
|
|
101
|
+
if (summaryData.totalComplexity) {
|
|
102
|
+
content += `- **${t.complexity} :** ${summaryData.totalComplexity}\n`;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (summaryData.avgComplexity) {
|
|
106
|
+
content += `- **${t.avgComplexity} :** ${summaryData.avgComplexity}\n`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (summaryData.totalDeps) {
|
|
110
|
+
content += `- **${t.dependencies} :** ${summaryData.totalDeps}\n`;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
content += `\n`;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Langages détectés
|
|
117
|
+
if (summaryData.topLanguages && summaryData.topLanguages.length > 0) {
|
|
118
|
+
content += `## ${t.topLangs}\n`;
|
|
119
|
+
summaryData.topLanguages.forEach(({ lang, count }) => {
|
|
120
|
+
content += `- **${lang}** : ${count} ${lang === "fr" ? "fichiers" : "files"}\n`;
|
|
121
|
+
});
|
|
122
|
+
content += `\n`;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Fichiers critiques
|
|
126
|
+
if (summaryData.criticalFiles && summaryData.criticalFiles.length > 0) {
|
|
127
|
+
content += `## ${t.criticalFiles}\n`;
|
|
128
|
+
summaryData.criticalFiles.forEach(file => {
|
|
129
|
+
content += `- \`${file}\`\n`;
|
|
130
|
+
});
|
|
131
|
+
content += `\n`;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
content += `## ${t.navigation}\n`;
|
|
135
|
+
content += `${t.navDesc}\n`;
|
|
136
|
+
content += `- **[${t.treeLink}](../docs/docs-to-dev.md)** : ${t.treeDesc}\n`;
|
|
137
|
+
content += `- **[${t.codeLink}](../)** : ${t.codeDesc}\n\n`;
|
|
138
|
+
|
|
139
|
+
content += `---\n`;
|
|
140
|
+
content += `*${t.footer}*\n`;
|
|
50
141
|
|
|
51
142
|
const outputPath = path.join(docsDir, "summary.md");
|
|
52
143
|
writeFileSync(outputPath, content);
|
|
53
144
|
|
|
54
|
-
// Log de succès bilingue
|
|
55
145
|
const successMsg = lang === "fr"
|
|
56
146
|
? `📑 Résumé humain généré avec succès : ${outputPath}`
|
|
57
147
|
: `📑 Human-friendly summary successfully generated: ${outputPath}`;
|