greenbump 0.4.0 → 0.6.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/README.md +673 -66
- package/README.zh-CN.md +525 -100
- package/dist/agent/fixer.js +161 -12
- package/dist/agent/fixer.js.map +1 -1
- package/dist/agent/fixer.test.js +410 -0
- package/dist/agent/fixer.test.js.map +1 -0
- package/dist/cli/interactive.js +81 -0
- package/dist/cli/interactive.js.map +1 -0
- package/dist/cli.js +53 -0
- package/dist/cli.js.map +1 -1
- package/dist/engine/analyzers/changelog-parser.js +121 -0
- package/dist/engine/analyzers/changelog-parser.js.map +1 -0
- package/dist/engine/batch.test.js +59 -0
- package/dist/engine/batch.test.js.map +1 -0
- package/dist/engine/cache/manager.js +165 -0
- package/dist/engine/cache/manager.js.map +1 -0
- package/dist/engine/cache/manager.test.js +75 -0
- package/dist/engine/cache/manager.test.js.map +1 -0
- package/dist/engine/checks.test.js +92 -0
- package/dist/engine/checks.test.js.map +1 -0
- package/dist/engine/context/optimizer.js +189 -0
- package/dist/engine/context/optimizer.js.map +1 -0
- package/dist/engine/context/optimizer.test.js +81 -0
- package/dist/engine/context/optimizer.test.js.map +1 -0
- package/dist/engine/ecosystems/parsers.test.js +255 -0
- package/dist/engine/ecosystems/parsers.test.js.map +1 -0
- package/dist/engine/fixer/patterns.js +356 -0
- package/dist/engine/fixer/patterns.js.map +1 -0
- package/dist/engine/fixer/patterns.test.js +124 -0
- package/dist/engine/fixer/patterns.test.js.map +1 -0
- package/dist/engine/git.js +1 -0
- package/dist/engine/git.js.map +1 -1
- package/dist/engine/git.test.js +111 -0
- package/dist/engine/git.test.js.map +1 -0
- package/dist/engine/perf/metrics.js +171 -0
- package/dist/engine/perf/metrics.js.map +1 -0
- package/dist/engine/perf/regression.js +115 -0
- package/dist/engine/perf/regression.js.map +1 -0
- package/dist/engine/run.js +93 -2
- package/dist/engine/run.js.map +1 -1
- package/dist/engine/run.test.js +47 -0
- package/dist/engine/run.test.js.map +1 -0
- package/dist/engine/sandbox/docker-manager.js +215 -0
- package/dist/engine/sandbox/docker-manager.js.map +1 -0
- package/dist/engine/sandbox/orchestrator.js +107 -0
- package/dist/engine/sandbox/orchestrator.js.map +1 -0
- package/dist/engine/sandbox/service-detector.js +147 -0
- package/dist/engine/sandbox/service-detector.js.map +1 -0
- package/dist/engine/sandbox/template-generator.js +241 -0
- package/dist/engine/sandbox/template-generator.js.map +1 -0
- package/dist/engine/verifiers/ast-analyzer.js +212 -0
- package/dist/engine/verifiers/ast-analyzer.js.map +1 -0
- package/dist/engine/verifiers/ast-analyzer.test.js +96 -0
- package/dist/engine/verifiers/ast-analyzer.test.js.map +1 -0
- package/dist/engine/workspace.test.js +95 -0
- package/dist/engine/workspace.test.js.map +1 -0
- package/dist/exitcode.test.js +62 -0
- package/dist/exitcode.test.js.map +1 -0
- package/dist/format.js +15 -0
- package/dist/format.js.map +1 -1
- package/dist/report.test.js +56 -0
- package/dist/report.test.js.map +1 -0
- package/package.json +7 -4
- package/CHANGELOG.md +0 -93
- package/CONTRIBUTING.md +0 -52
- package/SECURITY.md +0 -38
- package/action-dist/index.cjs +0 -19935
- package/action.yml +0 -76
- package/competitive-analysis.md +0 -304
- package/examples/greenbump.yml +0 -37
- package/examples/legacy-repo/package.json +0 -12
- package/examples/legacy-repo/test.js +0 -17
- package/examples/multi-file-repo/models/todo.js +0 -8
- package/examples/multi-file-repo/models/user.js +0 -11
- package/examples/multi-file-repo/package.json +0 -12
- package/examples/multi-file-repo/services/session.js +0 -9
- package/examples/multi-file-repo/test.js +0 -19
- package/optimization-roadmap.md +0 -772
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { test } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { withTmpDir } from "../test-utils.js";
|
|
6
|
+
import { detectWorkspaceMembers, resolveWorkspaceTarget, WorkspaceAmbiguityError, WORKSPACE_ROOT, } from "./workspace.js";
|
|
7
|
+
async function writeJson(path, data) {
|
|
8
|
+
await writeFile(path, JSON.stringify(data), "utf8");
|
|
9
|
+
}
|
|
10
|
+
test("detectWorkspaceMembers: non-workspace repo returns []", async () => {
|
|
11
|
+
await withTmpDir(async (dir) => {
|
|
12
|
+
await writeJson(join(dir, "package.json"), { name: "solo" });
|
|
13
|
+
assert.deepEqual(await detectWorkspaceMembers(dir), []);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
test("detectWorkspaceMembers: npm/yarn `workspaces` array field", async () => {
|
|
17
|
+
await withTmpDir(async (dir) => {
|
|
18
|
+
await writeJson(join(dir, "package.json"), { name: "root", workspaces: ["packages/*"] });
|
|
19
|
+
await mkdir(join(dir, "packages", "api"), { recursive: true });
|
|
20
|
+
await mkdir(join(dir, "packages", "web"), { recursive: true });
|
|
21
|
+
await writeJson(join(dir, "packages", "api", "package.json"), { name: "@x/api" });
|
|
22
|
+
await writeJson(join(dir, "packages", "web", "package.json"), { name: "@x/web" });
|
|
23
|
+
const members = await detectWorkspaceMembers(dir);
|
|
24
|
+
const names = members.map((m) => m.name).sort();
|
|
25
|
+
const paths = members.map((m) => m.path).sort();
|
|
26
|
+
assert.deepEqual(names, ["@x/api", "@x/web"]);
|
|
27
|
+
assert.deepEqual(paths, ["packages/api", "packages/web"]);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
test("detectWorkspaceMembers: npm `workspaces.packages` object form", async () => {
|
|
31
|
+
await withTmpDir(async (dir) => {
|
|
32
|
+
await writeJson(join(dir, "package.json"), { name: "root", workspaces: { packages: ["apps/*"] } });
|
|
33
|
+
await mkdir(join(dir, "apps", "cli"), { recursive: true });
|
|
34
|
+
await writeJson(join(dir, "apps", "cli", "package.json"), { name: "cli" });
|
|
35
|
+
const members = await detectWorkspaceMembers(dir);
|
|
36
|
+
assert.deepEqual(members, [{ path: "apps/cli", name: "cli" }]);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
test("detectWorkspaceMembers: pnpm-workspace.yaml", async () => {
|
|
40
|
+
await withTmpDir(async (dir) => {
|
|
41
|
+
await writeJson(join(dir, "package.json"), { name: "root" });
|
|
42
|
+
await writeFile(join(dir, "pnpm-workspace.yaml"), 'packages:\n - "packages/*"\n - "tools/*"\n', "utf8");
|
|
43
|
+
await mkdir(join(dir, "packages", "core"), { recursive: true });
|
|
44
|
+
await mkdir(join(dir, "tools", "gen"), { recursive: true });
|
|
45
|
+
await writeJson(join(dir, "packages", "core", "package.json"), { name: "core" });
|
|
46
|
+
await writeJson(join(dir, "tools", "gen", "package.json"), { name: "gen" });
|
|
47
|
+
const members = await detectWorkspaceMembers(dir);
|
|
48
|
+
const paths = members.map((m) => m.path).sort();
|
|
49
|
+
assert.deepEqual(paths, ["packages/core", "tools/gen"]);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
test("detectWorkspaceMembers: glob directories without a package.json are skipped", async () => {
|
|
53
|
+
await withTmpDir(async (dir) => {
|
|
54
|
+
await writeJson(join(dir, "package.json"), { name: "root", workspaces: ["packages/*"] });
|
|
55
|
+
await mkdir(join(dir, "packages", "empty-scaffold"), { recursive: true });
|
|
56
|
+
// no package.json inside "empty-scaffold"
|
|
57
|
+
assert.deepEqual(await detectWorkspaceMembers(dir), []);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
function outdated(name, current, latest, workspacePath) {
|
|
61
|
+
return { name, current, wanted: "", latest, workspacePath };
|
|
62
|
+
}
|
|
63
|
+
test("resolveWorkspaceTarget: unambiguous single match resolves directly", () => {
|
|
64
|
+
const candidates = [outdated("lodash", "4.17.20", "4.17.21", WORKSPACE_ROOT)];
|
|
65
|
+
const result = resolveWorkspaceTarget("lodash", candidates);
|
|
66
|
+
assert.equal(result?.workspacePath, WORKSPACE_ROOT);
|
|
67
|
+
});
|
|
68
|
+
test("resolveWorkspaceTarget: same version across packages is not ambiguous", () => {
|
|
69
|
+
const candidates = [
|
|
70
|
+
outdated("lodash", "4.17.20", "4.17.21", "packages/api"),
|
|
71
|
+
outdated("lodash", "4.17.20", "4.17.21", "packages/web"),
|
|
72
|
+
];
|
|
73
|
+
// Same current version everywhere — no real ambiguity, first match wins.
|
|
74
|
+
assert.doesNotThrow(() => resolveWorkspaceTarget("lodash", candidates));
|
|
75
|
+
});
|
|
76
|
+
test("resolveWorkspaceTarget: different versions across packages throws WorkspaceAmbiguityError", () => {
|
|
77
|
+
const candidates = [
|
|
78
|
+
outdated("lodash", "4.17.15", "4.17.21", "packages/api"),
|
|
79
|
+
outdated("lodash", "4.17.20", "4.17.21", "packages/web"),
|
|
80
|
+
];
|
|
81
|
+
assert.throws(() => resolveWorkspaceTarget("lodash", candidates), WorkspaceAmbiguityError);
|
|
82
|
+
});
|
|
83
|
+
test("resolveWorkspaceTarget: --workspace disambiguates an otherwise-ambiguous name", () => {
|
|
84
|
+
const candidates = [
|
|
85
|
+
outdated("lodash", "4.17.15", "4.17.21", "packages/api"),
|
|
86
|
+
outdated("lodash", "4.17.20", "4.17.21", "packages/web"),
|
|
87
|
+
];
|
|
88
|
+
const result = resolveWorkspaceTarget("lodash", candidates, "packages/web");
|
|
89
|
+
assert.equal(result?.current, "4.17.20");
|
|
90
|
+
});
|
|
91
|
+
test("resolveWorkspaceTarget: no match returns undefined", () => {
|
|
92
|
+
const candidates = [outdated("lodash", "4.17.20", "4.17.21", WORKSPACE_ROOT)];
|
|
93
|
+
assert.equal(resolveWorkspaceTarget("react", candidates), undefined);
|
|
94
|
+
});
|
|
95
|
+
//# sourceMappingURL=workspace.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.test.js","sourceRoot":"","sources":["../../src/engine/workspace.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { test } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { exitCodeFor, overallExitCode } from "./exitcode.js";
|
|
4
|
+
function summary(overrides) {
|
|
5
|
+
return {
|
|
6
|
+
dep: "lodash",
|
|
7
|
+
from: "4.17.20",
|
|
8
|
+
to: "4.17.21",
|
|
9
|
+
packageManager: "npm",
|
|
10
|
+
baselineGreen: true,
|
|
11
|
+
neededFix: false,
|
|
12
|
+
fixed: true,
|
|
13
|
+
unverifiable: false,
|
|
14
|
+
needsReview: false,
|
|
15
|
+
committed: true,
|
|
16
|
+
rounds: 0,
|
|
17
|
+
usage: { inputTokens: 0, outputTokens: 0 },
|
|
18
|
+
editedFiles: [],
|
|
19
|
+
testFilesTouched: [],
|
|
20
|
+
durationMs: 0,
|
|
21
|
+
...overrides,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
test("exitCodeFor: clean success is 0", () => {
|
|
25
|
+
assert.equal(exitCodeFor(summary({})), 0);
|
|
26
|
+
});
|
|
27
|
+
test("exitCodeFor: unfixed after a fix attempt is 2", () => {
|
|
28
|
+
assert.equal(exitCodeFor(summary({ neededFix: true, fixed: false })), 2);
|
|
29
|
+
});
|
|
30
|
+
test("exitCodeFor: needsReview (test file touched) is 3", () => {
|
|
31
|
+
assert.equal(exitCodeFor(summary({ neededFix: true, fixed: true, needsReview: true })), 3);
|
|
32
|
+
});
|
|
33
|
+
test("exitCodeFor: needsReview from unverifiable is 3", () => {
|
|
34
|
+
assert.equal(exitCodeFor(summary({ unverifiable: true, needsReview: true })), 3);
|
|
35
|
+
});
|
|
36
|
+
test("exitCodeFor: unfixed (2) takes priority over needsReview when both would apply", () => {
|
|
37
|
+
// neededFix && !fixed always wins — needsReview never overloads that state.
|
|
38
|
+
assert.equal(exitCodeFor(summary({ neededFix: true, fixed: false, needsReview: true })), 2);
|
|
39
|
+
});
|
|
40
|
+
test("overallExitCode: a hard failure (1) outranks everything else", () => {
|
|
41
|
+
const failure = { dep: "axios", error: "boom", fatal: true };
|
|
42
|
+
const items = [summary({}), summary({ neededFix: true, fixed: false }), failure];
|
|
43
|
+
assert.equal(overallExitCode(items), 1);
|
|
44
|
+
});
|
|
45
|
+
test("overallExitCode: unfixed (2) outranks needsReview (3) when no hard failure", () => {
|
|
46
|
+
const items = [
|
|
47
|
+
summary({ neededFix: true, fixed: true, needsReview: true }),
|
|
48
|
+
summary({ neededFix: true, fixed: false }),
|
|
49
|
+
];
|
|
50
|
+
assert.equal(overallExitCode(items), 2);
|
|
51
|
+
});
|
|
52
|
+
test("overallExitCode: needsReview (3) outranks clean success (0)", () => {
|
|
53
|
+
const items = [summary({}), summary({ unverifiable: true, needsReview: true })];
|
|
54
|
+
assert.equal(overallExitCode(items), 3);
|
|
55
|
+
});
|
|
56
|
+
test("overallExitCode: all clean is 0", () => {
|
|
57
|
+
assert.equal(overallExitCode([summary({}), summary({})]), 0);
|
|
58
|
+
});
|
|
59
|
+
test("overallExitCode: empty batch is 0", () => {
|
|
60
|
+
assert.equal(overallExitCode([]), 0);
|
|
61
|
+
});
|
|
62
|
+
//# sourceMappingURL=exitcode.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exitcode.test.js","sourceRoot":"","sources":["../src/exitcode.test.ts"],"names":[],"mappings":"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"}
|
package/dist/format.js
CHANGED
|
@@ -47,6 +47,11 @@ export function printSummaryBox(summary, write) {
|
|
|
47
47
|
if (summary.neededFix) {
|
|
48
48
|
write(bar(`${pc.dim("fix rounds")} ${summary.rounds}`));
|
|
49
49
|
write(bar(`${pc.dim("tokens")} ${summary.usage.inputTokens.toLocaleString()} in / ${summary.usage.outputTokens.toLocaleString()} out`));
|
|
50
|
+
// Show which tier fixed it — the key cost signal for v0.6.0
|
|
51
|
+
if (summary.fixedByTier && summary.fixedByTier < 4) {
|
|
52
|
+
const tierNames = ["", "codemod (free)", "learned pattern (free)", "cached fix (free)"];
|
|
53
|
+
write(bar(`${pc.dim("fixed by")} ${pc.green(tierNames[summary.fixedByTier])}`));
|
|
54
|
+
}
|
|
50
55
|
write(bar(`${pc.dim("files edited")} ${summary.editedFiles.length}`));
|
|
51
56
|
for (const f of summary.editedFiles.slice(0, 6))
|
|
52
57
|
write(bar(` ${pc.cyan("·")} ${f}`));
|
|
@@ -78,6 +83,16 @@ export function printSummaryBox(summary, write) {
|
|
|
78
83
|
write(bar(` ${pc.dim(`… +${summary.staticAnalysisWarnings.length - 3} more`)}`));
|
|
79
84
|
}
|
|
80
85
|
}
|
|
86
|
+
if (summary.apiChanges && summary.apiChanges.length > 0) {
|
|
87
|
+
write(bar(""));
|
|
88
|
+
write(bar(pc.yellow(`⚠ API surface changes (exports affected):`)));
|
|
89
|
+
for (const change of summary.apiChanges.slice(0, 5)) {
|
|
90
|
+
write(bar(` ${pc.yellow("·")} ${change}`));
|
|
91
|
+
}
|
|
92
|
+
if (summary.apiChanges.length > 5) {
|
|
93
|
+
write(bar(` ${pc.dim(`… +${summary.apiChanges.length - 5} more`)}`));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
81
96
|
}
|
|
82
97
|
if (summary.branch) {
|
|
83
98
|
write(bar(""));
|
package/dist/format.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { test } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { buildReport, writeReport, REPORT_SCHEMA_VERSION } from "./report.js";
|
|
6
|
+
import { withTmpDir } from "./test-utils.js";
|
|
7
|
+
function summary(overrides = {}) {
|
|
8
|
+
return {
|
|
9
|
+
dep: "lodash",
|
|
10
|
+
from: "4.17.20",
|
|
11
|
+
to: "4.17.21",
|
|
12
|
+
packageManager: "npm",
|
|
13
|
+
baselineGreen: true,
|
|
14
|
+
neededFix: false,
|
|
15
|
+
fixed: true,
|
|
16
|
+
unverifiable: false,
|
|
17
|
+
needsReview: false,
|
|
18
|
+
committed: true,
|
|
19
|
+
rounds: 0,
|
|
20
|
+
usage: { inputTokens: 0, outputTokens: 0 },
|
|
21
|
+
editedFiles: [],
|
|
22
|
+
testFilesTouched: [],
|
|
23
|
+
durationMs: 0,
|
|
24
|
+
...overrides,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
test("buildReport: wraps a single run in the same array envelope as a batch", () => {
|
|
28
|
+
const envelope = buildReport([summary()]);
|
|
29
|
+
assert.equal(envelope.schemaVersion, REPORT_SCHEMA_VERSION);
|
|
30
|
+
assert.ok(Array.isArray(envelope.runs));
|
|
31
|
+
assert.equal(envelope.runs.length, 1);
|
|
32
|
+
assert.ok(typeof envelope.generatedAt === "string" && !Number.isNaN(Date.parse(envelope.generatedAt)));
|
|
33
|
+
});
|
|
34
|
+
test("buildReport: batch of results, mixing successes and failures, keeps the array shape", () => {
|
|
35
|
+
const failure = { dep: "axios", error: "install failed", fatal: true };
|
|
36
|
+
const envelope = buildReport([summary({ dep: "lodash" }), failure]);
|
|
37
|
+
assert.equal(envelope.runs.length, 2);
|
|
38
|
+
});
|
|
39
|
+
test("writeReport: round-trips through disk with schema and fields intact", async () => {
|
|
40
|
+
await withTmpDir(async (dir) => {
|
|
41
|
+
const failure = { dep: "axios", error: "install failed", fatal: true };
|
|
42
|
+
const envelope = buildReport([summary({ dep: "lodash", rounds: 3 }), failure]);
|
|
43
|
+
const path = join(dir, "report.json");
|
|
44
|
+
await writeReport(path, envelope);
|
|
45
|
+
const raw = await readFile(path, "utf8");
|
|
46
|
+
const parsed = JSON.parse(raw);
|
|
47
|
+
assert.equal(parsed.schemaVersion, 1);
|
|
48
|
+
assert.equal(parsed.runs.length, 2);
|
|
49
|
+
assert.equal(parsed.runs[0].dep, "lodash");
|
|
50
|
+
assert.equal(parsed.runs[0].rounds, 3);
|
|
51
|
+
assert.equal(parsed.runs[1].dep, "axios");
|
|
52
|
+
assert.equal(parsed.runs[1].error, "install failed");
|
|
53
|
+
assert.equal(parsed.runs[1].fatal, true);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=report.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.test.js","sourceRoot":"","sources":["../src/report.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "greenbump",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Upgrade a dependency and let an AI agent fix the code it breaks — until CI is green. The Renovate that actually mends your code.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"greenbump": "dist/cli.js"
|
|
8
8
|
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
9
12
|
"engines": {
|
|
10
13
|
"node": ">=20"
|
|
11
14
|
},
|
|
@@ -41,14 +44,14 @@
|
|
|
41
44
|
"commander": "^14.0.0",
|
|
42
45
|
"madge": "^8.0.0",
|
|
43
46
|
"openai": "^4.77.0",
|
|
44
|
-
"picocolors": "^1.1.1"
|
|
47
|
+
"picocolors": "^1.1.1",
|
|
48
|
+
"typescript": "^5.7.0"
|
|
45
49
|
},
|
|
46
50
|
"devDependencies": {
|
|
47
51
|
"@types/madge": "^5.0.3",
|
|
48
52
|
"@types/node": "^22.10.0",
|
|
49
53
|
"esbuild": "^0.24.0",
|
|
50
54
|
"glob": "^13.0.6",
|
|
51
|
-
"tsx": "^4.19.0"
|
|
52
|
-
"typescript": "^5.7.0"
|
|
55
|
+
"tsx": "^4.19.0"
|
|
53
56
|
}
|
|
54
57
|
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to this project are documented here. Format follows
|
|
4
|
-
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
5
|
-
|
|
6
|
-
## [Unreleased] - v0.4.0
|
|
7
|
-
|
|
8
|
-
### Added
|
|
9
|
-
- **Dependency graph analysis**: Use madge to build dependency graph and identify affected files
|
|
10
|
-
- **Staged fix strategy**: Organize fixes into stages (Configuration → Type Definitions → Source Code)
|
|
11
|
-
- **Incremental commits**: Each stage commits separately, allowing rollback to last successful stage
|
|
12
|
-
- New modules: `dep-graph.ts`, `stages.ts`, `staged-fix.ts`
|
|
13
|
-
- `commitStage()` helper in git.ts for incremental commits
|
|
14
|
-
|
|
15
|
-
### Changed
|
|
16
|
-
- Foundation for `--staged` flag (will be exposed in CLI in future release)
|
|
17
|
-
- Improved fix success rate for complex upgrades (target: 20-40% → 50-70%)
|
|
18
|
-
|
|
19
|
-
### Technical Details
|
|
20
|
-
- Uses madge for static dependency analysis
|
|
21
|
-
- Three-stage fix pipeline: config files first, then type definitions, then source code
|
|
22
|
-
- Each stage validates independently before committing
|
|
23
|
-
- Falls back to single-stage fix if dependency graph unavailable
|
|
24
|
-
|
|
25
|
-
## [0.3.0] - 2026-08-17
|
|
26
|
-
|
|
27
|
-
### Added
|
|
28
|
-
- **Static analysis verification**: Run TypeScript (`tsc --noEmit`) and ESLint checks after fix loop
|
|
29
|
-
- **Change detection warnings**: Automatically flag suspicious changes in git diff
|
|
30
|
-
- Test file modifications (critical severity)
|
|
31
|
-
- Large deletions >50 lines (warning severity)
|
|
32
|
-
- Commented-out or removed test cases (critical severity)
|
|
33
|
-
- Display static analysis and change detection warnings in summary output
|
|
34
|
-
- Set `needsReview` flag when critical issues detected
|
|
35
|
-
|
|
36
|
-
### Changed
|
|
37
|
-
- `RunSummary` now includes `suspiciousChanges` and `staticAnalysisWarnings` fields
|
|
38
|
-
- Enhanced verification: fixes must pass type checks (TypeScript projects) in addition to tests
|
|
39
|
-
|
|
40
|
-
### Impact
|
|
41
|
-
- Reduces false positive fix rate from 10-20% → 5-10% (50% improvement)
|
|
42
|
-
- Improves user trust by catching LLM "cheating" (commenting tests, deleting code)
|
|
43
|
-
- TypeScript type error detection: 0% → 95%
|
|
44
|
-
|
|
45
|
-
## [0.2.1]
|
|
46
|
-
|
|
47
|
-
### Added
|
|
48
|
-
- `--scan` flag: list outdated dependencies without upgrading (read-only mode)
|
|
49
|
-
- Risk boundaries documentation in README (when to use greenbump vs manual review)
|
|
50
|
-
- Competitor comparison table (vs Dependabot, Renovate, Migratowl)
|
|
51
|
-
- CI smoke tests for real toolchains (npm, pip, cargo)
|
|
52
|
-
- Options table updated with `--scan`, `--all`, `--group`, `--max-tokens`
|
|
53
|
-
|
|
54
|
-
### Changed
|
|
55
|
-
- GitHub Action branding icon from `arrow-up-circle` to `refresh-cw`
|
|
56
|
-
- npm package excludes test files via `.npmignore` (reduced from 116 to 114 files)
|
|
57
|
-
|
|
58
|
-
## [0.2.0]
|
|
59
|
-
|
|
60
|
-
### Added
|
|
61
|
-
- Batch upgrades: `--all` (every outdated dep) and multi-dep args, with `--group <name>`
|
|
62
|
-
to combine several deps into one branch/PR, and `--fail-fast` to abort a batch on the
|
|
63
|
-
first hard failure.
|
|
64
|
-
- Monorepo/workspace support: detects npm/yarn `workspaces` and pnpm's
|
|
65
|
-
`pnpm-workspace.yaml`, resolving ambiguous dependency names via `--workspace`.
|
|
66
|
-
- `needsReview` field on run summaries, surfaced as CLI exit code 3 (distinct from exit
|
|
67
|
-
code 2 for an unfixed upgrade) — flags runs where a human should look before merging
|
|
68
|
-
(a test file was touched to get green, the run was unverifiable, or a `--max-tokens`
|
|
69
|
-
budget was hit).
|
|
70
|
-
- `--max-tokens`: hard cap on total tokens spent by the fix loop. Stops the loop and
|
|
71
|
-
flags `needsReview` instead of silently overspending.
|
|
72
|
-
- `--report-file <path>`: persist a JSON report (schema-versioned) of the run(s).
|
|
73
|
-
- GitHub Action: PR draft/label updates driven by `needsReview`, new `review-label`
|
|
74
|
-
input (default `needs-review`), and `report-file` input.
|
|
75
|
-
- Parser unit tests for the 7 ecosystems that had none: npm, pnpm, pip, uv, pipenv,
|
|
76
|
-
swiftpm, elm.
|
|
77
|
-
|
|
78
|
-
### Changed
|
|
79
|
-
- Clarified in the docs and in `EcosystemAdapter.verified`'s own type comment that
|
|
80
|
-
`verified: true` is a self-reported, one-time manual smoke test by the maintainer —
|
|
81
|
-
not an automated, CI-backed guarantee.
|
|
82
|
-
|
|
83
|
-
### Fixed
|
|
84
|
-
- A CI-only flaky test in `checks.test.ts` caused by cross-stream (stdout/stderr)
|
|
85
|
-
write-ordering not being guaranteed when appended into one combined buffer.
|
|
86
|
-
|
|
87
|
-
## [0.1.0]
|
|
88
|
-
|
|
89
|
-
Initial release: single-dependency upgrade via `greenbump <dep>` or the GitHub Action,
|
|
90
|
-
auto-detecting the ecosystem (npm, Yarn, pnpm, pip, Poetry, uv, Pipenv, Cargo, Go
|
|
91
|
-
modules, Bundler, Composer, Gradle, Maven, NuGet, Mix, Pub, Swift Package Manager,
|
|
92
|
-
CocoaPods, Conan, Elm), running the project's build/test, and handing any breakage to
|
|
93
|
-
an AI fix agent (Anthropic/OpenAI-compatible providers) until checks pass again.
|
package/CONTRIBUTING.md
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
# Contributing
|
|
2
|
-
|
|
3
|
-
## Setup
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
npm install
|
|
7
|
-
npm run build
|
|
8
|
-
npm test
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
`npm test` builds the project then runs every `*.test.js` file under `dist/`
|
|
12
|
-
with Node's built-in test runner. Some tests (`git.test.ts`) create real
|
|
13
|
-
temporary git repositories and shell out to the actual `git` binary — no
|
|
14
|
-
mocking — so they need `git` on `PATH` but touch nothing outside `os.tmpdir()`.
|
|
15
|
-
|
|
16
|
-
## Adding or fixing an ecosystem adapter
|
|
17
|
-
|
|
18
|
-
Each package manager lives in its own file under
|
|
19
|
-
`src/engine/ecosystems/<id>.ts` and implements the `EcosystemAdapter`
|
|
20
|
-
interface (`src/engine/ecosystems/types.ts`): `detect`, `outdated`, `install`,
|
|
21
|
-
`defaultCheckCommands`.
|
|
22
|
-
|
|
23
|
-
If you're fixing a parser bug, please:
|
|
24
|
-
1. Reproduce it against the *real* CLI output, not a guessed format — most
|
|
25
|
-
existing bugs here came from a test fixture that didn't match what the
|
|
26
|
-
real tool actually prints (e.g. `mix hex.outdated`'s "Only" column, or
|
|
27
|
-
`pod outdated`'s `(latest version X)` suffix).
|
|
28
|
-
2. Add or update the corresponding case in
|
|
29
|
-
`src/engine/ecosystems/parsers.test.ts` with a comment explaining the
|
|
30
|
-
real-world quirk, not just the happy path.
|
|
31
|
-
3. If you have the toolchain installed locally, run the adapter against a
|
|
32
|
-
throwaway project to confirm `detect`/`outdated`/`install` work end to end
|
|
33
|
-
before setting `verified: true`.
|
|
34
|
-
|
|
35
|
-
## Code style
|
|
36
|
-
|
|
37
|
-
- No unnecessary abstractions — match the size of the existing adapters.
|
|
38
|
-
- Don't add error handling for cases that can't happen; only validate at
|
|
39
|
-
actual boundaries (parsing untrusted CLI/API output, user-supplied paths).
|
|
40
|
-
- Keep PRs scoped: a parser fix doesn't need to also refactor the adapter
|
|
41
|
-
around it.
|
|
42
|
-
|
|
43
|
-
## Reporting a bug in a specific ecosystem
|
|
44
|
-
|
|
45
|
-
Include:
|
|
46
|
-
- The ecosystem id (`--ecosystem <id>` or auto-detected)
|
|
47
|
-
- The exact manifest/lockfile involved (redact anything private)
|
|
48
|
-
- The raw output of the underlying CLI command that greenbump would have
|
|
49
|
-
parsed (e.g. `npm outdated --json`, `pod outdated`)
|
|
50
|
-
|
|
51
|
-
For security issues, see [SECURITY.md](SECURITY.md) instead of opening a
|
|
52
|
-
public issue.
|
package/SECURITY.md
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# Security Policy
|
|
2
|
-
|
|
3
|
-
## Reporting a vulnerability
|
|
4
|
-
|
|
5
|
-
Please do **not** open a public GitHub issue for security vulnerabilities.
|
|
6
|
-
|
|
7
|
-
Instead, report it privately via GitHub's
|
|
8
|
-
[private vulnerability reporting](https://github.com/shidesheng0218/greenbump/security/advisories/new)
|
|
9
|
-
(https://github.com/shidesheng0218/greenbump), or by
|
|
10
|
-
emailing the maintainer directly if that's not enabled yet.
|
|
11
|
-
|
|
12
|
-
Include:
|
|
13
|
-
- A description of the issue and its impact
|
|
14
|
-
- Steps to reproduce
|
|
15
|
-
- The version/commit affected
|
|
16
|
-
|
|
17
|
-
We'll acknowledge reports as quickly as we can and credit you in the fix
|
|
18
|
-
unless you'd prefer otherwise.
|
|
19
|
-
|
|
20
|
-
## Scope and known risk areas
|
|
21
|
-
|
|
22
|
-
greenbump is a CLI/GitHub Action that:
|
|
23
|
-
- Runs shell commands from your project's own package manager (`npm`,
|
|
24
|
-
`poetry`, `cargo`, etc.) against your working directory.
|
|
25
|
-
- Gives an LLM-driven agent tool access (`read_file`, `write_file`,
|
|
26
|
-
`search_code`, `run_check`) scoped to the project directory — see
|
|
27
|
-
`src/agent/fixer.ts`'s `safePath()` for the path-escape guard.
|
|
28
|
-
- Sends your build/test failure output, and optionally dependency changelogs,
|
|
29
|
-
to the LLM provider you configure (your own API key — nothing is sent to
|
|
30
|
-
any greenbump-operated server).
|
|
31
|
-
|
|
32
|
-
If you find a way for the fix agent to escape the project directory, run
|
|
33
|
-
arbitrary commands beyond your configured build/test scripts, or exfiltrate
|
|
34
|
-
data beyond what's needed for the fix loop, that's a valid report.
|
|
35
|
-
|
|
36
|
-
Vulnerabilities in third-party dependencies (`@anthropic-ai/sdk`, `openai`,
|
|
37
|
-
`commander`, etc.) should be reported upstream, though we're happy to hear
|
|
38
|
-
about them too if they materially affect greenbump.
|