tech-debt-visualizer 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.
@@ -0,0 +1,19 @@
1
+ export function generateJsonReport(run) {
2
+ const payload = {
3
+ repoPath: run.repoPath,
4
+ startedAt: run.startedAt,
5
+ completedAt: run.completedAt,
6
+ analyzers: run.analyzers,
7
+ summary: {
8
+ filesAnalyzed: run.fileMetrics.length,
9
+ debtItemsCount: run.debtItems.length,
10
+ errorsCount: run.errors.length,
11
+ },
12
+ fileMetrics: run.fileMetrics,
13
+ debtItems: run.debtItems,
14
+ debtTrend: run.debtTrend,
15
+ errors: run.errors,
16
+ llmOverallAssessment: run.llmOverallAssessment ?? undefined,
17
+ };
18
+ return JSON.stringify(payload, null, 2);
19
+ }
@@ -0,0 +1,2 @@
1
+ import type { AnalysisRun } from "../types.js";
2
+ export declare function generateMarkdownReport(run: AnalysisRun): string;
@@ -0,0 +1,64 @@
1
+ export function generateMarkdownReport(run) {
2
+ const lines = [];
3
+ lines.push("# Technical Debt Report");
4
+ lines.push("");
5
+ lines.push(`**Repository:** \`${run.repoPath}\``);
6
+ lines.push(`**Generated:** ${run.completedAt ?? run.startedAt}`);
7
+ lines.push("");
8
+ lines.push("## Summary");
9
+ lines.push("");
10
+ lines.push(`| Metric | Value |`);
11
+ lines.push(`|--------|-------|`);
12
+ lines.push(`| Files analyzed | ${run.fileMetrics.length} |`);
13
+ lines.push(`| Debt items | ${run.debtItems.length} |`);
14
+ lines.push(`| Parse errors | ${run.errors.length} |`);
15
+ lines.push("");
16
+ const bySeverity = { critical: 0, high: 0, medium: 0, low: 0 };
17
+ for (const d of run.debtItems) {
18
+ bySeverity[d.severity]++;
19
+ }
20
+ lines.push("## By severity");
21
+ lines.push("");
22
+ lines.push(`- **Critical:** ${bySeverity.critical}`);
23
+ lines.push(`- **High:** ${bySeverity.high}`);
24
+ lines.push(`- **Medium:** ${bySeverity.medium}`);
25
+ lines.push(`- **Low:** ${bySeverity.low}`);
26
+ lines.push("");
27
+ const hotspots = run.fileMetrics
28
+ .filter((m) => (m.hotspotScore ?? 0) > 0.2)
29
+ .sort((a, b) => (b.hotspotScore ?? 0) - (a.hotspotScore ?? 0))
30
+ .slice(0, 15);
31
+ if (hotspots.length > 0) {
32
+ lines.push("## Hotspot files");
33
+ lines.push("");
34
+ lines.push("| File | Hotspot score | Complexity | Churn |");
35
+ lines.push("|------|---------------|------------|-------|");
36
+ for (const h of hotspots) {
37
+ lines.push(`| \`${h.file}\` | ${(h.hotspotScore ?? 0).toFixed(2)} | ${h.cyclomaticComplexity ?? "-"} | ${h.churn ?? "-"} |`);
38
+ }
39
+ lines.push("");
40
+ }
41
+ lines.push("## Debt items");
42
+ lines.push("");
43
+ const byCategory = new Map();
44
+ for (const d of run.debtItems) {
45
+ const list = byCategory.get(d.category) ?? [];
46
+ list.push(d);
47
+ byCategory.set(d.category, list);
48
+ }
49
+ const order = ["complexity", "hotspot", "documentation", "duplication", "architecture", "dependencies", "other"];
50
+ for (const cat of order) {
51
+ const items = byCategory.get(cat);
52
+ if (!items?.length)
53
+ continue;
54
+ lines.push(`### ${cat}`);
55
+ lines.push("");
56
+ for (const d of items.slice(0, 20)) {
57
+ lines.push(`- **${d.title}** (\`${d.file}${d.line ? `:${d.line}` : ""}\`) — ${d.severity}`);
58
+ if (d.insight)
59
+ lines.push(` - ${d.insight}`);
60
+ }
61
+ lines.push("");
62
+ }
63
+ return lines.join("\n");
64
+ }
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Core types for the Technical Debt Visualizer.
3
+ * Language-agnostic debt items, metrics, and analyzer contracts.
4
+ */
5
+ export type DebtCategory = "complexity" | "duplication" | "dependencies" | "test_coverage" | "documentation" | "architecture" | "hotspot" | "naming" | "other";
6
+ export type Severity = "low" | "medium" | "high" | "critical";
7
+ export interface DebtItem {
8
+ id: string;
9
+ file: string;
10
+ line?: number;
11
+ endLine?: number;
12
+ category: DebtCategory;
13
+ severity: Severity;
14
+ title: string;
15
+ description: string;
16
+ /** 0-1 confidence that this is real debt */
17
+ confidence: number;
18
+ /** LLM-generated explanation of why it matters and what to do */
19
+ insight?: string;
20
+ /** LLM-suggested simplified/refactored code snippet (when applicable) */
21
+ suggestedCode?: string;
22
+ /** Raw metrics that contributed (e.g. cyclomatic complexity value) */
23
+ metrics?: Record<string, number | string>;
24
+ /** Suggested fix or refactor (short text) */
25
+ recommendation?: string;
26
+ }
27
+ export interface FileMetrics {
28
+ file: string;
29
+ language: string;
30
+ /** Cyclomatic complexity (max or sum by scope) */
31
+ cyclomaticComplexity?: number;
32
+ /** Cognitive complexity style */
33
+ cognitiveComplexity?: number;
34
+ lineCount: number;
35
+ /** Approx. duplicate/similar blocks */
36
+ duplicateBlocks?: number;
37
+ /** Test coverage 0-1 if available */
38
+ coverage?: number;
39
+ /** Has docstring/JSDoc at module level */
40
+ hasDocumentation?: boolean;
41
+ /** Coupling / dependency count */
42
+ coupling?: number;
43
+ /** From git: number of commits touching this file in window */
44
+ changeCount?: number;
45
+ /** From git: lines changed in window */
46
+ churn?: number;
47
+ /** Computed: high churn + high complexity */
48
+ hotspotScore?: number;
49
+ /** LLM-generated short assessment of this file's cleanliness (when LLM attached) */
50
+ llmAssessment?: string;
51
+ /** LLM-suggested refactored code snippet for this file (when applicable) */
52
+ llmSuggestedCode?: string;
53
+ }
54
+ export interface GitBlameEntry {
55
+ file: string;
56
+ commits: number;
57
+ authors: number;
58
+ lastChange: string;
59
+ churn: number;
60
+ }
61
+ export interface AnalyzerResult {
62
+ language: string;
63
+ files: string[];
64
+ metrics: FileMetrics[];
65
+ debtItems: DebtItem[];
66
+ /** Errors during analysis (e.g. parse failures) */
67
+ errors: Array<{
68
+ file: string;
69
+ message: string;
70
+ }>;
71
+ }
72
+ export interface AnalysisRun {
73
+ repoPath: string;
74
+ startedAt: string;
75
+ completedAt?: string;
76
+ analyzers: string[];
77
+ fileMetrics: FileMetrics[];
78
+ debtItems: DebtItem[];
79
+ /** Time-series: debt score over recent commits (for trend) */
80
+ debtTrend?: Array<{
81
+ commit: string;
82
+ date: string;
83
+ score: number;
84
+ }>;
85
+ errors: Array<{
86
+ file: string;
87
+ message: string;
88
+ }>;
89
+ /** LLM-generated overall codebase cleanliness assessment (when LLM attached) */
90
+ llmOverallAssessment?: string;
91
+ }
92
+ /** Pluggable analyzer: given file paths and content, returns metrics + debt items */
93
+ export interface IAnalyzer {
94
+ readonly name: string;
95
+ readonly languages: string[];
96
+ /** Check if this analyzer can handle the given file path */
97
+ canAnalyze(filePath: string): boolean;
98
+ /** Analyze files; content keyed by path */
99
+ analyze(files: Map<string, string>, options?: {
100
+ repoPath?: string;
101
+ }): Promise<AnalyzerResult>;
102
+ }
103
+ export interface ReportOptions {
104
+ outputPath: string;
105
+ format: "html" | "json" | "markdown";
106
+ title?: string;
107
+ darkMode?: boolean;
108
+ }
109
+ export interface CliOptions {
110
+ path: string;
111
+ output?: string;
112
+ format?: "html" | "json" | "markdown" | "cli";
113
+ languages?: string[];
114
+ noLlm?: boolean;
115
+ ci?: boolean;
116
+ }
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Core types for the Technical Debt Visualizer.
3
+ * Language-agnostic debt items, metrics, and analyzer contracts.
4
+ */
5
+ export {};
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "tech-debt-visualizer",
3
+ "version": "0.1.0",
4
+ "description": "Language-agnostic CLI that analyzes repos and generates interactive technical debt visualizations with AI-powered insights",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "tech-debt": "dist/cli.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "start": "node dist/cli.js",
13
+ "analyze": "node dist/cli.js analyze",
14
+ "dev": "tsx src/cli.ts",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "keywords": [
18
+ "technical-debt",
19
+ "code-quality",
20
+ "static-analysis",
21
+ "visualization"
22
+ ],
23
+ "author": "",
24
+ "license": "GPL-3.0-only",
25
+ "engines": {
26
+ "node": ">=18"
27
+ },
28
+ "files": [
29
+ "dist",
30
+ "README.md"
31
+ ],
32
+ "dependencies": {
33
+ "chalk": "^5.3.0",
34
+ "cli-progress": "^3.12.0",
35
+ "commander": "^12.1.0",
36
+ "simple-git": "^3.27.0",
37
+ "tree-sitter": "^0.21.1",
38
+ "tree-sitter-javascript": "^0.21.0",
39
+ "tree-sitter-typescript": "^0.21.0",
40
+ "tree-sitter-python": "^0.21.0"
41
+ },
42
+ "devDependencies": {
43
+ "@types/node": "^22.10.0",
44
+ "tsx": "^4.19.2",
45
+ "typescript": "^5.7.2"
46
+ }
47
+ }