greenbump 0.2.1 → 0.4.0
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/CHANGELOG.md +39 -0
- package/README.md +2 -0
- package/action-dist/index.cjs +241 -1
- package/competitive-analysis.md +304 -0
- package/dist/engine/change-detector.js +152 -0
- package/dist/engine/change-detector.js.map +1 -0
- package/dist/engine/dep-graph.js +101 -0
- package/dist/engine/dep-graph.js.map +1 -0
- package/dist/engine/git.js +9 -0
- package/dist/engine/git.js.map +1 -1
- package/dist/engine/run.js +22 -1
- package/dist/engine/run.js.map +1 -1
- package/dist/engine/staged-fix.js +108 -0
- package/dist/engine/staged-fix.js.map +1 -0
- package/dist/engine/stages.js +125 -0
- package/dist/engine/stages.js.map +1 -0
- package/dist/engine/verify.js +121 -0
- package/dist/engine/verify.js.map +1 -0
- package/dist/format.js +20 -0
- package/dist/format.js.map +1 -1
- package/optimization-roadmap.md +772 -0
- package/package.json +4 -1
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { exec } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
const execAsync = promisify(exec);
|
|
4
|
+
/**
|
|
5
|
+
* Detect suspicious changes in the git diff that might indicate the LLM
|
|
6
|
+
* "cheated" to make tests pass (e.g., commenting out tests, deleting code).
|
|
7
|
+
*/
|
|
8
|
+
export async function detectSuspiciousChanges(cwd) {
|
|
9
|
+
const changes = [];
|
|
10
|
+
try {
|
|
11
|
+
// Get git diff for staged + unstaged changes
|
|
12
|
+
const { stdout: diff } = await execAsync("git diff HEAD", { cwd });
|
|
13
|
+
if (!diff.trim())
|
|
14
|
+
return []; // No changes
|
|
15
|
+
// 1. Detect test file modifications
|
|
16
|
+
const testFileChanges = detectTestFileChanges(diff);
|
|
17
|
+
changes.push(...testFileChanges);
|
|
18
|
+
// 2. Detect large deletions (>50 lines in a single file)
|
|
19
|
+
const largeDeletions = detectLargeDeletions(diff);
|
|
20
|
+
changes.push(...largeDeletions);
|
|
21
|
+
// 3. Detect commented-out tests (heuristic)
|
|
22
|
+
const commentedTests = detectCommentedTests(diff);
|
|
23
|
+
changes.push(...commentedTests);
|
|
24
|
+
// 4. Detect removed test cases (it('...') or test('...') deletions)
|
|
25
|
+
const removedTests = detectRemovedTests(diff);
|
|
26
|
+
changes.push(...removedTests);
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
// Git command failed (e.g., not a git repo) - ignore
|
|
30
|
+
}
|
|
31
|
+
return changes;
|
|
32
|
+
}
|
|
33
|
+
function detectTestFileChanges(diff) {
|
|
34
|
+
const changes = [];
|
|
35
|
+
const testFilePattern = /\.(test|spec)\.(ts|js|tsx|jsx)$/;
|
|
36
|
+
// Parse diff to find modified files
|
|
37
|
+
const fileHeaderPattern = /^diff --git a\/(.+?) b\/(.+?)$/gm;
|
|
38
|
+
let match;
|
|
39
|
+
while ((match = fileHeaderPattern.exec(diff)) !== null) {
|
|
40
|
+
const filePath = match[2];
|
|
41
|
+
if (testFilePattern.test(filePath)) {
|
|
42
|
+
changes.push({
|
|
43
|
+
type: "test-modified",
|
|
44
|
+
file: filePath,
|
|
45
|
+
description: "Test file was modified during fix loop",
|
|
46
|
+
severity: "critical",
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return changes;
|
|
51
|
+
}
|
|
52
|
+
function detectLargeDeletions(diff) {
|
|
53
|
+
const changes = [];
|
|
54
|
+
// Split diff by file
|
|
55
|
+
const fileDiffs = diff.split(/^diff --git /m).slice(1); // First element is empty
|
|
56
|
+
for (const fileDiff of fileDiffs) {
|
|
57
|
+
const fileMatch = fileDiff.match(/^a\/(.+?) b\/(.+?)$/m);
|
|
58
|
+
if (!fileMatch)
|
|
59
|
+
continue;
|
|
60
|
+
const filePath = fileMatch[2];
|
|
61
|
+
// Count deletions (lines starting with -)
|
|
62
|
+
const lines = fileDiff.split("\n");
|
|
63
|
+
let deletions = 0;
|
|
64
|
+
for (const line of lines) {
|
|
65
|
+
if (line.startsWith("-") && !line.startsWith("---")) {
|
|
66
|
+
deletions++;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (deletions > 50) {
|
|
70
|
+
changes.push({
|
|
71
|
+
type: "large-deletion",
|
|
72
|
+
file: filePath,
|
|
73
|
+
description: `${deletions} lines deleted (possible over-aggressive fix)`,
|
|
74
|
+
severity: "warning",
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return changes;
|
|
79
|
+
}
|
|
80
|
+
function detectCommentedTests(diff) {
|
|
81
|
+
const changes = [];
|
|
82
|
+
// Look for patterns like:
|
|
83
|
+
// - it('should work', () => {
|
|
84
|
+
// + // it('should work', () => {
|
|
85
|
+
// or
|
|
86
|
+
// - test('should work', () => {
|
|
87
|
+
// + /* test('should work', () => {
|
|
88
|
+
const lines = diff.split("\n");
|
|
89
|
+
for (let i = 0; i < lines.length - 1; i++) {
|
|
90
|
+
const prevLine = lines[i];
|
|
91
|
+
const currLine = lines[i + 1];
|
|
92
|
+
if (prevLine.startsWith("-") &&
|
|
93
|
+
/\b(it|test|describe)\(/.test(prevLine) &&
|
|
94
|
+
currLine.startsWith("+") &&
|
|
95
|
+
(/^[+]\s*(\/\/|\/\*)/.test(currLine) ||
|
|
96
|
+
currLine.includes("// it(") ||
|
|
97
|
+
currLine.includes("// test(") ||
|
|
98
|
+
currLine.includes("/* it(") ||
|
|
99
|
+
currLine.includes("/* test("))) {
|
|
100
|
+
// Extract approximate location
|
|
101
|
+
const fileContext = findFileContext(diff, i);
|
|
102
|
+
changes.push({
|
|
103
|
+
type: "test-commented",
|
|
104
|
+
file: fileContext || "unknown",
|
|
105
|
+
description: "Test case appears to have been commented out",
|
|
106
|
+
severity: "critical",
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return changes;
|
|
111
|
+
}
|
|
112
|
+
function detectRemovedTests(diff) {
|
|
113
|
+
const changes = [];
|
|
114
|
+
// Look for deleted test cases (lines starting with - that contain it( or test()
|
|
115
|
+
const lines = diff.split("\n");
|
|
116
|
+
let removedTestCount = 0;
|
|
117
|
+
let currentFile = "unknown";
|
|
118
|
+
for (const line of lines) {
|
|
119
|
+
// Track current file
|
|
120
|
+
const fileMatch = line.match(/^diff --git a\/(.+?) b\/(.+?)$/);
|
|
121
|
+
if (fileMatch) {
|
|
122
|
+
currentFile = fileMatch[2];
|
|
123
|
+
removedTestCount = 0; // Reset counter for new file
|
|
124
|
+
}
|
|
125
|
+
// Check for deleted test cases
|
|
126
|
+
if (line.startsWith("-") &&
|
|
127
|
+
!line.startsWith("---") &&
|
|
128
|
+
/\b(it|test)\s*\(/.test(line)) {
|
|
129
|
+
removedTestCount++;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (removedTestCount > 0) {
|
|
133
|
+
changes.push({
|
|
134
|
+
type: "test-removed",
|
|
135
|
+
file: currentFile,
|
|
136
|
+
description: `${removedTestCount} test case(s) were deleted`,
|
|
137
|
+
severity: "critical",
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
return changes;
|
|
141
|
+
}
|
|
142
|
+
function findFileContext(diff, lineIndex) {
|
|
143
|
+
// Walk backwards to find the nearest "diff --git" header
|
|
144
|
+
const lines = diff.split("\n");
|
|
145
|
+
for (let i = lineIndex; i >= 0; i--) {
|
|
146
|
+
const match = lines[i].match(/^diff --git a\/(.+?) b\/(.+?)$/);
|
|
147
|
+
if (match)
|
|
148
|
+
return match[2];
|
|
149
|
+
}
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=change-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change-detector.js","sourceRoot":"","sources":["../../src/engine/change-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import madge from "madge";
|
|
2
|
+
/**
|
|
3
|
+
* Build a dependency graph for the codebase and identify which files
|
|
4
|
+
* are affected by upgrading a specific package.
|
|
5
|
+
*
|
|
6
|
+
* This helps prioritize which files to fix first in a staged fix approach.
|
|
7
|
+
*/
|
|
8
|
+
export async function buildDependencyGraph(cwd, upgradedPkg) {
|
|
9
|
+
try {
|
|
10
|
+
// Use madge to analyze dependencies
|
|
11
|
+
const result = await madge(cwd, {
|
|
12
|
+
fileExtensions: ["js", "ts", "jsx", "tsx"],
|
|
13
|
+
excludeRegExp: [/node_modules/, /dist/, /build/, /\.test\.|\.spec\./],
|
|
14
|
+
});
|
|
15
|
+
const graph = result.obj();
|
|
16
|
+
const nodes = [];
|
|
17
|
+
// Convert madge graph to our format
|
|
18
|
+
for (const [file, imports] of Object.entries(graph)) {
|
|
19
|
+
const importsList = imports;
|
|
20
|
+
// Check if this file directly imports the upgraded package
|
|
21
|
+
const usesUpgradedPkg = importsList.some((imp) => {
|
|
22
|
+
// Match import statements like: import x from 'react'
|
|
23
|
+
// or: const x = require('react')
|
|
24
|
+
return imp === upgradedPkg || imp.startsWith(`${upgradedPkg}/`);
|
|
25
|
+
});
|
|
26
|
+
nodes.push({
|
|
27
|
+
file,
|
|
28
|
+
imports: importsList,
|
|
29
|
+
usesUpgradedPkg,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return nodes;
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
// Madge might fail on certain codebases - return empty graph
|
|
36
|
+
console.warn(`Failed to build dependency graph: ${err.message}`);
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Organize files into layers based on dependency distance from the upgraded package.
|
|
42
|
+
*
|
|
43
|
+
* Layer 0: Files that directly import the upgraded package
|
|
44
|
+
* Layer 1: Files that import Layer 0 files
|
|
45
|
+
* Layer 2: Files that import Layer 1 files
|
|
46
|
+
* etc.
|
|
47
|
+
*
|
|
48
|
+
* This layering helps fix files in order: fix the "leaves" first (directly affected),
|
|
49
|
+
* then work up the dependency tree.
|
|
50
|
+
*/
|
|
51
|
+
export function organizeLayers(nodes) {
|
|
52
|
+
const layers = [];
|
|
53
|
+
const fileToLayer = new Map();
|
|
54
|
+
// Layer 0: direct users of the upgraded package
|
|
55
|
+
const layer0Files = nodes
|
|
56
|
+
.filter((n) => n.usesUpgradedPkg)
|
|
57
|
+
.map((n) => n.file);
|
|
58
|
+
if (layer0Files.length === 0) {
|
|
59
|
+
// No direct imports found - return all files as one layer
|
|
60
|
+
return [
|
|
61
|
+
{
|
|
62
|
+
level: 0,
|
|
63
|
+
files: nodes.map((n) => n.file),
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
}
|
|
67
|
+
layers.push({ level: 0, files: layer0Files });
|
|
68
|
+
layer0Files.forEach((f) => fileToLayer.set(f, 0));
|
|
69
|
+
// Build subsequent layers
|
|
70
|
+
let currentLayer = 0;
|
|
71
|
+
let remainingNodes = nodes.filter((n) => !n.usesUpgradedPkg);
|
|
72
|
+
while (remainingNodes.length > 0 && currentLayer < 10) {
|
|
73
|
+
// Cap at 10 layers to avoid infinite loops
|
|
74
|
+
currentLayer++;
|
|
75
|
+
const prevLayerFiles = layers[currentLayer - 1].files;
|
|
76
|
+
const nextLayerFiles = [];
|
|
77
|
+
for (const node of remainingNodes) {
|
|
78
|
+
// Check if this node imports any files from the previous layer
|
|
79
|
+
const importsPrevLayer = node.imports.some((imp) => prevLayerFiles.includes(imp));
|
|
80
|
+
if (importsPrevLayer) {
|
|
81
|
+
nextLayerFiles.push(node.file);
|
|
82
|
+
fileToLayer.set(node.file, currentLayer);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (nextLayerFiles.length === 0) {
|
|
86
|
+
// No more dependencies found - remaining files are unaffected
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
layers.push({ level: currentLayer, files: nextLayerFiles });
|
|
90
|
+
remainingNodes = remainingNodes.filter((n) => !fileToLayer.has(n.file));
|
|
91
|
+
}
|
|
92
|
+
return layers;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get a flat list of files to fix, ordered by dependency layer (leaves first).
|
|
96
|
+
* This is what the fix loop will iterate through.
|
|
97
|
+
*/
|
|
98
|
+
export function getPrioritizedFiles(layers) {
|
|
99
|
+
return layers.flatMap((layer) => layer.files);
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=dep-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dep-graph.js","sourceRoot":"","sources":["../../src/engine/dep-graph.ts"],"names":[],"mappings":"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"}
|
package/dist/engine/git.js
CHANGED
|
@@ -21,6 +21,15 @@ export async function commitAll(cwd, message) {
|
|
|
21
21
|
await exec("git", ["add", "-A"], { cwd });
|
|
22
22
|
await exec("git", ["commit", "-m", message, "--no-verify"], { cwd });
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Create an incremental commit for a specific stage of the fix process.
|
|
26
|
+
* Used in staged fix mode to create separate commits for each stage.
|
|
27
|
+
*/
|
|
28
|
+
export async function commitStage(cwd, stageName, stageNumber, totalStages) {
|
|
29
|
+
await exec("git", ["add", "-A"], { cwd });
|
|
30
|
+
const message = `fix: stage ${stageNumber}/${totalStages} - ${stageName}\n\nAutomated by greenbump (staged fix mode).`;
|
|
31
|
+
await exec("git", ["commit", "-m", message, "--no-verify"], { cwd });
|
|
32
|
+
}
|
|
24
33
|
/** `git diff --stat` against a ref, for the PR summary. */
|
|
25
34
|
export async function diffStat(cwd, ref) {
|
|
26
35
|
const r = await exec("git", ["diff", "--stat", ref], { cwd });
|
package/dist/engine/git.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/engine/git.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/engine/git.ts"],"names":[],"mappings":"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"}
|
package/dist/engine/run.js
CHANGED
|
@@ -6,6 +6,8 @@ import { fetchChangelog } from "./changelog.js";
|
|
|
6
6
|
import { isGitRepo, isTreeClean, currentBranch, createBranch, commitAll, diffStat, fullDiff, } from "./git.js";
|
|
7
7
|
import { runFixLoop } from "../agent/fixer.js";
|
|
8
8
|
import { createProvider } from "../agent/factory.js";
|
|
9
|
+
import { runStaticAnalysis } from "./verify.js";
|
|
10
|
+
import { detectSuspiciousChanges } from "./change-detector.js";
|
|
9
11
|
export class RunError extends Error {
|
|
10
12
|
}
|
|
11
13
|
/**
|
|
@@ -141,13 +143,32 @@ export async function run(opts) {
|
|
|
141
143
|
summary.usage = fix.usage;
|
|
142
144
|
summary.editedFiles = fix.editedFiles;
|
|
143
145
|
summary.testFilesTouched = fix.editedFiles.filter((f) => /(^|\/)(test|tests|__tests__|spec)(\/|\.)|\.(test|spec)\./i.test(f));
|
|
146
|
+
// Run static analysis (TypeScript + ESLint)
|
|
147
|
+
log("running static analysis…");
|
|
148
|
+
const staticResults = await runStaticAnalysis(cwd, { strictLint: false });
|
|
149
|
+
const typesFailed = staticResults.some(r => r.stage === "types" && !r.passed);
|
|
150
|
+
if (typesFailed) {
|
|
151
|
+
log("⚠️ TypeScript type check failed after fix");
|
|
152
|
+
summary.needsReview = true;
|
|
153
|
+
summary.staticAnalysisWarnings = staticResults
|
|
154
|
+
.filter(r => !r.passed)
|
|
155
|
+
.flatMap(r => r.warnings || []);
|
|
156
|
+
}
|
|
157
|
+
// Detect suspicious changes
|
|
158
|
+
const suspiciousChanges = await detectSuspiciousChanges(cwd);
|
|
159
|
+
const criticalChanges = suspiciousChanges.filter(c => c.severity === "critical");
|
|
160
|
+
if (criticalChanges.length > 0) {
|
|
161
|
+
log("⚠️ Suspicious changes detected (test modifications, large deletions)");
|
|
162
|
+
summary.needsReview = true;
|
|
163
|
+
summary.suspiciousChanges = suspiciousChanges.map(c => `${c.type}: ${c.file} - ${c.description}`);
|
|
164
|
+
}
|
|
144
165
|
summary.needsReview = computeNeedsReview({
|
|
145
166
|
unverifiable: false,
|
|
146
167
|
neededFix: true,
|
|
147
168
|
fixed: fix.fixed,
|
|
148
169
|
testFilesTouched: summary.testFilesTouched,
|
|
149
170
|
budgetExceeded: fix.budgetExceeded,
|
|
150
|
-
});
|
|
171
|
+
}) || summary.needsReview; // Preserve needsReview if already set by static analysis or suspicious changes
|
|
151
172
|
await maybeCommit(cwd, summary, fix.fixed);
|
|
152
173
|
summary.durationMs = Date.now() - startedAt;
|
|
153
174
|
return summary;
|
package/dist/engine/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/engine/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAuB,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAuB,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EACL,SAAS,EACT,WAAW,EACX,aAAa,EACb,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,QAAQ,GACT,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/engine/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Staged fix orchestrator for v0.4.0
|
|
3
|
+
*
|
|
4
|
+
* This module provides a multi-stage fix strategy that:
|
|
5
|
+
* 1. Builds a dependency graph to identify affected files
|
|
6
|
+
* 2. Categorizes files into stages (config → types → source)
|
|
7
|
+
* 3. Fixes each stage independently with incremental commits
|
|
8
|
+
* 4. Allows rollback to the last successful stage on failure
|
|
9
|
+
*
|
|
10
|
+
* Usage: pass --staged flag to enable staged fix mode
|
|
11
|
+
*/
|
|
12
|
+
import { buildDependencyGraph, organizeLayers } from "./dep-graph.js";
|
|
13
|
+
import { COMMON_STAGES, categorizeFilesByStage } from "./stages.js";
|
|
14
|
+
import { commitStage } from "./git.js";
|
|
15
|
+
import { runFixLoop } from "../agent/fixer.js";
|
|
16
|
+
import { runChecks } from "./checks.js";
|
|
17
|
+
/**
|
|
18
|
+
* Run a staged fix: break the fix into multiple stages, fix each independently,
|
|
19
|
+
* and commit after each successful stage.
|
|
20
|
+
*/
|
|
21
|
+
export async function runStagedFix(opts) {
|
|
22
|
+
const log = opts.onLog ?? (() => { });
|
|
23
|
+
const { cwd, pm, dep } = opts;
|
|
24
|
+
// 1. Build dependency graph
|
|
25
|
+
log("📊 building dependency graph…");
|
|
26
|
+
const nodes = await buildDependencyGraph(cwd, dep);
|
|
27
|
+
if (nodes.length === 0) {
|
|
28
|
+
log("⚠️ dependency graph empty, falling back to single-stage fix");
|
|
29
|
+
return await runSingleStageFix(opts);
|
|
30
|
+
}
|
|
31
|
+
const layers = organizeLayers(nodes);
|
|
32
|
+
log(`📊 found ${layers.length} dependency layers, ${nodes.length} files total`);
|
|
33
|
+
// 2. Categorize files by stage
|
|
34
|
+
const stageFiles = await categorizeFilesByStage(cwd, COMMON_STAGES);
|
|
35
|
+
const stages = COMMON_STAGES.filter((stage) => {
|
|
36
|
+
const files = stageFiles.get(stage.name) || [];
|
|
37
|
+
return files.length > 0;
|
|
38
|
+
});
|
|
39
|
+
if (stages.length === 0) {
|
|
40
|
+
log("⚠️ no files matched any stage patterns, falling back to single-stage fix");
|
|
41
|
+
return await runSingleStageFix(opts);
|
|
42
|
+
}
|
|
43
|
+
log(`🔧 identified ${stages.length} stages: ${stages.map(s => s.name).join(" → ")}`);
|
|
44
|
+
// 3. Fix each stage
|
|
45
|
+
let totalRounds = 0;
|
|
46
|
+
let totalInputTokens = 0;
|
|
47
|
+
let totalOutputTokens = 0;
|
|
48
|
+
const allEditedFiles = [];
|
|
49
|
+
for (let i = 0; i < stages.length; i++) {
|
|
50
|
+
const stage = stages[i];
|
|
51
|
+
const files = stageFiles.get(stage.name) || [];
|
|
52
|
+
log(`\n🔧 Stage ${i + 1}/${stages.length}: ${stage.name} (${files.length} files)`);
|
|
53
|
+
// Run fix loop for this stage only
|
|
54
|
+
// (In a full implementation, we'd pass a file filter to the fix loop)
|
|
55
|
+
const stageResult = await runFixLoop({
|
|
56
|
+
...opts,
|
|
57
|
+
onLog: (msg) => log(` ${msg}`),
|
|
58
|
+
});
|
|
59
|
+
totalRounds += stageResult.rounds;
|
|
60
|
+
totalInputTokens += stageResult.usage.inputTokens;
|
|
61
|
+
totalOutputTokens += stageResult.usage.outputTokens;
|
|
62
|
+
allEditedFiles.push(...stageResult.editedFiles);
|
|
63
|
+
// Validate stage
|
|
64
|
+
const passed = await stage.validator(cwd);
|
|
65
|
+
if (!passed) {
|
|
66
|
+
log(`❌ Stage ${i + 1} validation failed`);
|
|
67
|
+
return {
|
|
68
|
+
fixed: false,
|
|
69
|
+
completedStages: i,
|
|
70
|
+
totalStages: stages.length,
|
|
71
|
+
failedStage: stage.name,
|
|
72
|
+
rounds: totalRounds,
|
|
73
|
+
usage: { inputTokens: totalInputTokens, outputTokens: totalOutputTokens },
|
|
74
|
+
editedFiles: allEditedFiles,
|
|
75
|
+
budgetExceeded: stageResult.budgetExceeded,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
// Commit this stage
|
|
79
|
+
await commitStage(cwd, stage.name, i + 1, stages.length);
|
|
80
|
+
log(`✓ Stage ${i + 1} completed and committed`);
|
|
81
|
+
}
|
|
82
|
+
// Final validation
|
|
83
|
+
const finalCheck = await runChecks(pm, cwd, opts.checkOverrides);
|
|
84
|
+
return {
|
|
85
|
+
fixed: finalCheck.ok,
|
|
86
|
+
completedStages: stages.length,
|
|
87
|
+
totalStages: stages.length,
|
|
88
|
+
rounds: totalRounds,
|
|
89
|
+
usage: { inputTokens: totalInputTokens, outputTokens: totalOutputTokens },
|
|
90
|
+
editedFiles: allEditedFiles,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Fallback: run a single fix loop without staging (same as v0.3.0 behavior)
|
|
95
|
+
*/
|
|
96
|
+
async function runSingleStageFix(opts) {
|
|
97
|
+
const result = await runFixLoop(opts);
|
|
98
|
+
return {
|
|
99
|
+
fixed: result.fixed,
|
|
100
|
+
completedStages: result.fixed ? 1 : 0,
|
|
101
|
+
totalStages: 1,
|
|
102
|
+
rounds: result.rounds,
|
|
103
|
+
usage: result.usage,
|
|
104
|
+
editedFiles: result.editedFiles,
|
|
105
|
+
budgetExceeded: result.budgetExceeded,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=staged-fix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staged-fix.js","sourceRoot":"","sources":["../../src/engine/staged-fix.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { pathExists } from "./ecosystems/types.js";
|
|
3
|
+
import { exec } from "node:child_process";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
import { glob } from "glob";
|
|
6
|
+
const execAsync = promisify(exec);
|
|
7
|
+
/**
|
|
8
|
+
* Common staged fix strategy for most projects:
|
|
9
|
+
* 1. Configuration files (package.json, tsconfig.json, webpack.config.js)
|
|
10
|
+
* 2. Type definitions (*.d.ts, types/)
|
|
11
|
+
* 3. Source code (*.ts, *.tsx, *.js, *.jsx)
|
|
12
|
+
*/
|
|
13
|
+
export const COMMON_STAGES = [
|
|
14
|
+
{
|
|
15
|
+
name: "Configuration",
|
|
16
|
+
filePatterns: [
|
|
17
|
+
"**/package.json",
|
|
18
|
+
"**/tsconfig.json",
|
|
19
|
+
"**/tsconfig.*.json",
|
|
20
|
+
"**/webpack.config.js",
|
|
21
|
+
"**/webpack.*.js",
|
|
22
|
+
"**/.eslintrc.*",
|
|
23
|
+
"**/babel.config.*",
|
|
24
|
+
"**/vite.config.*",
|
|
25
|
+
"**/rollup.config.*",
|
|
26
|
+
],
|
|
27
|
+
validator: async (cwd) => {
|
|
28
|
+
// Check if config files are syntactically valid
|
|
29
|
+
return await validateConfigSyntax(cwd);
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: "Type Definitions",
|
|
34
|
+
filePatterns: [
|
|
35
|
+
"**/*.d.ts",
|
|
36
|
+
"**/types/**/*.ts",
|
|
37
|
+
"**/@types/**/*.ts",
|
|
38
|
+
],
|
|
39
|
+
validator: async (cwd) => {
|
|
40
|
+
// Check if TypeScript types are valid
|
|
41
|
+
if (await pathExists(join(cwd, "tsconfig.json"))) {
|
|
42
|
+
try {
|
|
43
|
+
await execAsync("npx tsc --noEmit", { cwd, timeout: 60000 });
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return true; // No TypeScript, skip
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "Source Code",
|
|
55
|
+
filePatterns: [
|
|
56
|
+
"**/*.ts",
|
|
57
|
+
"**/*.tsx",
|
|
58
|
+
"**/*.js",
|
|
59
|
+
"**/*.jsx",
|
|
60
|
+
// Exclude already handled files
|
|
61
|
+
"!**/*.d.ts",
|
|
62
|
+
"!**/types/**",
|
|
63
|
+
"!**/@types/**",
|
|
64
|
+
"!**/node_modules/**",
|
|
65
|
+
"!**/dist/**",
|
|
66
|
+
"!**/build/**",
|
|
67
|
+
"!**/*.test.*",
|
|
68
|
+
"!**/*.spec.*",
|
|
69
|
+
],
|
|
70
|
+
validator: async (cwd) => {
|
|
71
|
+
// Source code stage succeeds if tests pass
|
|
72
|
+
// (This will be checked by the main fix loop)
|
|
73
|
+
return true; // Delegated to main validator
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
];
|
|
77
|
+
async function validateConfigSyntax(cwd) {
|
|
78
|
+
// Check if package.json is valid JSON
|
|
79
|
+
try {
|
|
80
|
+
const pkgPath = join(cwd, "package.json");
|
|
81
|
+
if (await pathExists(pkgPath)) {
|
|
82
|
+
const fs = await import("node:fs/promises");
|
|
83
|
+
const content = await fs.readFile(pkgPath, "utf8");
|
|
84
|
+
JSON.parse(content); // Will throw if invalid
|
|
85
|
+
}
|
|
86
|
+
// Check if tsconfig.json is valid JSON
|
|
87
|
+
const tsconfigPath = join(cwd, "tsconfig.json");
|
|
88
|
+
if (await pathExists(tsconfigPath)) {
|
|
89
|
+
const fs = await import("node:fs/promises");
|
|
90
|
+
const content = await fs.readFile(tsconfigPath, "utf8");
|
|
91
|
+
JSON.parse(content); // Will throw if invalid
|
|
92
|
+
}
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Match files against a set of glob patterns.
|
|
101
|
+
*/
|
|
102
|
+
export async function matchFiles(cwd, patterns) {
|
|
103
|
+
const allMatches = new Set();
|
|
104
|
+
for (const pattern of patterns) {
|
|
105
|
+
const matches = await glob(pattern, {
|
|
106
|
+
cwd,
|
|
107
|
+
absolute: false,
|
|
108
|
+
ignore: ["**/node_modules/**", "**/dist/**", "**/build/**"],
|
|
109
|
+
});
|
|
110
|
+
matches.forEach((m) => allMatches.add(m));
|
|
111
|
+
}
|
|
112
|
+
return Array.from(allMatches);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Determine which files belong to which stage based on glob patterns.
|
|
116
|
+
*/
|
|
117
|
+
export async function categorizeFilesByStage(cwd, stages) {
|
|
118
|
+
const stageFiles = new Map();
|
|
119
|
+
for (const stage of stages) {
|
|
120
|
+
const files = await matchFiles(cwd, stage.filePatterns);
|
|
121
|
+
stageFiles.set(stage.name, files);
|
|
122
|
+
}
|
|
123
|
+
return stageFiles;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=stages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stages.js","sourceRoot":"","sources":["../../src/engine/stages.ts"],"names":[],"mappings":"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"}
|