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.
@@ -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(`\nTitle: ${explanation.title}`);
53
- console.error(`Files: ${fileDiffs.length} | +${totalAdditions} -${totalDeletions}`);
54
- console.error(`Risks: ${explanation.risks.length > 0 ? explanation.risks.map((r) => `${r.level}: ${r.description}`).join("; ") : "none"}`);
55
- console.error(`Tokens: ${explanation.tokenUsage.input} in / ${explanation.tokenUsage.output} out`);
56
- console.error(`\nReport written to: ${outFile}`);
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":"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"}
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
- const riskBadges = explanation.risks.length > 0
13
+ // --- Fixes section ---
14
+ const fixesHtml = explanation.fixes.length > 0
15
+ ? explanation.fixes.map((f) => `<div class="fix-item"><span class="fix-icon">&#10003;</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 c = RISK_COLORS[r.level] || RISK_COLORS.low;
32
- return `<span style="display:inline-block;padding:2px 8px;border-radius:4px;font-size:13px;background:${c.bg};color:${c.text};margin-right:6px;">${r.level.toUpperCase()}: ${escapeHtml(r.description)}</span>`;
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
- : '<span style="color:#166534;">No risks identified</span>';
35
- const filesTable = files.map((f) => {
36
- const icon = STATUS_ICON[f.status] || "";
37
- const changeCount = f.structuralChanges.length;
38
- return `<tr>
39
- <td>${icon}</td>
40
- <td style="font-family:monospace;font-size:13px;">${escapeHtml(f.path)}</td>
41
- <td>${f.status}</td>
42
- <td>${f.language || "—"}</td>
43
- <td>${changeCount}</td>
44
- </tr>`;
45
- }).join("\n");
46
- const fileDetails = files.map((f) => {
47
- const changesList = f.structuralChanges.length > 0
48
- ? "<ul style=\"margin:8px 0;padding-left:20px;\">" +
49
- f.structuralChanges.map((c) => {
50
- const badge = ACTION_BADGE[c.action] || ACTION_BADGE.modified;
51
- return `<li><span style="display:inline-block;padding:1px 6px;border-radius:3px;font-size:11px;background:${badge.color};color:white;margin-right:4px;">${badge.label}</span> <code>${escapeHtml(c.name)}</code> <span style="color:#666;">(${c.type})</span></li>`;
52
- }).join("\n") +
53
- "</ul>"
54
- : "<p style=\"color:#888;margin:8px 0;\">No structural changes detected</p>";
55
- const diffBlock = f.rawDiff
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
- </details>`;
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 { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; max-width: 900px; margin: 0 auto; padding: 24px; color: #1f2937; background: #fff; line-height: 1.6; }
75
- h1 { font-size: 22px; margin-bottom: 6px; }
76
- h2 { font-size: 16px; margin: 24px 0 10px; color: #374151; border-bottom: 1px solid #e5e7eb; padding-bottom: 6px; }
77
- table { width: 100%; border-collapse: collapse; margin: 10px 0; }
78
- th, td { text-align: left; padding: 6px 10px; border-bottom: 1px solid #f3f4f6; font-size: 13px; }
79
- th { background: #f9fafb; font-weight: 600; }
80
- .stats { display: flex; gap: 16px; margin: 12px 0; }
81
- .stat { padding: 8px 14px; border-radius: 6px; background: #f3f4f6; font-size: 14px; }
82
- .stat b { font-size: 18px; }
83
- .meta { color: #6b7280; font-size: 12px; margin-bottom: 16px; }
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
- <h1>${escapeHtml(explanation.title)}</h1>
88
- <div class="meta">${escapeHtml(report.baseRef)} &rarr; ${escapeHtml(report.headRef)} &middot; ${escapeHtml(report.generatedAt)}</div>
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)} &rarr; ${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 changed</div>
92
- <div class="stat" style="color:#166534;"><b>+${summary.additions}</b> additions</div>
93
- <div class="stat" style="color:#991b1b;"><b>-${summary.deletions}</b> deletions</div>
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
- <h2>Description</h2>
97
- <p style="margin:8px 0;">${escapeHtml(explanation.description)}</p>
226
+ <div class="description">${escapeHtml(explanation.description)}</div>
98
227
 
99
- <h2>Risk Assessment</h2>
100
- <div style="margin:8px 0;">${riskBadges}</div>
228
+ ${fixesHtml ? `<h2>What was fixed</h2>\n${fixesHtml}` : ""}
101
229
 
102
- <h2>Files Overview</h2>
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>File Details</h2>
109
- ${fileDetails}
232
+ <h2>Changed files</h2>
233
+ ${fileCards}
110
234
 
111
- <div style="margin-top:32px;padding-top:12px;border-top:1px solid #e5e7eb;color:#9ca3af;font-size:11px;">
112
- Generated by intent-spec explain &middot; Tokens: ${explanation.tokenUsage.input} in / ${explanation.tokenUsage.output} out
235
+ <div class="footer">
236
+ Generated by diffintel &middot; ${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":"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"}
1
+ {"version":3,"file":"html-report.js","sourceRoot":"","sources":["../../src/explain/html-report.ts"],"names":[],"mappings":"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"}
@@ -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 analyze code changes. Respond ONLY with valid JSON. Be extremely concise.
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
- IMPORTANT context rules for risk assessment:
11
- - You are given the BASE STATE (declarations before this diff) and RECENT GIT HISTORY (what happened to each file recently).
12
- - Use history to understand INTENT: if a recent commit removed something and this diff adds it back, that is a FIX/RESTORATION, not a breaking change.
13
- - RESTORATION: re-adding something that was recently removed is safe do NOT flag as high risk.
14
- - NEW addition: only flag as breaking if it introduces behavior that never existed before.
15
- - REMOVAL: flag as risky if it removes established functionality.
16
- - When history shows a recent problematic change, frame this diff as fixing/reverting that change.`;
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
- const historySummary = files
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 = files
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 = files
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
- // Truncate diff to ~4000 chars, prioritizing modified files
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
- { "title": "<60 char PR title>",
68
- "description": "<2-4 sentences summarizing the changes>",
69
- "risks": [{"level":"low|medium|high","description":"<one sentence>"}] }`;
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: 512,
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":";;;;;AAmBA,wCA6FC;AAhHD,4DAA0C;AAG1C,MAAM,aAAa,GAAG;;;;;;;;mGAQ6E,CAAC;AAEpG,MAAM,WAAW,GAA2B;IAC1C,KAAK,EAAE,GAAG;IACV,OAAO,EAAE,GAAG;IACZ,QAAQ,EAAE,GAAG;CACd,CAAC;AAEK,KAAK,UAAU,cAAc,CAClC,KAAqB,EACrB,OAAe;IAEf,MAAM,cAAc,GAAG,KAAK;SACzB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;SACzC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,OAAO,GAAG,CAAC,CAAC,aAAa;aAC5B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC;aACnD,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,UAAU,GAAG,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;QAC5C,MAAM,WAAW,GAAG,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,IAAI;YACxD,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,mBAAmB;YACjD,CAAC,CAAC,UAAU,CAAC;QACf,MAAM,WAAW,GAAG,WAAW;YAC7B,CAAC,CAAC,iCAAiC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC9F,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,KAAK,CAAC,CAAC,IAAI,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAClD,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,WAAW,GAAG,KAAK;SACtB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC;SAC5C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;SAC3D,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,iBAAiB,GAAG,KAAK;SAC5B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC;SAC7C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,OAAO,GAAG,CAAC,CAAC,iBAAiB;aAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC;aAC3D,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,OAAO,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM,MAAM,OAAO,EAAE,CAAC;IACjD,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,4DAA4D;IAC5D,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAElD,MAAM,MAAM,GAAG;EACf,cAAc,IAAI,oBAAoB;;;EAGtC,WAAW,IAAI,kCAAkC;;;EAGjD,iBAAiB,IAAI,kCAAkC;;;EAGvD,aAAa,IAAI,cAAc;;;;;0EAKyC,CAAC;IAEzE,MAAM,MAAM,GAAG,IAAI,aAAS,EAAE,CAAC;IAC/B,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC3C,KAAK,EAAE,4BAA4B;QACnC,UAAU,EAAE,GAAG;QACf,MAAM,EAAE,aAAa;QACrB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;KAC9C,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO;SACzB,MAAM,CAAC,CAAC,KAAK,EAAgC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC;SACtE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;SAC1B,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,UAAU,GAAG;QACjB,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,YAAY,IAAI,CAAC;QACvC,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,aAAa,IAAI,CAAC;KAC1C,CAAC;IAEF,IAAI,MAA6D,CAAC;IAClE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAChF,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,4CAA4C;QAC5C,MAAM,GAAG;YACP,KAAK,EAAE,cAAc;YACrB,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;YAC/B,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,oDAAoD,EAAE,CAAC;SAC7F,CAAC;IACJ,CAAC;IAED,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,cAAc;QACrC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE;QACrC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;QACtD,UAAU;KACX,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,IAAY,EAAE,MAAc;IAChD,IAAI,IAAI,CAAC,MAAM,IAAI,MAAM;QAAE,OAAO,IAAI,CAAC;IAEvC,8CAA8C;IAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7D,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,cAAc,OAAO,EAAE,CAAC;QACtC,IAAI,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;YAC1C,MAAM,IAAI,wBAAwB,CAAC;YACnC,MAAM;QACR,CAAC;QACD,MAAM,IAAI,KAAK,CAAC;IAClB,CAAC;IACD,OAAO,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,mBAAmB,CAAC;AAC/D,CAAC"}
1
+ {"version":3,"file":"llm-explain.js","sourceRoot":"","sources":["../../src/explain/llm-explain.ts"],"names":[],"mappings":";;;;;AAiCA,wCAmHC;AApJD,4DAA0C;AAG1C,MAAM,aAAa,GAAG;;;;;;;;;;;;;;4GAcsF,CAAC;AAE7G,MAAM,WAAW,GAA2B;IAC1C,KAAK,EAAE,GAAG;IACV,OAAO,EAAE,GAAG;IACZ,QAAQ,EAAE,GAAG;CACd,CAAC;AAUK,KAAK,UAAU,cAAc,CAClC,KAAqB,EACrB,OAAe;IAEf,+DAA+D;IAC/D,MAAM,WAAW,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAE5E,MAAM,cAAc,GAAG,WAAW;SAC/B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;SACzC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,OAAO,GAAG,CAAC,CAAC,aAAa;aAC5B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC;aACnD,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,UAAU,GAAG,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;QAC5C,MAAM,WAAW,GAAG,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,IAAI;YACxD,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,mBAAmB;YACjD,CAAC,CAAC,UAAU,CAAC;QACf,MAAM,WAAW,GAAG,WAAW;YAC7B,CAAC,CAAC,iCAAiC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC9F,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,KAAK,CAAC,CAAC,IAAI,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAClD,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,WAAW,GAAG,WAAW;SAC5B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC;SAC5C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;SAC3D,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,iBAAiB,GAAG,WAAW;SAClC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC;SAC7C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,OAAO,GAAG,CAAC,CAAC,iBAAiB;aAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC;aAC3D,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,OAAO,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM,MAAM,OAAO,EAAE,CAAC;IACjD,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEhF,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAElD,MAAM,MAAM,GAAG;EACf,cAAc,IAAI,oBAAoB;;;EAGtC,WAAW,IAAI,kCAAkC;;;EAGjD,iBAAiB,IAAI,kCAAkC;;;EAGvD,QAAQ;;;EAGR,aAAa,IAAI,cAAc;;;;;;;;;;;;;;6MAc4K,CAAC;IAE5M,MAAM,MAAM,GAAG,IAAI,aAAS,EAAE,CAAC;IAC/B,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC3C,KAAK,EAAE,4BAA4B;QACnC,UAAU,EAAE,IAAI;QAChB,WAAW,EAAE,CAAC;QACd,MAAM,EAAE,aAAa;QACrB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;KAC9C,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO;SACzB,MAAM,CAAC,CAAC,KAAK,EAAgC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC;SACtE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;SAC1B,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,UAAU,GAAG;QACjB,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,YAAY,IAAI,CAAC;QACvC,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,aAAa,IAAI,CAAC;KAC1C,CAAC;IAEF,IAAI,MAAmB,CAAC;IACxB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAChF,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,GAAG;YACP,KAAK,EAAE,cAAc;YACrB,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;YAC/B,KAAK,EAAE,EAAE;YACT,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,oDAAoD,EAAE,CAAC;YAC5F,gBAAgB,EAAE,EAAE;SACrB,CAAC;IACJ,CAAC;IAED,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,cAAc;QACrC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE;QACrC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;QACtD,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;QACtD,gBAAgB,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC;YACtD,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAClG,CAAC,CAAC,EAAE;QACN,UAAU;KACX,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,IAAY,EAAE,MAAc;IAChD,IAAI,IAAI,CAAC,MAAM,IAAI,MAAM;QAAE,OAAO,IAAI,CAAC;IAEvC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7D,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,cAAc,OAAO,EAAE,CAAC;QACtC,IAAI,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;YAC1C,MAAM,IAAI,wBAAwB,CAAC;YACnC,MAAM;QACR,CAAC;QACD,MAAM,IAAI,KAAK,CAAC;IAClB,CAAC;IACD,OAAO,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,mBAAmB,CAAC;AAC/D,CAAC"}
@@ -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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "diffintel",
3
- "version": "0.1.3",
3
+ "version": "0.2.1",
4
4
  "description": "AI-powered structural diff explainer for pull requests",
5
5
  "bin": {
6
6
  "diffintel": "dist/cli.js"