@kodus/kodus-graph 0.2.5 → 0.2.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/package.json +1 -1
- package/src/analysis/diff.ts +11 -12
- package/src/analysis/prompt-formatter.ts +47 -7
package/package.json
CHANGED
package/src/analysis/diff.ts
CHANGED
|
@@ -74,18 +74,17 @@ export function computeStructuralDiff(
|
|
|
74
74
|
} else {
|
|
75
75
|
const newN = newNodesMap.get(qn)!;
|
|
76
76
|
const changes: string[] = [];
|
|
77
|
-
// Detect real changes vs. pure displacement
|
|
78
|
-
// content_hash
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (n.content_hash
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
77
|
+
// Detect real content changes vs. pure displacement.
|
|
78
|
+
// content_hash = SHA256 of the node's source text (position-independent).
|
|
79
|
+
if (n.content_hash && newN.content_hash) {
|
|
80
|
+
// Definitive: hash comparison catches ALL content changes,
|
|
81
|
+
// even same-line-count edits (e.g. `return 1` → `return 2`).
|
|
82
|
+
if (n.content_hash !== newN.content_hash) changes.push('body');
|
|
83
|
+
} else if (n.line_start !== newN.line_start || n.line_end !== newN.line_end) {
|
|
84
|
+
// Fallback (legacy data without content_hash): size heuristic.
|
|
85
|
+
const oldSize = n.line_end - n.line_start;
|
|
86
|
+
const newSize = newN.line_end - newN.line_start;
|
|
87
|
+
if (oldSize !== newSize) changes.push('line_range');
|
|
89
88
|
}
|
|
90
89
|
if ((n.params || '') !== (newN.params || '')) changes.push('params');
|
|
91
90
|
if ((n.return_type || '') !== (newN.return_type || '')) changes.push('return_type');
|
|
@@ -118,16 +118,56 @@ export function formatPrompt(output: ContextV2Output): string {
|
|
|
118
118
|
lines.push('');
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
// Structural diff
|
|
121
|
+
// Structural diff
|
|
122
122
|
const diff = analysis.structural_diff;
|
|
123
|
-
|
|
123
|
+
const hasNodeChanges = diff.summary.added > 0 || diff.summary.removed > 0 || diff.summary.modified > 0;
|
|
124
|
+
const hasEdgeChanges = diff.edges.added.length > 0 || diff.edges.removed.length > 0;
|
|
125
|
+
|
|
126
|
+
if (hasNodeChanges || hasEdgeChanges) {
|
|
124
127
|
lines.push('## Structural Changes');
|
|
125
128
|
lines.push('');
|
|
126
|
-
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
|
|
130
|
+
if (hasNodeChanges) {
|
|
131
|
+
const parts: string[] = [];
|
|
132
|
+
if (diff.summary.added > 0) parts.push(`${diff.summary.added} added`);
|
|
133
|
+
if (diff.summary.removed > 0) parts.push(`${diff.summary.removed} removed`);
|
|
134
|
+
if (diff.summary.modified > 0) parts.push(`${diff.summary.modified} modified`);
|
|
135
|
+
lines.push(parts.join(', '));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (diff.nodes.removed.length > 0) {
|
|
139
|
+
lines.push('');
|
|
140
|
+
lines.push('Removed:');
|
|
141
|
+
for (const n of diff.nodes.removed) {
|
|
142
|
+
const name = n.qualified_name.split('::').pop();
|
|
143
|
+
lines.push(` - [${n.kind}] ${name} [${n.file_path}:${n.line_start}]`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (diff.nodes.modified.length > 0) {
|
|
148
|
+
lines.push('');
|
|
149
|
+
lines.push('Modified:');
|
|
150
|
+
for (const m of diff.nodes.modified) {
|
|
151
|
+
const name = m.qualified_name.split('::').pop();
|
|
152
|
+
lines.push(` - ${name} (${m.changes.join(', ')})`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (hasEdgeChanges) {
|
|
157
|
+
lines.push('');
|
|
158
|
+
lines.push('Dependency changes:');
|
|
159
|
+
for (const e of diff.edges.added) {
|
|
160
|
+
const src = e.source_qualified.split('::').pop();
|
|
161
|
+
const tgt = e.target_qualified.split('::').pop();
|
|
162
|
+
lines.push(` + ${e.kind}: ${src} → ${tgt}`);
|
|
163
|
+
}
|
|
164
|
+
for (const e of diff.edges.removed) {
|
|
165
|
+
const src = e.source_qualified.split('::').pop();
|
|
166
|
+
const tgt = e.target_qualified.split('::').pop();
|
|
167
|
+
lines.push(` - ${e.kind}: ${src} → ${tgt}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
131
171
|
lines.push('');
|
|
132
172
|
}
|
|
133
173
|
|