tech-debt-visualizer 0.1.4 → 0.1.6
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/dist/reports/html.js +109 -118
- package/package.json +1 -1
package/dist/reports/html.js
CHANGED
|
@@ -41,189 +41,180 @@ function buildHtml(run, title, darkMode) {
|
|
|
41
41
|
<meta charset="UTF-8" />
|
|
42
42
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
43
43
|
<title>${escapeHtml(title)}</title>
|
|
44
|
+
<meta property="og:title" content="${escapeHtml(title)} — ${cleanliness.tier}/5 ${escapeHtml(cleanliness.label)}" />
|
|
45
|
+
<meta property="og:description" content="${escapeHtml(cleanliness.description)}" />
|
|
46
|
+
<meta property="og:type" content="website" />
|
|
47
|
+
<meta name="twitter:card" content="summary" />
|
|
48
|
+
<meta name="twitter:title" content="${escapeHtml(title)} — ${cleanliness.tier}/5" />
|
|
49
|
+
<meta name="twitter:description" content="${escapeHtml(cleanliness.label)}: ${escapeHtml(cleanliness.description)}" />
|
|
44
50
|
<style>
|
|
45
51
|
:root {
|
|
46
|
-
--bg: #
|
|
47
|
-
--surface: #1a1a1f;
|
|
48
|
-
--border: #2a2a32;
|
|
49
|
-
--text: #e4e4e7;
|
|
50
|
-
--text-muted: #71717a;
|
|
51
|
-
--accent: #6366f1;
|
|
52
|
-
--accent-dim: #4f46e5;
|
|
53
|
-
--green: #22c55e;
|
|
54
|
-
--yellow: #eab308;
|
|
55
|
-
--red: #ef4444;
|
|
56
|
-
--gradient: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #a855f7 100%);
|
|
57
|
-
}
|
|
58
|
-
[data-theme="light"] {
|
|
59
|
-
--bg: #fafafa;
|
|
52
|
+
--bg: #fff;
|
|
60
53
|
--surface: #fff;
|
|
61
|
-
--border: #
|
|
62
|
-
--text: #
|
|
63
|
-
--text-muted: #
|
|
54
|
+
--border: #ccc;
|
|
55
|
+
--text: #222;
|
|
56
|
+
--text-muted: #666;
|
|
57
|
+
--link: #0568c2;
|
|
58
|
+
}
|
|
59
|
+
[data-theme="dark"] {
|
|
60
|
+
--bg: #1a1a1a;
|
|
61
|
+
--surface: #252525;
|
|
62
|
+
--border: #404040;
|
|
63
|
+
--text: #e0e0e0;
|
|
64
|
+
--text-muted: #999;
|
|
65
|
+
--link: #6eb3f7;
|
|
64
66
|
}
|
|
65
67
|
* { box-sizing: border-box; }
|
|
66
68
|
body {
|
|
67
69
|
margin: 0;
|
|
68
|
-
font-family:
|
|
70
|
+
font-family: system-ui, sans-serif;
|
|
69
71
|
background: var(--bg);
|
|
70
72
|
color: var(--text);
|
|
71
73
|
min-height: 100vh;
|
|
72
|
-
|
|
74
|
+
font-size: 14px;
|
|
75
|
+
line-height: 1.5;
|
|
73
76
|
}
|
|
74
|
-
.container { max-width:
|
|
77
|
+
.container { max-width: 900px; margin: 0 auto; padding: 1.5rem 1.25rem; }
|
|
75
78
|
.no-llm-banner {
|
|
76
79
|
width: 100%;
|
|
77
80
|
background: var(--surface);
|
|
78
|
-
border-bottom:
|
|
79
|
-
padding: 0.
|
|
80
|
-
text-align: center;
|
|
81
|
-
}
|
|
82
|
-
.no-llm-banner .no-llm-cta { font-size: 1rem; font-weight: 600; color: var(--text); margin: 0; }
|
|
83
|
-
.hero-caption { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-muted); margin: 0 0 1rem; font-weight: 600; text-align: center; }
|
|
84
|
-
.hero {
|
|
81
|
+
border-bottom: 1px solid var(--border);
|
|
82
|
+
padding: 0.5rem 1rem;
|
|
85
83
|
text-align: center;
|
|
86
|
-
margin-bottom: 2rem;
|
|
87
84
|
}
|
|
85
|
+
.no-llm-banner .no-llm-cta { font-size: 14px; font-weight: normal; color: var(--text); margin: 0; }
|
|
86
|
+
.hero-caption { font-size: 12px; color: var(--text-muted); margin: 0 0 0.5rem; text-align: center; }
|
|
87
|
+
.hero { text-align: center; margin-bottom: 1.5rem; }
|
|
88
88
|
.score-badge {
|
|
89
|
-
display: inline-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
display: inline-flex;
|
|
90
|
+
flex-direction: column;
|
|
91
|
+
align-items: center;
|
|
92
|
+
justify-content: center;
|
|
93
|
+
width: 110px;
|
|
94
|
+
height: 120px;
|
|
95
|
+
margin-bottom: 0.5rem;
|
|
92
96
|
background: var(--tier-bg);
|
|
93
|
-
color: var(--tier-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
margin-bottom: 0.75rem;
|
|
97
|
+
color: var(--tier-num);
|
|
98
|
+
clip-path: polygon(50% 0%, 100% 18%, 100% 82%, 50% 100%, 0% 82%, 0% 18%);
|
|
99
|
+
-webkit-clip-path: polygon(50% 0%, 100% 18%, 100% 82%, 50% 100%, 0% 82%, 0% 18%);
|
|
97
100
|
}
|
|
98
|
-
.score-badge .num { display: block; font-size:
|
|
99
|
-
.score-badge .of { display: block; font-size:
|
|
100
|
-
.hero .score-label { font-size: 1.
|
|
101
|
-
.hero .score-desc { font-size:
|
|
102
|
-
.hero .report-meta { font-size:
|
|
103
|
-
.hero.tier-1 { --tier-bg: #
|
|
104
|
-
.hero.tier-2 { --tier-bg: #
|
|
105
|
-
.hero.tier-3 { --tier-bg: #
|
|
106
|
-
.hero.tier-4 { --tier-bg: #
|
|
107
|
-
.hero.tier-5 { --tier-bg: #
|
|
108
|
-
[data-theme="light"] .hero.tier-1 { --tier-bg: #fef2f2; --tier-fg: #dc2626; }
|
|
109
|
-
[data-theme="light"] .hero.tier-2 { --tier-bg: #fff7ed; --tier-fg: #ea580c; }
|
|
110
|
-
[data-theme="light"] .hero.tier-3 { --tier-bg: #fefce8; --tier-fg: #ca8a04; }
|
|
111
|
-
[data-theme="light"] .hero.tier-4 { --tier-bg: #f0f9ff; --tier-fg: #0284c7; }
|
|
112
|
-
[data-theme="light"] .hero.tier-5 { --tier-bg: #f0fdf4; --tier-fg: #16a34a; }
|
|
101
|
+
.score-badge .num { display: block; font-size: 2.75rem; font-weight: 900; line-height: 1; text-align: center; }
|
|
102
|
+
.score-badge .of { display: block; font-size: 12px; font-weight: bold; text-align: center; margin-top: 0.15rem; color: var(--tier-num); opacity: 0.95; }
|
|
103
|
+
.hero .score-label { font-size: 1.1rem; font-weight: bold; color: var(--text); margin: 0 0 0.2rem; }
|
|
104
|
+
.hero .score-desc { font-size: 13px; color: var(--text-muted); margin: 0 0 0.35rem; max-width: 360px; margin-left: auto; margin-right: auto; }
|
|
105
|
+
.hero .report-meta { font-size: 12px; color: var(--text-muted); }
|
|
106
|
+
.hero.tier-1 { --tier-bg: #c00; --tier-num: #fff; }
|
|
107
|
+
.hero.tier-2 { --tier-bg: #e85d00; --tier-num: #fff; }
|
|
108
|
+
.hero.tier-3 { --tier-bg: #b8860b; --tier-num: #fff; }
|
|
109
|
+
.hero.tier-4 { --tier-bg: #069; --tier-num: #fff; }
|
|
110
|
+
.hero.tier-5 { --tier-bg: #0a6b0a; --tier-num: #fff; }
|
|
113
111
|
.summary-cards {
|
|
114
112
|
display: grid;
|
|
115
113
|
grid-template-columns: repeat(4, 1fr);
|
|
116
|
-
gap:
|
|
117
|
-
margin-bottom:
|
|
114
|
+
gap: 0.75rem;
|
|
115
|
+
margin-bottom: 1.5rem;
|
|
118
116
|
}
|
|
119
117
|
@media (max-width: 640px) { .summary-cards { grid-template-columns: repeat(2, 1fr); } }
|
|
120
118
|
.card {
|
|
121
119
|
background: var(--surface);
|
|
122
120
|
border: 1px solid var(--border);
|
|
123
|
-
|
|
124
|
-
padding: 1.25rem 1.35rem;
|
|
125
|
-
transition: border-color 0.2s;
|
|
121
|
+
padding: 0.75rem 1rem;
|
|
126
122
|
}
|
|
127
|
-
.card
|
|
128
|
-
.card .
|
|
129
|
-
.card .label { font-size: 0.72rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.06em; margin-top: 0.2rem; }
|
|
123
|
+
.card .value { font-size: 1.35rem; font-weight: bold; color: var(--text); }
|
|
124
|
+
.card .label { font-size: 12px; color: var(--text-muted); margin-top: 0.15rem; }
|
|
130
125
|
.section {
|
|
131
126
|
background: var(--surface);
|
|
132
127
|
border: 1px solid var(--border);
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
margin-bottom: 1.5rem;
|
|
128
|
+
padding: 1rem 1.25rem;
|
|
129
|
+
margin-bottom: 1rem;
|
|
136
130
|
}
|
|
137
|
-
.section h2 { font-size:
|
|
131
|
+
.section h2 { font-size: 1rem; margin: 0 0 0.75rem; color: var(--text); font-weight: bold; }
|
|
138
132
|
#treemap {
|
|
139
133
|
display: flex;
|
|
140
134
|
flex-wrap: wrap;
|
|
141
|
-
gap:
|
|
142
|
-
min-height:
|
|
143
|
-
padding: 0.
|
|
135
|
+
gap: 4px;
|
|
136
|
+
min-height: 160px;
|
|
137
|
+
padding: 0.25rem 0;
|
|
144
138
|
}
|
|
145
139
|
.treemap-cell {
|
|
146
|
-
border-radius: 8px;
|
|
147
140
|
display: flex;
|
|
148
141
|
align-items: flex-end;
|
|
149
|
-
min-width:
|
|
150
|
-
padding: 8px
|
|
151
|
-
font-size:
|
|
142
|
+
min-width: 64px;
|
|
143
|
+
padding: 6px 8px;
|
|
144
|
+
font-size: 11px;
|
|
152
145
|
cursor: pointer;
|
|
153
|
-
transition: transform 0.15s, filter 0.15s, box-shadow 0.15s;
|
|
154
146
|
overflow: hidden;
|
|
155
147
|
text-overflow: ellipsis;
|
|
156
148
|
white-space: nowrap;
|
|
149
|
+
border: 1px solid rgba(0,0,0,0.1);
|
|
157
150
|
}
|
|
158
|
-
.treemap-cell:hover {
|
|
159
|
-
.treemap-cell[data-severity="critical"] { background:
|
|
160
|
-
.treemap-cell[data-severity="high"] { background:
|
|
161
|
-
.treemap-cell[data-severity="medium"] { background:
|
|
162
|
-
.treemap-cell[data-severity="low"] { background:
|
|
163
|
-
.treemap-cell[data-severity="none"] { background: var(--border); color: var(--text-muted); }
|
|
151
|
+
.treemap-cell:hover { outline: 2px solid var(--text); outline-offset: 1px; }
|
|
152
|
+
.treemap-cell[data-severity="critical"] { background: #c00; color: #fff; border-color: #900; }
|
|
153
|
+
.treemap-cell[data-severity="high"] { background: #e85d00; color: #fff; border-color: #b84a00; }
|
|
154
|
+
.treemap-cell[data-severity="medium"] { background: #b8860b; color: #fff; border-color: #8b6914; }
|
|
155
|
+
.treemap-cell[data-severity="low"] { background: #0a6b0a; color: #fff; border-color: #064906; }
|
|
156
|
+
.treemap-cell[data-severity="none"] { background: var(--border); color: var(--text-muted); border-color: var(--border); }
|
|
164
157
|
.debt-list { list-style: none; padding: 0; margin: 0; }
|
|
165
158
|
.debt-list li {
|
|
166
159
|
border-bottom: 1px solid var(--border);
|
|
167
|
-
padding: 0.
|
|
160
|
+
padding: 0.6rem 0;
|
|
168
161
|
cursor: pointer;
|
|
169
|
-
transition: background 0.15s;
|
|
170
162
|
}
|
|
171
163
|
.debt-list li:last-child { border-bottom: none; }
|
|
172
|
-
.debt-list li:hover { background:
|
|
173
|
-
.debt-list .title { font-weight:
|
|
174
|
-
.debt-list .meta { font-size:
|
|
175
|
-
.debt-list .insight { font-size:
|
|
176
|
-
.badge { display: inline-block; padding: 0.
|
|
177
|
-
.badge-critical { background: #
|
|
178
|
-
.badge-high { background: #
|
|
179
|
-
.badge-medium { background: #
|
|
180
|
-
.badge-low { background: #
|
|
164
|
+
.debt-list li:hover { background: var(--bg); }
|
|
165
|
+
.debt-list .title { font-weight: bold; margin-bottom: 0.2rem; }
|
|
166
|
+
.debt-list .meta { font-size: 12px; color: var(--text-muted); }
|
|
167
|
+
.debt-list .insight { font-size: 13px; color: var(--text-muted); margin-top: 0.25rem; line-height: 1.4; }
|
|
168
|
+
.badge { display: inline-block; padding: 0.15em 0.4em; font-size: 11px; font-weight: bold; }
|
|
169
|
+
.badge-critical { background: #c00; color: #fff; }
|
|
170
|
+
.badge-high { background: #e85d00; color: #fff; }
|
|
171
|
+
.badge-medium { background: #b8860b; color: #fff; }
|
|
172
|
+
.badge-low { background: #0a6b0a; color: #fff; }
|
|
181
173
|
#detail {
|
|
182
174
|
position: fixed;
|
|
183
175
|
inset: 0;
|
|
184
|
-
background: rgba(0,0,0,0.
|
|
176
|
+
background: rgba(0,0,0,0.5);
|
|
185
177
|
display: none;
|
|
186
178
|
align-items: center;
|
|
187
179
|
justify-content: center;
|
|
188
180
|
z-index: 100;
|
|
189
|
-
padding:
|
|
181
|
+
padding: 1rem;
|
|
190
182
|
}
|
|
191
183
|
#detail.show { display: flex; }
|
|
192
184
|
#detail .panel {
|
|
193
185
|
background: var(--surface);
|
|
194
186
|
border: 1px solid var(--border);
|
|
195
|
-
|
|
196
|
-
max-width: 520px;
|
|
187
|
+
max-width: 480px;
|
|
197
188
|
width: 100%;
|
|
198
189
|
max-height: 85vh;
|
|
199
190
|
overflow: auto;
|
|
200
|
-
padding: 1.
|
|
191
|
+
padding: 1.25rem;
|
|
201
192
|
}
|
|
202
|
-
#detail .panel h3 { margin: 0 0 0.
|
|
203
|
-
#detail .panel .file { font-family: monospace; font-size:
|
|
204
|
-
#detail .panel .explanation { margin-top:
|
|
205
|
-
#detail .panel .close-hint { margin-top:
|
|
206
|
-
#detail .panel .file-assessment { margin-top:
|
|
207
|
-
#detail .panel .file-assessment strong { color: var(--text); font-size:
|
|
208
|
-
#detail .panel .suggested-code { margin-top:
|
|
193
|
+
#detail .panel h3 { margin: 0 0 0.35rem; font-size: 1rem; }
|
|
194
|
+
#detail .panel .file { font-family: ui-monospace, monospace; font-size: 13px; color: var(--link); }
|
|
195
|
+
#detail .panel .explanation { margin-top: 0.75rem; line-height: 1.5; color: var(--text-muted); font-size: 13px; }
|
|
196
|
+
#detail .panel .close-hint { margin-top: 0.75rem; font-size: 12px; color: var(--text-muted); }
|
|
197
|
+
#detail .panel .file-assessment { margin-top: 0.75rem; padding-top: 0.75rem; border-top: 1px solid var(--border); font-size: 13px; color: var(--text-muted); line-height: 1.5; }
|
|
198
|
+
#detail .panel .file-assessment strong { color: var(--text); font-size: 12px; }
|
|
199
|
+
#detail .panel .suggested-code { margin-top: 0.75rem; padding: 0.5rem; background: var(--bg); border: 1px solid var(--border); font-size: 12px; overflow-x: auto; }
|
|
209
200
|
#detail .panel .suggested-code pre { margin: 0; white-space: pre-wrap; }
|
|
210
|
-
.llm-overall { border-left:
|
|
211
|
-
.llm-overall h2 { color: var(--
|
|
212
|
-
.llm-overall .llm-overall-text { margin: 0; color: var(--text); line-height: 1.
|
|
213
|
-
.llm-next-steps h2 { color: var(--
|
|
214
|
-
.llm-next-steps ul { margin: 0; padding-left: 1.25rem; color: var(--text); line-height: 1.
|
|
215
|
-
.priority-matrix { display: grid; grid-template-columns: 1fr 1fr; gap:
|
|
216
|
-
.priority-matrix .quadrant { padding:
|
|
217
|
-
.priority-matrix .quadrant h4 { margin: 0 0 0.
|
|
218
|
-
.priority-matrix .quadrant p { margin: 0; font-size:
|
|
219
|
-
.section-desc { font-size:
|
|
220
|
-
.legend { display: flex; flex-wrap: wrap; gap:
|
|
221
|
-
.legend span { display: inline-flex; align-items: center; gap: 0.
|
|
222
|
-
.legend .swatch { width:
|
|
223
|
-
.legend .swatch-crit { background:
|
|
224
|
-
.legend .swatch-high { background:
|
|
225
|
-
.legend .swatch-med { background:
|
|
226
|
-
.legend .swatch-low { background:
|
|
201
|
+
.llm-overall { border-left: 3px solid var(--link); padding-left: 0.5rem; margin-left: -0.5rem; }
|
|
202
|
+
.llm-overall h2 { color: var(--text); font-size: 1rem; }
|
|
203
|
+
.llm-overall .llm-overall-text { margin: 0; color: var(--text); line-height: 1.5; font-size: 14px; }
|
|
204
|
+
.llm-next-steps h2 { color: var(--text); font-size: 1rem; }
|
|
205
|
+
.llm-next-steps ul { margin: 0; padding-left: 1.25rem; color: var(--text); line-height: 1.5; }
|
|
206
|
+
.priority-matrix { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; margin-top: 0.75rem; }
|
|
207
|
+
.priority-matrix .quadrant { padding: 0.75rem; border: 1px solid var(--border); }
|
|
208
|
+
.priority-matrix .quadrant h4 { margin: 0 0 0.35rem; font-size: 0.9rem; font-weight: bold; }
|
|
209
|
+
.priority-matrix .quadrant p { margin: 0; font-size: 13px; color: var(--text-muted); }
|
|
210
|
+
.section-desc { font-size: 13px; color: var(--text-muted); margin: -0.35rem 0 0.75rem; line-height: 1.4; }
|
|
211
|
+
.legend { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; margin-bottom: 0.75rem; font-size: 12px; color: var(--text-muted); }
|
|
212
|
+
.legend span { display: inline-flex; align-items: center; gap: 0.25rem; }
|
|
213
|
+
.legend .swatch { width: 10px; height: 10px; }
|
|
214
|
+
.legend .swatch-crit { background: #c00; }
|
|
215
|
+
.legend .swatch-high { background: #e85d00; }
|
|
216
|
+
.legend .swatch-med { background: #b8860b; }
|
|
217
|
+
.legend .swatch-low { background: #0a6b0a; }
|
|
227
218
|
.legend .swatch-none { background: var(--border); }
|
|
228
219
|
</style>
|
|
229
220
|
</head>
|
|
@@ -346,7 +337,7 @@ function buildHtml(run, title, darkMode) {
|
|
|
346
337
|
const sev = { critical: 4, high: 3, medium: 2, low: 1 };
|
|
347
338
|
DATA.debtItems.sort((a,b) => (sev[b.severity] || 0) - (sev[a.severity] || 0)).forEach(d => {
|
|
348
339
|
const li = document.createElement('li');
|
|
349
|
-
li.innerHTML = '<span class="title">' + escapeHtml(d.title) + '</span> <span class="badge badge-' + d.severity + '">' + d.severity + '</span>' + (d.suggestedCode ? ' <span class="badge" style="background:var(--
|
|
340
|
+
li.innerHTML = '<span class="title">' + escapeHtml(d.title) + '</span> <span class="badge badge-' + d.severity + '">' + d.severity + '</span>' + (d.suggestedCode ? ' <span class="badge" style="background:var(--link);color:#fff">refactor</span>' : '') + '<br><span class="meta">' + escapeHtml(d.file) + (d.line ? ':' + d.line : '') + '</span>' + (d.insight ? '<div class="insight">' + escapeHtml(d.insight) + '</div>' : '');
|
|
350
341
|
li.addEventListener('click', () => showDetail(d.file, [d]));
|
|
351
342
|
list.appendChild(li);
|
|
352
343
|
});
|
|
@@ -370,7 +361,7 @@ function buildHtml(run, title, darkMode) {
|
|
|
370
361
|
if (fileMetric && (fileMetric.llmAssessment || fileMetric.llmSuggestedCode)) {
|
|
371
362
|
fileAssessEl.style.display = 'block';
|
|
372
363
|
let html = '<strong>LLM file assessment</strong><br>' + (fileMetric.llmAssessment ? escapeHtml(fileMetric.llmAssessment) : '');
|
|
373
|
-
if (fileMetric.llmSuggestedCode) html += '<br><br><strong>Suggested refactor</strong><pre style="margin:0.5rem 0 0;padding:0.5rem;background:var(--bg);border
|
|
364
|
+
if (fileMetric.llmSuggestedCode) html += '<br><br><strong>Suggested refactor</strong><pre style="margin:0.5rem 0 0;padding:0.5rem;background:var(--bg);border:1px solid var(--border);font-size:12px;overflow-x:auto">' + escapeHtml(fileMetric.llmSuggestedCode) + '</pre>';
|
|
374
365
|
fileAssessEl.innerHTML = html;
|
|
375
366
|
} else {
|
|
376
367
|
fileAssessEl.style.display = 'none';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tech-debt-visualizer",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Language-agnostic CLI that analyzes repos and generates interactive technical debt visualizations with AI-powered insights",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|