diffintel 0.1.3 → 0.2.1
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/commands/explain.js +9 -5
- package/dist/commands/explain.js.map +1 -1
- package/dist/explain/html-report.js +201 -77
- package/dist/explain/html-report.js.map +1 -1
- package/dist/explain/llm-explain.js +43 -18
- package/dist/explain/llm-explain.js.map +1 -1
- package/dist/explain/types.d.ts +10 -0
- package/package.json +1 -1
package/dist/commands/explain.js
CHANGED
|
@@ -49,11 +49,15 @@ async function run(opts) {
|
|
|
49
49
|
};
|
|
50
50
|
const html = (0, html_report_1.renderReport)(report);
|
|
51
51
|
fs_1.default.writeFileSync(outFile, html, "utf-8");
|
|
52
|
-
console.error(`\
|
|
53
|
-
console.error(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
console.error(`\n${explanation.title}`);
|
|
53
|
+
console.error(`${fileDiffs.length} files | +${totalAdditions} -${totalDeletions}`);
|
|
54
|
+
if (explanation.fixes.length > 0) {
|
|
55
|
+
console.error(`Fixes: ${explanation.fixes.map((f) => f.description).join("; ")}`);
|
|
56
|
+
}
|
|
57
|
+
if (explanation.risks.length > 0) {
|
|
58
|
+
console.error(`Risks: ${explanation.risks.map((r) => `[${r.level}] ${r.description}`).join("; ")}`);
|
|
59
|
+
}
|
|
60
|
+
console.error(`\nReport: ${outFile}`);
|
|
57
61
|
return 0;
|
|
58
62
|
}
|
|
59
63
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explain.js","sourceRoot":"","sources":["../../src/commands/explain.ts"],"names":[],"mappings":";;;;;AAaA,
|
|
1
|
+
{"version":3,"file":"explain.js","sourceRoot":"","sources":["../../src/commands/explain.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,108 +8,232 @@ function escapeHtml(str) {
|
|
|
8
8
|
.replace(/>/g, ">")
|
|
9
9
|
.replace(/"/g, """);
|
|
10
10
|
}
|
|
11
|
-
const STATUS_ICON = {
|
|
12
|
-
added: "+", // +
|
|
13
|
-
modified: "✎", // pencil
|
|
14
|
-
deleted: "✕", // x
|
|
15
|
-
renamed: "→", // arrow
|
|
16
|
-
};
|
|
17
|
-
const ACTION_BADGE = {
|
|
18
|
-
added: { label: "added", color: "#22c55e" },
|
|
19
|
-
removed: { label: "removed", color: "#ef4444" },
|
|
20
|
-
modified: { label: "modified", color: "#f59e0b" },
|
|
21
|
-
};
|
|
22
|
-
const RISK_COLORS = {
|
|
23
|
-
low: { bg: "#dcfce7", text: "#166534" },
|
|
24
|
-
medium: { bg: "#fef3c7", text: "#92400e" },
|
|
25
|
-
high: { bg: "#fee2e2", text: "#991b1b" },
|
|
26
|
-
};
|
|
27
11
|
function renderReport(report) {
|
|
28
12
|
const { explanation, summary, files } = report;
|
|
29
|
-
|
|
13
|
+
// --- Fixes section ---
|
|
14
|
+
const fixesHtml = explanation.fixes.length > 0
|
|
15
|
+
? explanation.fixes.map((f) => `<div class="fix-item"><span class="fix-icon">✓</span> ${escapeHtml(f.description)}</div>`).join("\n")
|
|
16
|
+
: "";
|
|
17
|
+
// --- Risks section ---
|
|
18
|
+
const risksHtml = explanation.risks.length > 0
|
|
30
19
|
? explanation.risks.map((r) => {
|
|
31
|
-
const
|
|
32
|
-
return `<
|
|
20
|
+
const cls = `risk-${r.level}`;
|
|
21
|
+
return `<div class="risk-item ${cls}"><span class="risk-label">${r.level}</span> ${escapeHtml(r.description)}</div>`;
|
|
33
22
|
}).join("\n")
|
|
34
|
-
:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
? `<pre style="background:#1e1e1e;color:#d4d4d4;padding:12px;border-radius:6px;overflow-x:auto;font-size:12px;line-height:1.5;margin:8px 0;">${colorDiff(f.rawDiff)}</pre>`
|
|
57
|
-
: "<p style=\"color:#888;\">No diff available</p>";
|
|
58
|
-
return `<details style="margin-bottom:12px;border:1px solid #e5e7eb;border-radius:8px;padding:0;">
|
|
59
|
-
<summary style="padding:10px 14px;cursor:pointer;font-family:monospace;font-size:14px;background:#f9fafb;border-radius:8px;">${STATUS_ICON[f.status] || ""} ${escapeHtml(f.path)} <span style="color:#888;">(${f.structuralChanges.length} changes)</span></summary>
|
|
60
|
-
<div style="padding:10px 14px;">
|
|
61
|
-
${changesList}
|
|
62
|
-
${diffBlock}
|
|
23
|
+
: "";
|
|
24
|
+
// --- Per-file detail cards ---
|
|
25
|
+
// Build a map for both summary and notes
|
|
26
|
+
const fileExplanationData = new Map(explanation.fileExplanations.map((fe) => [fe.path, fe]));
|
|
27
|
+
const fileCards = files.map((f) => {
|
|
28
|
+
const feData = fileExplanationData.get(f.path);
|
|
29
|
+
const changesHtml = f.structuralChanges.length > 0
|
|
30
|
+
? `<div class="changes-list">${f.structuralChanges.map((c) => {
|
|
31
|
+
const cls = `action-${c.action}`;
|
|
32
|
+
return `<span class="change-badge ${cls}">${c.action}</span> <code>${escapeHtml(c.name)}</code> <span class="change-type">${c.type}</span>`;
|
|
33
|
+
}).join('<br>')}</div>`
|
|
34
|
+
: "";
|
|
35
|
+
const notesHtml = feData?.notes && feData.notes.length > 0
|
|
36
|
+
? `<div class="file-notes"><div class="file-notes-label">Things to note</div><ul>${feData.notes.map((n) => `<li>${escapeHtml(n)}</li>`).join("")}</ul></div>`
|
|
37
|
+
: "";
|
|
38
|
+
const diffHtml = f.rawDiff
|
|
39
|
+
? `<details class="diff-toggle"><summary>View diff</summary><pre class="diff-block">${colorDiff(f.rawDiff)}</pre></details>`
|
|
40
|
+
: "";
|
|
41
|
+
return `<div class="file-card">
|
|
42
|
+
<div class="file-header">
|
|
43
|
+
<span class="file-status status-${f.status}">${f.status}</span>
|
|
44
|
+
<span class="file-path">${escapeHtml(f.path)}</span>
|
|
63
45
|
</div>
|
|
64
|
-
|
|
46
|
+
${feData?.summary ? `<p class="file-summary">${escapeHtml(feData.summary)}</p>` : ""}
|
|
47
|
+
${notesHtml}
|
|
48
|
+
${changesHtml}
|
|
49
|
+
${diffHtml}
|
|
50
|
+
</div>`;
|
|
65
51
|
}).join("\n");
|
|
52
|
+
// --- Assemble the full report ---
|
|
66
53
|
return `<!DOCTYPE html>
|
|
67
54
|
<html lang="en">
|
|
68
55
|
<head>
|
|
69
56
|
<meta charset="utf-8">
|
|
70
57
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
71
58
|
<title>${escapeHtml(explanation.title)}</title>
|
|
59
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
60
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
61
|
+
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@700;800&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
|
|
72
62
|
<style>
|
|
73
63
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
74
|
-
body {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
.
|
|
82
|
-
|
|
83
|
-
|
|
64
|
+
body {
|
|
65
|
+
font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
66
|
+
max-width: 740px; margin: 0 auto; padding: 48px 20px;
|
|
67
|
+
color: #1a1a1a; background: #fff; line-height: 1.7;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* Article header */
|
|
71
|
+
.article-header {
|
|
72
|
+
margin-bottom: 36px;
|
|
73
|
+
padding-bottom: 28px;
|
|
74
|
+
border-bottom: 1px solid #eee;
|
|
75
|
+
}
|
|
76
|
+
.article-header .label {
|
|
77
|
+
display: inline-block; font-size: 11px; font-weight: 600;
|
|
78
|
+
text-transform: uppercase; letter-spacing: 1.5px; color: #3b82f6;
|
|
79
|
+
margin-bottom: 12px;
|
|
80
|
+
}
|
|
81
|
+
h1 {
|
|
82
|
+
font-family: "Playfair Display", Georgia, "Times New Roman", serif;
|
|
83
|
+
font-size: 34px; font-weight: 800; line-height: 1.2;
|
|
84
|
+
margin-bottom: 16px; letter-spacing: -0.5px; color: #111;
|
|
85
|
+
}
|
|
86
|
+
.meta { color: #999; font-size: 13px; font-weight: 400; }
|
|
87
|
+
.meta span { margin-right: 16px; }
|
|
88
|
+
|
|
89
|
+
/* Stats */
|
|
90
|
+
.stats {
|
|
91
|
+
display: flex; gap: 20px; margin-bottom: 32px;
|
|
92
|
+
}
|
|
93
|
+
.stat {
|
|
94
|
+
font-size: 13px; color: #777; font-weight: 500;
|
|
95
|
+
}
|
|
96
|
+
.stat b { font-size: 18px; color: #1a1a1a; margin-right: 3px; }
|
|
97
|
+
.stat.additions b { color: #16a34a; }
|
|
98
|
+
.stat.deletions b { color: #dc2626; }
|
|
99
|
+
|
|
100
|
+
/* Description — article lede */
|
|
101
|
+
.description {
|
|
102
|
+
font-size: 18px; line-height: 1.85; margin-bottom: 36px;
|
|
103
|
+
color: #333; font-weight: 400;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/* Section headings */
|
|
107
|
+
h2 {
|
|
108
|
+
font-size: 12px; font-weight: 600; text-transform: uppercase;
|
|
109
|
+
letter-spacing: 1.2px; color: #999; margin: 36px 0 14px;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/* Fixes */
|
|
113
|
+
.fix-item {
|
|
114
|
+
padding: 10px 14px; margin-bottom: 8px;
|
|
115
|
+
background: #f0fdf4; border-left: 3px solid #22c55e;
|
|
116
|
+
border-radius: 0 6px 6px 0; font-size: 14px; color: #15803d;
|
|
117
|
+
}
|
|
118
|
+
.fix-icon { margin-right: 6px; font-weight: bold; }
|
|
119
|
+
|
|
120
|
+
/* Risks */
|
|
121
|
+
.risk-item {
|
|
122
|
+
padding: 10px 14px; margin-bottom: 8px;
|
|
123
|
+
border-radius: 0 6px 6px 0; font-size: 14px;
|
|
124
|
+
}
|
|
125
|
+
.risk-label {
|
|
126
|
+
display: inline-block; padding: 1px 8px; border-radius: 3px;
|
|
127
|
+
font-size: 11px; font-weight: 600; text-transform: uppercase;
|
|
128
|
+
margin-right: 8px; color: white;
|
|
129
|
+
}
|
|
130
|
+
.risk-low { background: #fefce8; border-left: 3px solid #eab308; color: #854d0e; }
|
|
131
|
+
.risk-low .risk-label { background: #eab308; }
|
|
132
|
+
.risk-medium { background: #fff7ed; border-left: 3px solid #f97316; color: #9a3412; }
|
|
133
|
+
.risk-medium .risk-label { background: #f97316; }
|
|
134
|
+
.risk-high { background: #fef2f2; border-left: 3px solid #ef4444; color: #991b1b; }
|
|
135
|
+
.risk-high .risk-label { background: #ef4444; }
|
|
136
|
+
|
|
137
|
+
/* File cards */
|
|
138
|
+
.file-card {
|
|
139
|
+
border: 1px solid #e5e7eb; border-radius: 8px;
|
|
140
|
+
margin-bottom: 16px; overflow: hidden;
|
|
141
|
+
}
|
|
142
|
+
.file-header {
|
|
143
|
+
padding: 10px 14px; background: #fafafa;
|
|
144
|
+
border-bottom: 1px solid #f0f0f0;
|
|
145
|
+
display: flex; align-items: center; gap: 10px;
|
|
146
|
+
}
|
|
147
|
+
.file-path { font-family: "SF Mono", Menlo, monospace; font-size: 13px; }
|
|
148
|
+
.file-status {
|
|
149
|
+
display: inline-block; padding: 2px 8px; border-radius: 4px;
|
|
150
|
+
font-size: 11px; font-weight: 600; text-transform: uppercase; color: white;
|
|
151
|
+
}
|
|
152
|
+
.status-added { background: #22c55e; }
|
|
153
|
+
.status-modified { background: #3b82f6; }
|
|
154
|
+
.status-deleted { background: #ef4444; }
|
|
155
|
+
.status-renamed { background: #8b5cf6; }
|
|
156
|
+
|
|
157
|
+
.file-summary {
|
|
158
|
+
padding: 12px 14px; font-size: 14px; color: #444;
|
|
159
|
+
border-bottom: 1px solid #f5f5f5;
|
|
160
|
+
}
|
|
161
|
+
.file-notes {
|
|
162
|
+
padding: 10px 14px; background: #fafbff;
|
|
163
|
+
border-bottom: 1px solid #f0f0f0;
|
|
164
|
+
}
|
|
165
|
+
.file-notes-label {
|
|
166
|
+
font-size: 11px; font-weight: 600; text-transform: uppercase;
|
|
167
|
+
letter-spacing: 0.8px; color: #7c8db0; margin-bottom: 6px;
|
|
168
|
+
}
|
|
169
|
+
.file-notes ul {
|
|
170
|
+
margin: 0; padding-left: 18px;
|
|
171
|
+
}
|
|
172
|
+
.file-notes li {
|
|
173
|
+
font-size: 13px; color: #555; line-height: 1.6; margin-bottom: 2px;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.changes-list {
|
|
177
|
+
padding: 10px 14px; font-size: 13px; line-height: 2;
|
|
178
|
+
}
|
|
179
|
+
.change-badge {
|
|
180
|
+
display: inline-block; padding: 1px 6px; border-radius: 3px;
|
|
181
|
+
font-size: 11px; font-weight: 600; color: white; margin-right: 4px;
|
|
182
|
+
}
|
|
183
|
+
.action-added { background: #22c55e; }
|
|
184
|
+
.action-removed { background: #ef4444; }
|
|
185
|
+
.action-modified { background: #f59e0b; }
|
|
186
|
+
.change-type { color: #999; font-size: 12px; }
|
|
187
|
+
code { font-family: "SF Mono", Menlo, monospace; font-size: 12px; }
|
|
188
|
+
|
|
189
|
+
/* Diff */
|
|
190
|
+
.diff-toggle { margin: 0; }
|
|
191
|
+
.diff-toggle summary {
|
|
192
|
+
padding: 8px 14px; cursor: pointer; font-size: 12px;
|
|
193
|
+
color: #888; user-select: none; border-top: 1px solid #f0f0f0;
|
|
194
|
+
}
|
|
195
|
+
.diff-toggle summary:hover { color: #555; }
|
|
196
|
+
.diff-block {
|
|
197
|
+
background: #1e1e1e; color: #d4d4d4; padding: 14px;
|
|
198
|
+
overflow-x: auto; font-size: 12px; line-height: 1.6;
|
|
199
|
+
font-family: "SF Mono", Menlo, monospace;
|
|
200
|
+
margin: 0; border-radius: 0;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/* Footer */
|
|
204
|
+
.footer {
|
|
205
|
+
margin-top: 36px; padding-top: 14px; border-top: 1px solid #eee;
|
|
206
|
+
color: #bbb; font-size: 11px;
|
|
207
|
+
}
|
|
84
208
|
</style>
|
|
85
209
|
</head>
|
|
86
210
|
<body>
|
|
87
|
-
<
|
|
88
|
-
|
|
211
|
+
<div class="article-header">
|
|
212
|
+
<div class="label">Change Report</div>
|
|
213
|
+
<h1>${escapeHtml(explanation.title)}</h1>
|
|
214
|
+
<div class="meta">
|
|
215
|
+
<span>${escapeHtml(report.baseRef)} → ${escapeHtml(report.headRef)}</span>
|
|
216
|
+
<span>${new Date(report.generatedAt).toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" })}</span>
|
|
217
|
+
</div>
|
|
218
|
+
</div>
|
|
89
219
|
|
|
90
220
|
<div class="stats">
|
|
91
|
-
<div class="stat"><b>${summary.filesChanged}</b> files
|
|
92
|
-
<div class="stat
|
|
93
|
-
<div class="stat
|
|
221
|
+
<div class="stat"><b>${summary.filesChanged}</b> files</div>
|
|
222
|
+
<div class="stat additions"><b>+${summary.additions}</b> added</div>
|
|
223
|
+
<div class="stat deletions"><b>-${summary.deletions}</b> removed</div>
|
|
94
224
|
</div>
|
|
95
225
|
|
|
96
|
-
<
|
|
97
|
-
<p style="margin:8px 0;">${escapeHtml(explanation.description)}</p>
|
|
226
|
+
<div class="description">${escapeHtml(explanation.description)}</div>
|
|
98
227
|
|
|
99
|
-
|
|
100
|
-
<div style="margin:8px 0;">${riskBadges}</div>
|
|
228
|
+
${fixesHtml ? `<h2>What was fixed</h2>\n${fixesHtml}` : ""}
|
|
101
229
|
|
|
102
|
-
|
|
103
|
-
<table>
|
|
104
|
-
<thead><tr><th></th><th>File</th><th>Status</th><th>Language</th><th>Changes</th></tr></thead>
|
|
105
|
-
<tbody>${filesTable}</tbody>
|
|
106
|
-
</table>
|
|
230
|
+
${risksHtml ? `<h2>Things to watch</h2>\n${risksHtml}` : ""}
|
|
107
231
|
|
|
108
|
-
<h2>
|
|
109
|
-
${
|
|
232
|
+
<h2>Changed files</h2>
|
|
233
|
+
${fileCards}
|
|
110
234
|
|
|
111
|
-
<div
|
|
112
|
-
Generated by
|
|
235
|
+
<div class="footer">
|
|
236
|
+
Generated by diffintel · ${explanation.tokenUsage.input + explanation.tokenUsage.output} tokens used
|
|
113
237
|
</div>
|
|
114
238
|
</body>
|
|
115
239
|
</html>`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html-report.js","sourceRoot":"","sources":["../../src/explain/html-report.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"html-report.js","sourceRoot":"","sources":["../../src/explain/html-report.ts"],"names":[],"mappings":";;AAUA,oCAkPC;AA1PD,SAAS,UAAU,CAAC,GAAW;IAC7B,OAAO,GAAG;SACP,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED,SAAgB,YAAY,CAAC,MAAqB;IAChD,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;IAE/C,wBAAwB;IACxB,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;QAC5C,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAC1B,gEAAgE,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAClG,CAAC,IAAI,CAAC,IAAI,CAAC;QACd,CAAC,CAAC,EAAE,CAAC;IAEP,wBAAwB;IACxB,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;QAC5C,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YAC1B,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,KAAK,EAAE,CAAC;YAC9B,OAAO,yBAAyB,GAAG,8BAA8B,CAAC,CAAC,KAAK,WAAW,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC;QACvH,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACf,CAAC,CAAC,EAAE,CAAC;IAEP,gCAAgC;IAChC,yCAAyC;IACzC,MAAM,mBAAmB,GAAG,IAAI,GAAG,CACjC,WAAW,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CACxD,CAAC;IAEF,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAChC,MAAM,MAAM,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAE/C,MAAM,WAAW,GAAG,CAAC,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC;YAChD,CAAC,CAAC,6BAA6B,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBACzD,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,MAAM,EAAE,CAAC;gBACjC,OAAO,6BAA6B,GAAG,KAAK,CAAC,CAAC,MAAM,iBAAiB,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC,IAAI,SAAS,CAAC;YAC9I,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ;YACzB,CAAC,CAAC,EAAE,CAAC;QAEP,MAAM,SAAS,GAAG,MAAM,EAAE,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;YACxD,CAAC,CAAC,iFAAiF,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa;YAC7J,CAAC,CAAC,EAAE,CAAC;QAEP,MAAM,QAAQ,GAAG,CAAC,CAAC,OAAO;YACxB,CAAC,CAAC,oFAAoF,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,kBAAkB;YAC5H,CAAC,CAAC,EAAE,CAAC;QAEP,OAAO;;0CAE+B,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;kCAC7B,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;;QAE5C,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,2BAA2B,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;QAClF,SAAS;QACT,WAAW;QACX,QAAQ;WACL,CAAC;IACV,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,mCAAmC;IACnC,OAAO;;;;;SAKA,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA2J5B,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC;;cAEzB,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC;cAC/D,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,kBAAkB,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;;;;;2BAK/F,OAAO,CAAC,YAAY;sCACT,OAAO,CAAC,SAAS;sCACjB,OAAO,CAAC,SAAS;;;6BAG1B,UAAU,CAAC,WAAW,CAAC,WAAW,CAAC;;IAE5D,SAAS,CAAC,CAAC,CAAC,4BAA4B,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE;;IAExD,SAAS,CAAC,CAAC,CAAC,6BAA6B,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE;;;IAGzD,SAAS;;;sCAGyB,WAAW,CAAC,UAAU,CAAC,KAAK,GAAG,WAAW,CAAC,UAAU,CAAC,MAAM;;;QAG1F,CAAC;AACT,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,UAAU,CAAC,IAAI,CAAC;SACpB,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,gCAAgC,IAAI,SAAS,CAAC;QAC/E,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,gCAAgC,IAAI,SAAS,CAAC;QAC/E,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,gCAAgC,IAAI,SAAS,CAAC;QAChF,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
|
|
@@ -5,22 +5,30 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.explainChanges = explainChanges;
|
|
7
7
|
const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
|
|
8
|
-
const SYSTEM_PROMPT = `You
|
|
8
|
+
const SYSTEM_PROMPT = `You explain code changes for both developers and non-developers. Respond ONLY with valid JSON. Be concise but clear.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
- You are given
|
|
12
|
-
- Use history to understand INTENT: if a recent commit
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
|
|
10
|
+
Context rules:
|
|
11
|
+
- You are given BASE STATE, RECENT GIT HISTORY (with diffs), and the current changes.
|
|
12
|
+
- Use history to understand INTENT: if a recent commit broke something and this diff fixes it, categorize it as a FIX.
|
|
13
|
+
- Clearly separate what was FIXED from what are genuine RISKS.
|
|
14
|
+
- Write the description in plain language that a non-developer can understand.
|
|
15
|
+
- For file explanations, describe what each file does and what changed in simple terms.
|
|
16
|
+
|
|
17
|
+
Precision rules:
|
|
18
|
+
- When describing changes, state what BEHAVIOR changed, not just what code moved.
|
|
19
|
+
- Be specific: "product listings now require a valid token" not "authentication was added".
|
|
20
|
+
- Name the affected endpoints, functions, or data flows.
|
|
21
|
+
- If an assumption or invariant changed (e.g., "IDs were sequential, now they're computed"), say so.
|
|
22
|
+
- Stick to what the diff shows. Do not speculate about intent beyond what the code and history demonstrate.`;
|
|
17
23
|
const ACTION_ICON = {
|
|
18
24
|
added: "+",
|
|
19
25
|
removed: "-",
|
|
20
26
|
modified: "~",
|
|
21
27
|
};
|
|
22
28
|
async function explainChanges(files, rawDiff) {
|
|
23
|
-
|
|
29
|
+
// Sort files by path for stable, deterministic prompt ordering
|
|
30
|
+
const sortedFiles = [...files].sort((a, b) => a.path.localeCompare(b.path));
|
|
31
|
+
const historySummary = sortedFiles
|
|
24
32
|
.filter((f) => f.recentHistory.length > 0)
|
|
25
33
|
.map((f) => {
|
|
26
34
|
const entries = f.recentHistory
|
|
@@ -36,11 +44,11 @@ async function explainChanges(files, rawDiff) {
|
|
|
36
44
|
return `- ${f.path}:\n${entries}${diffSection}`;
|
|
37
45
|
})
|
|
38
46
|
.join("\n");
|
|
39
|
-
const baseSummary =
|
|
47
|
+
const baseSummary = sortedFiles
|
|
40
48
|
.filter((f) => f.baseDeclarations.length > 0)
|
|
41
49
|
.map((f) => `- ${f.path}: ${f.baseDeclarations.join(", ")}`)
|
|
42
50
|
.join("\n");
|
|
43
|
-
const structuralSummary =
|
|
51
|
+
const structuralSummary = sortedFiles
|
|
44
52
|
.filter((f) => f.structuralChanges.length > 0)
|
|
45
53
|
.map((f) => {
|
|
46
54
|
const changes = f.structuralChanges
|
|
@@ -49,7 +57,7 @@ async function explainChanges(files, rawDiff) {
|
|
|
49
57
|
return `- ${f.path} (${f.status}): ${changes}`;
|
|
50
58
|
})
|
|
51
59
|
.join("\n");
|
|
52
|
-
|
|
60
|
+
const fileList = sortedFiles.map((f) => `- ${f.path} (${f.status})`).join("\n");
|
|
53
61
|
const truncatedDiff = truncateDiff(rawDiff, 4000);
|
|
54
62
|
const prompt = `## Recent git history for changed files
|
|
55
63
|
${historySummary || "(no prior history)"}
|
|
@@ -60,17 +68,30 @@ ${baseSummary || "(new files only, no prior state)"}
|
|
|
60
68
|
## Structural changes (this diff)
|
|
61
69
|
${structuralSummary || "(no structural changes detected)"}
|
|
62
70
|
|
|
71
|
+
## Files changed
|
|
72
|
+
${fileList}
|
|
73
|
+
|
|
63
74
|
## Diff (truncated)
|
|
64
75
|
${truncatedDiff || "(empty diff)"}
|
|
65
76
|
|
|
66
77
|
Respond with JSON:
|
|
67
|
-
{
|
|
68
|
-
"
|
|
69
|
-
"
|
|
78
|
+
{
|
|
79
|
+
"title": "<60 char title for these changes>",
|
|
80
|
+
"description": "<2-4 sentences in plain language explaining what changed and why, suitable for non-developers>",
|
|
81
|
+
"fixes": [{"description": "<what was fixed or restored, one sentence>"}],
|
|
82
|
+
"risks": [{"level": "low|medium|high", "description": "<genuine new risk, one sentence>"}],
|
|
83
|
+
"fileExplanations": [{"path": "<file path>", "summary": "<1-2 sentences explaining what this file does and what changed>", "notes": ["<thing to consider about this specific change>"]}]
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
Rules:
|
|
87
|
+
- "fixes": things this change REPAIRS or RESTORES (e.g., re-adding security that was removed). Can be empty.
|
|
88
|
+
- "risks": only GENUINE new concerns, NOT things being fixed. If a change restores previous behavior, that is a fix, not a risk. Can be empty.
|
|
89
|
+
- "fileExplanations": one entry per changed file, plain language. "notes" are file-specific things to consider — edge cases, testing suggestions, behavioral changes. Can be empty array if nothing notable.`;
|
|
70
90
|
const client = new sdk_1.default();
|
|
71
91
|
const message = await client.messages.create({
|
|
72
92
|
model: "claude-sonnet-4-5-20250929",
|
|
73
|
-
max_tokens:
|
|
93
|
+
max_tokens: 1024,
|
|
94
|
+
temperature: 0,
|
|
74
95
|
system: SYSTEM_PROMPT,
|
|
75
96
|
messages: [{ role: "user", content: prompt }],
|
|
76
97
|
});
|
|
@@ -88,24 +109,28 @@ Respond with JSON:
|
|
|
88
109
|
parsed = JSON.parse(cleaned);
|
|
89
110
|
}
|
|
90
111
|
catch {
|
|
91
|
-
// Fallback if LLM doesn't return valid JSON
|
|
92
112
|
parsed = {
|
|
93
113
|
title: "Code changes",
|
|
94
114
|
description: text.slice(0, 200),
|
|
115
|
+
fixes: [],
|
|
95
116
|
risks: [{ level: "low", description: "LLM response was not valid JSON; showing raw text." }],
|
|
117
|
+
fileExplanations: [],
|
|
96
118
|
};
|
|
97
119
|
}
|
|
98
120
|
return {
|
|
99
121
|
title: parsed.title || "Code changes",
|
|
100
122
|
description: parsed.description || "",
|
|
123
|
+
fixes: Array.isArray(parsed.fixes) ? parsed.fixes : [],
|
|
101
124
|
risks: Array.isArray(parsed.risks) ? parsed.risks : [],
|
|
125
|
+
fileExplanations: Array.isArray(parsed.fileExplanations)
|
|
126
|
+
? parsed.fileExplanations.map((fe) => ({ ...fe, notes: Array.isArray(fe.notes) ? fe.notes : [] }))
|
|
127
|
+
: [],
|
|
102
128
|
tokenUsage,
|
|
103
129
|
};
|
|
104
130
|
}
|
|
105
131
|
function truncateDiff(diff, maxLen) {
|
|
106
132
|
if (diff.length <= maxLen)
|
|
107
133
|
return diff;
|
|
108
|
-
// Split by file sections, keep as many as fit
|
|
109
134
|
const sections = diff.split(/^diff --git /m).filter(Boolean);
|
|
110
135
|
let result = "";
|
|
111
136
|
for (const section of sections) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm-explain.js","sourceRoot":"","sources":["../../src/explain/llm-explain.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"llm-explain.js","sourceRoot":"","sources":["../../src/explain/llm-explain.ts"],"names":[],"mappings":"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"}
|
package/dist/explain/types.d.ts
CHANGED
|
@@ -35,14 +35,24 @@ export interface FileAnalysis {
|
|
|
35
35
|
recentHistory: FileHistoryEntry[];
|
|
36
36
|
rawDiff: string;
|
|
37
37
|
}
|
|
38
|
+
export interface Fix {
|
|
39
|
+
description: string;
|
|
40
|
+
}
|
|
38
41
|
export interface Risk {
|
|
39
42
|
level: "low" | "medium" | "high";
|
|
40
43
|
description: string;
|
|
41
44
|
}
|
|
45
|
+
export interface FileExplanation {
|
|
46
|
+
path: string;
|
|
47
|
+
summary: string;
|
|
48
|
+
notes: string[];
|
|
49
|
+
}
|
|
42
50
|
export interface LLMExplanation {
|
|
43
51
|
title: string;
|
|
44
52
|
description: string;
|
|
53
|
+
fixes: Fix[];
|
|
45
54
|
risks: Risk[];
|
|
55
|
+
fileExplanations: FileExplanation[];
|
|
46
56
|
tokenUsage: {
|
|
47
57
|
input: number;
|
|
48
58
|
output: number;
|