codeblast 0.3.3 → 0.3.4
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/bin.js +30 -8
- package/package.json +2 -1
package/dist/bin.js
CHANGED
|
@@ -899,6 +899,13 @@ var init_cli = __esm(() => {
|
|
|
899
899
|
if (pyFiles > 0)
|
|
900
900
|
console.error(`python files ingested: ${pyFiles}`);
|
|
901
901
|
}
|
|
902
|
+
if (failures === 0) {
|
|
903
|
+
const stale = db.prepare("SELECT path FROM files").all().filter((row) => !seenFiles.has(row.path));
|
|
904
|
+
transaction(db, () => {
|
|
905
|
+
for (const row of stale)
|
|
906
|
+
invalidateFile(db, row.path);
|
|
907
|
+
})();
|
|
908
|
+
}
|
|
902
909
|
dt = ((performance.now() - t0) / 1000).toFixed(1);
|
|
903
910
|
console.log(JSON.stringify({
|
|
904
911
|
db: dbPath,
|
|
@@ -2046,6 +2053,7 @@ function reviewDecision(input) {
|
|
|
2046
2053
|
const { diff, prodNodesAdded, bodyChanged, affectedTests, truncated, blindSpotCount } = input;
|
|
2047
2054
|
const apiContractions = diff.visibilityChanged.filter((v) => !v.nowExported).length;
|
|
2048
2055
|
const apiChanges = apiContractions + diff.signatureChanged.length;
|
|
2056
|
+
const renames = diff.renamed.length;
|
|
2049
2057
|
const removals = diff.nodesRemoved.length;
|
|
2050
2058
|
const behaviorChanges = bodyChanged.length;
|
|
2051
2059
|
const reasons = [];
|
|
@@ -2053,7 +2061,7 @@ function reviewDecision(input) {
|
|
|
2053
2061
|
let risk = "low";
|
|
2054
2062
|
if (apiContractions > 0 || removals > 0 || truncated)
|
|
2055
2063
|
risk = "high";
|
|
2056
|
-
else if (apiChanges > 0 || behaviorChanges > 0 || affectedTests > 0 || blindSpotCount > 0)
|
|
2064
|
+
else if (apiChanges > 0 || renames > 0 || behaviorChanges > 0 || affectedTests > 0 || blindSpotCount > 0)
|
|
2057
2065
|
risk = "medium";
|
|
2058
2066
|
if (apiContractions > 0)
|
|
2059
2067
|
reasons.push(`${apiContractions} exported symbol${apiContractions === 1 ? " is" : "s are"} no longer public`);
|
|
@@ -2061,10 +2069,10 @@ function reviewDecision(input) {
|
|
|
2061
2069
|
reasons.push(`${removals} symbol${removals === 1 ? " was" : "s were"} removed`);
|
|
2062
2070
|
if (diff.signatureChanged.length > 0)
|
|
2063
2071
|
reasons.push(`${diff.signatureChanged.length} exported signature${diff.signatureChanged.length === 1 ? " changed" : "s changed"}`);
|
|
2072
|
+
if (renames > 0)
|
|
2073
|
+
reasons.push(`${renames} symbol${renames === 1 ? " was" : "s were"} renamed`);
|
|
2064
2074
|
if (behaviorChanges > 0)
|
|
2065
2075
|
reasons.push(`${behaviorChanges} function bod${behaviorChanges === 1 ? "y" : "ies"} changed`);
|
|
2066
|
-
if (affectedTests > 0)
|
|
2067
|
-
reasons.push(`${affectedTests} test file${affectedTests === 1 ? " is" : "s are"} in the predicted impact set`);
|
|
2068
2076
|
if (truncated)
|
|
2069
2077
|
reasons.push("the impact set exceeded the reporting limit");
|
|
2070
2078
|
if (blindSpotCount > 0)
|
|
@@ -2197,7 +2205,9 @@ var init_pr_comment = __esm(async () => {
|
|
|
2197
2205
|
if (diff2.renamed.length > 0) {
|
|
2198
2206
|
lines3.push(`### 重命名`, ``);
|
|
2199
2207
|
for (const r of diff2.renamed.slice(0, 10)) {
|
|
2200
|
-
|
|
2208
|
+
const targetName = r.to.includes("#") ? r.to.split("#").pop() : r.to;
|
|
2209
|
+
const target = dbB2.prepare("SELECT line FROM nodes WHERE file = ? AND name = ? ORDER BY line LIMIT 1").get(r.file, targetName);
|
|
2210
|
+
lines3.push(`- \`${r.from}\` → \`${r.to}\` (${r.kind})${target ? ` (${link(r.file, target.line)})` : ""}`);
|
|
2201
2211
|
}
|
|
2202
2212
|
if (diff2.renamed.length > 10)
|
|
2203
2213
|
lines3.push(`- …及另外 ${diff2.renamed.length - 10} 项`);
|
|
@@ -2338,7 +2348,7 @@ var SCHEMA_VERSION = "1", EXIT_OK = 0, EXIT_REVIEW = 1, EXIT_ERROR = 2, readVers
|
|
|
2338
2348
|
nodes: Number(db.prepare("SELECT COUNT(*) c FROM nodes").get().c),
|
|
2339
2349
|
edges: Number(db.prepare("SELECT COUNT(*) c FROM edges").get().c),
|
|
2340
2350
|
blind_spots: Number(db.prepare("SELECT COUNT(*) c FROM blind_spots").get().c)
|
|
2341
|
-
}), healthBase, healthHead, diff3, healthWarnings, prodNodesAdded2, total3, affectedTests = 0, truncated = false, blindSpots = 0, bodyChanged2, diffText, currentFile = "", diffLineCount2, decision2, output;
|
|
2351
|
+
}), healthBase, healthHead, diff3, healthWarnings, prodNodesAdded2, total3, affectedTests = 0, truncated = false, blindSpots = 0, bodyChanged2, structuralIds2, diffText, currentFile = "", diffLineCount2, changedFiles2, auxOnly, decision2, output;
|
|
2342
2352
|
var init_check_change = __esm(() => {
|
|
2343
2353
|
init_db();
|
|
2344
2354
|
init_proc();
|
|
@@ -2383,6 +2393,10 @@ var init_check_change = __esm(() => {
|
|
|
2383
2393
|
} catch {}
|
|
2384
2394
|
}
|
|
2385
2395
|
bodyChanged2 = [];
|
|
2396
|
+
structuralIds2 = new Set([
|
|
2397
|
+
...diff3.nodesAdded.map((node) => node.id),
|
|
2398
|
+
...diff3.renamed.map((rename) => `${rename.file}#${rename.to}`)
|
|
2399
|
+
]);
|
|
2386
2400
|
diffText = spawnSync(["git", "diff", "--unified=0", baseSha2, headSha2, "--", "*.ts", "*.tsx"], { cwd: repo3 }).stdout;
|
|
2387
2401
|
for (const line of diffText.split(`
|
|
2388
2402
|
`)) {
|
|
@@ -2392,10 +2406,10 @@ var init_check_change = __esm(() => {
|
|
|
2392
2406
|
continue;
|
|
2393
2407
|
}
|
|
2394
2408
|
const hunk = line.match(/^@@ -\d+(?:,\d+)? \+(\d+)/);
|
|
2395
|
-
if (!hunk || !currentFile || TEST_RE3.test(currentFile))
|
|
2409
|
+
if (!hunk || !currentFile || TEST_RE3.test(currentFile) || AUX_RE.test(currentFile))
|
|
2396
2410
|
continue;
|
|
2397
2411
|
const row = dbB3.prepare("SELECT id, name, kind, file, line FROM nodes WHERE file = ? AND kind IN ('function','method') AND line <= ? AND end_line >= ? ORDER BY (end_line - line) ASC LIMIT 1").get(currentFile, Number(hunk[1]), Number(hunk[1]));
|
|
2398
|
-
if (row && !bodyChanged2.some((item) => item.id === row.id))
|
|
2412
|
+
if (row && !structuralIds2.has(row.id) && !bodyChanged2.some((item) => item.id === row.id))
|
|
2399
2413
|
bodyChanged2.push(row);
|
|
2400
2414
|
}
|
|
2401
2415
|
diffLineCount2 = spawnSync(["git", "diff", "--numstat", baseSha2, headSha2], { cwd: repo3 }).stdout.split(`
|
|
@@ -2403,11 +2417,19 @@ var init_check_change = __esm(() => {
|
|
|
2403
2417
|
const match = line.match(/^(\d+)\t(\d+)\t/);
|
|
2404
2418
|
return sum + (match ? Number(match[1]) + Number(match[2]) : 0);
|
|
2405
2419
|
}, 0);
|
|
2420
|
+
changedFiles2 = spawnSync(["git", "diff", "--name-only", baseSha2, headSha2], { cwd: repo3 }).stdout.split(`
|
|
2421
|
+
`).filter(Boolean);
|
|
2422
|
+
auxOnly = changedFiles2.length > 0 && changedFiles2.every((file) => AUX_RE.test(file));
|
|
2406
2423
|
decision2 = reviewDecision({ diff: diff3, prodNodesAdded: prodNodesAdded2, bodyChanged: bodyChanged2, affectedTests, truncated, blindSpotCount: blindSpots });
|
|
2407
2424
|
if (healthWarnings.length > 0) {
|
|
2408
2425
|
decision2.risk = "high";
|
|
2409
2426
|
decision2.reasons.push(...healthWarnings);
|
|
2410
2427
|
decision2.recommendedActions.unshift("Rebuild or inspect the graph before relying on this decision.");
|
|
2428
|
+
} else if (auxOnly) {
|
|
2429
|
+
decision2.risk = "low";
|
|
2430
|
+
decision2.summary = "Low structural risk: only auxiliary-directory changes were found.";
|
|
2431
|
+
decision2.reasons = ["only auxiliary-directory changes were found"];
|
|
2432
|
+
decision2.recommendedActions = ["No code review signal; inspect the auxiliary change directly if needed."];
|
|
2411
2433
|
}
|
|
2412
2434
|
output = {
|
|
2413
2435
|
schema_version: SCHEMA_VERSION,
|
|
@@ -2426,7 +2448,7 @@ var init_check_change = __esm(() => {
|
|
|
2426
2448
|
signals: {
|
|
2427
2449
|
core_named: coreNamedCount(diff3, prodNodesAdded2),
|
|
2428
2450
|
body: bodySignalCount(bodyChanged2, diffLineCount2, () => false),
|
|
2429
|
-
aux_only:
|
|
2451
|
+
aux_only: auxOnly
|
|
2430
2452
|
},
|
|
2431
2453
|
diff: diff3
|
|
2432
2454
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeblast",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "Know what breaks before you merge — mutation-tested code graph with architecture, change & impact maps. Evidence on every edge. For humans and AI agents.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"impact-analysis",
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"typecheck": "tsc -p .",
|
|
41
41
|
"agent-smoke": "bun run build && node eval/agent-workflow-smoke.mjs",
|
|
42
42
|
"guidance-stability": "node eval/guidance-stability.mjs",
|
|
43
|
+
"incremental-equivalence": "bun run build && node eval/incremental-equivalence.mjs",
|
|
43
44
|
"offline-replay": "bun run build && node eval/offline-replay.mjs",
|
|
44
45
|
"pilot-summary": "node eval/pilot-summary.mjs",
|
|
45
46
|
"release-smoke": "node eval/release-smoke.mjs",
|