greenbump 0.2.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.
Files changed (116) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +125 -0
  3. package/README.zh-CN.md +213 -0
  4. package/action-dist/index.cjs +19695 -0
  5. package/action.yml +76 -0
  6. package/dist/action/github.js +70 -0
  7. package/dist/action/github.js.map +1 -0
  8. package/dist/action/main.js +99 -0
  9. package/dist/action/main.js.map +1 -0
  10. package/dist/agent/factory.js +72 -0
  11. package/dist/agent/factory.js.map +1 -0
  12. package/dist/agent/fixer.js +307 -0
  13. package/dist/agent/fixer.js.map +1 -0
  14. package/dist/agent/fixer.test.js +224 -0
  15. package/dist/agent/fixer.test.js.map +1 -0
  16. package/dist/agent/provider-anthropic.js +59 -0
  17. package/dist/agent/provider-anthropic.js.map +1 -0
  18. package/dist/agent/provider-openai.js +65 -0
  19. package/dist/agent/provider-openai.js.map +1 -0
  20. package/dist/agent/provider.js +4 -0
  21. package/dist/agent/provider.js.map +1 -0
  22. package/dist/cli.js +138 -0
  23. package/dist/cli.js.map +1 -0
  24. package/dist/engine/batch.js +246 -0
  25. package/dist/engine/batch.js.map +1 -0
  26. package/dist/engine/batch.test.js +59 -0
  27. package/dist/engine/batch.test.js.map +1 -0
  28. package/dist/engine/changelog.js +66 -0
  29. package/dist/engine/changelog.js.map +1 -0
  30. package/dist/engine/checks.js +41 -0
  31. package/dist/engine/checks.js.map +1 -0
  32. package/dist/engine/checks.test.js +92 -0
  33. package/dist/engine/checks.test.js.map +1 -0
  34. package/dist/engine/detect.js +5 -0
  35. package/dist/engine/detect.js.map +1 -0
  36. package/dist/engine/ecosystems/bundler.js +59 -0
  37. package/dist/engine/ecosystems/bundler.js.map +1 -0
  38. package/dist/engine/ecosystems/cargo.js +83 -0
  39. package/dist/engine/ecosystems/cargo.js.map +1 -0
  40. package/dist/engine/ecosystems/cocoapods.js +47 -0
  41. package/dist/engine/ecosystems/cocoapods.js.map +1 -0
  42. package/dist/engine/ecosystems/composer.js +32 -0
  43. package/dist/engine/ecosystems/composer.js.map +1 -0
  44. package/dist/engine/ecosystems/conan.js +106 -0
  45. package/dist/engine/ecosystems/conan.js.map +1 -0
  46. package/dist/engine/ecosystems/elm.js +77 -0
  47. package/dist/engine/ecosystems/elm.js.map +1 -0
  48. package/dist/engine/ecosystems/go.js +72 -0
  49. package/dist/engine/ecosystems/go.js.map +1 -0
  50. package/dist/engine/ecosystems/gradle.js +90 -0
  51. package/dist/engine/ecosystems/gradle.js.map +1 -0
  52. package/dist/engine/ecosystems/index.js +67 -0
  53. package/dist/engine/ecosystems/index.js.map +1 -0
  54. package/dist/engine/ecosystems/maven.js +77 -0
  55. package/dist/engine/ecosystems/maven.js.map +1 -0
  56. package/dist/engine/ecosystems/mix.js +64 -0
  57. package/dist/engine/ecosystems/mix.js.map +1 -0
  58. package/dist/engine/ecosystems/npm.js +47 -0
  59. package/dist/engine/ecosystems/npm.js.map +1 -0
  60. package/dist/engine/ecosystems/nuget.js +50 -0
  61. package/dist/engine/ecosystems/nuget.js.map +1 -0
  62. package/dist/engine/ecosystems/parsers.test.js +255 -0
  63. package/dist/engine/ecosystems/parsers.test.js.map +1 -0
  64. package/dist/engine/ecosystems/pip.js +61 -0
  65. package/dist/engine/ecosystems/pip.js.map +1 -0
  66. package/dist/engine/ecosystems/pipenv.js +37 -0
  67. package/dist/engine/ecosystems/pipenv.js.map +1 -0
  68. package/dist/engine/ecosystems/pnpm.js +48 -0
  69. package/dist/engine/ecosystems/pnpm.js.map +1 -0
  70. package/dist/engine/ecosystems/poetry.js +42 -0
  71. package/dist/engine/ecosystems/poetry.js.map +1 -0
  72. package/dist/engine/ecosystems/pub.js +32 -0
  73. package/dist/engine/ecosystems/pub.js.map +1 -0
  74. package/dist/engine/ecosystems/python-shared.js +29 -0
  75. package/dist/engine/ecosystems/python-shared.js.map +1 -0
  76. package/dist/engine/ecosystems/swiftpm.js +102 -0
  77. package/dist/engine/ecosystems/swiftpm.js.map +1 -0
  78. package/dist/engine/ecosystems/types.js +19 -0
  79. package/dist/engine/ecosystems/types.js.map +1 -0
  80. package/dist/engine/ecosystems/uv.js +36 -0
  81. package/dist/engine/ecosystems/uv.js.map +1 -0
  82. package/dist/engine/ecosystems/yarn.js +62 -0
  83. package/dist/engine/ecosystems/yarn.js.map +1 -0
  84. package/dist/engine/exec.js +47 -0
  85. package/dist/engine/exec.js.map +1 -0
  86. package/dist/engine/git.js +42 -0
  87. package/dist/engine/git.js.map +1 -0
  88. package/dist/engine/git.test.js +111 -0
  89. package/dist/engine/git.test.js.map +1 -0
  90. package/dist/engine/pm.js +14 -0
  91. package/dist/engine/pm.js.map +1 -0
  92. package/dist/engine/run.js +167 -0
  93. package/dist/engine/run.js.map +1 -0
  94. package/dist/engine/run.test.js +47 -0
  95. package/dist/engine/run.test.js.map +1 -0
  96. package/dist/engine/upgrade.js +10 -0
  97. package/dist/engine/upgrade.js.map +1 -0
  98. package/dist/engine/workspace.js +155 -0
  99. package/dist/engine/workspace.js.map +1 -0
  100. package/dist/engine/workspace.test.js +95 -0
  101. package/dist/engine/workspace.test.js.map +1 -0
  102. package/dist/exitcode.js +51 -0
  103. package/dist/exitcode.js.map +1 -0
  104. package/dist/exitcode.test.js +62 -0
  105. package/dist/exitcode.test.js.map +1 -0
  106. package/dist/format.js +101 -0
  107. package/dist/format.js.map +1 -0
  108. package/dist/pr.js +63 -0
  109. package/dist/pr.js.map +1 -0
  110. package/dist/report.js +13 -0
  111. package/dist/report.js.map +1 -0
  112. package/dist/report.test.js +56 -0
  113. package/dist/report.test.js.map +1 -0
  114. package/dist/test-utils.js +36 -0
  115. package/dist/test-utils.js.map +1 -0
  116. package/package.json +56 -0
@@ -0,0 +1,111 @@
1
+ import { test } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdtemp, writeFile, rm, appendFile } from "node:fs/promises";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { exec } from "./exec.js";
7
+ import { isGitRepo, isTreeClean, currentBranch, createBranch, checkout, commitAll, diffStat, fullDiff, changedFiles, } from "./git.js";
8
+ async function withRepo(fn) {
9
+ const dir = await mkdtemp(join(tmpdir(), "greenbump-git-"));
10
+ try {
11
+ await exec("git", ["init", "-q"], { cwd: dir });
12
+ // Never touch the machine's global git config — set identity locally only.
13
+ await exec("git", ["config", "user.email", "test@greenbump.dev"], { cwd: dir });
14
+ await exec("git", ["config", "user.name", "greenbump test"], { cwd: dir });
15
+ await fn(dir);
16
+ }
17
+ finally {
18
+ await rm(dir, { recursive: true, force: true });
19
+ }
20
+ }
21
+ /** Repo with one committed file, so HEAD is a real ref (not "unborn"). */
22
+ async function withInitializedRepo(fn) {
23
+ await withRepo(async (dir) => {
24
+ await writeFile(join(dir, "README.md"), "hello\n", "utf8");
25
+ await exec("git", ["add", "-A"], { cwd: dir });
26
+ await exec("git", ["commit", "-q", "-m", "init"], { cwd: dir });
27
+ await fn(dir);
28
+ });
29
+ }
30
+ test("isGitRepo: true inside a git repo, false in a plain directory", async () => {
31
+ await withRepo(async (dir) => {
32
+ assert.equal(await isGitRepo(dir), true);
33
+ });
34
+ const plain = await mkdtemp(join(tmpdir(), "greenbump-plain-"));
35
+ try {
36
+ assert.equal(await isGitRepo(plain), false);
37
+ }
38
+ finally {
39
+ await rm(plain, { recursive: true, force: true });
40
+ }
41
+ });
42
+ test("isTreeClean: true right after commit, false with an untracked or modified file", async () => {
43
+ await withInitializedRepo(async (dir) => {
44
+ assert.equal(await isTreeClean(dir), true);
45
+ await writeFile(join(dir, "untracked.txt"), "x", "utf8");
46
+ assert.equal(await isTreeClean(dir), false);
47
+ await exec("git", ["add", "-A"], { cwd: dir });
48
+ await exec("git", ["commit", "-q", "-m", "add untracked"], { cwd: dir });
49
+ assert.equal(await isTreeClean(dir), true);
50
+ await appendFile(join(dir, "README.md"), "more\n");
51
+ assert.equal(await isTreeClean(dir), false);
52
+ });
53
+ });
54
+ test("currentBranch + createBranch: creates and switches to a new branch", async () => {
55
+ await withInitializedRepo(async (dir) => {
56
+ const before = await currentBranch(dir);
57
+ assert.ok(before.length > 0);
58
+ await createBranch(dir, "greenbump/lodash-4.17.21");
59
+ const after = await currentBranch(dir);
60
+ assert.equal(after, "greenbump/lodash-4.17.21");
61
+ assert.notEqual(after, before);
62
+ });
63
+ });
64
+ test("checkout: switches HEAD back to an existing branch", async () => {
65
+ await withInitializedRepo(async (dir) => {
66
+ const original = await currentBranch(dir);
67
+ await createBranch(dir, "feature-x");
68
+ assert.equal(await currentBranch(dir), "feature-x");
69
+ await checkout(dir, original);
70
+ assert.equal(await currentBranch(dir), original);
71
+ });
72
+ });
73
+ test("commitAll: stages and commits pending changes, including untracked files", async () => {
74
+ await withInitializedRepo(async (dir) => {
75
+ await writeFile(join(dir, "new-file.txt"), "content", "utf8");
76
+ await appendFile(join(dir, "README.md"), "more\n");
77
+ assert.equal(await isTreeClean(dir), false);
78
+ await commitAll(dir, "chore(deps): bump lodash 4.17.20 → 4.17.21");
79
+ assert.equal(await isTreeClean(dir), true);
80
+ const log = await exec("git", ["log", "-1", "--pretty=%s"], { cwd: dir });
81
+ assert.equal(log.stdout.trim(), "chore(deps): bump lodash 4.17.20 → 4.17.21");
82
+ });
83
+ });
84
+ test("diffStat + fullDiff + changedFiles: report changes made since a ref", async () => {
85
+ await withInitializedRepo(async (dir) => {
86
+ const base = (await exec("git", ["rev-parse", "HEAD"], { cwd: dir })).stdout.trim();
87
+ await writeFile(join(dir, "src.js"), "export const x = 1;\n", "utf8");
88
+ await appendFile(join(dir, "README.md"), "changed\n");
89
+ await commitAll(dir, "add src.js and edit README");
90
+ const files = await changedFiles(dir, base);
91
+ assert.deepEqual([...files].sort(), ["README.md", "src.js"]);
92
+ const stat = await diffStat(dir, base);
93
+ assert.match(stat, /README\.md/);
94
+ assert.match(stat, /src\.js/);
95
+ const diff = await fullDiff(dir, base);
96
+ assert.match(diff, /\+export const x = 1;/);
97
+ assert.match(diff, /\+changed/);
98
+ });
99
+ });
100
+ test("commitAll: --no-verify means a failing pre-commit hook does not block the commit", async () => {
101
+ await withInitializedRepo(async (dir) => {
102
+ const hooksDir = join(dir, ".git", "hooks");
103
+ await writeFile(join(hooksDir, "pre-commit"), "#!/bin/sh\nexit 1\n", { mode: 0o755 });
104
+ await writeFile(join(dir, "another.txt"), "x", "utf8");
105
+ await commitAll(dir, "should succeed despite failing hook");
106
+ assert.equal(await isTreeClean(dir), true);
107
+ const log = await exec("git", ["log", "-1", "--pretty=%s"], { cwd: dir });
108
+ assert.equal(log.stdout.trim(), "should succeed despite failing hook");
109
+ });
110
+ });
111
+ //# sourceMappingURL=git.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.test.js","sourceRoot":"","sources":["../../src/engine/git.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { ADAPTERS, getAdapter, detectEcosystem } from "./ecosystems/index.js";
2
+ /** Detect which ecosystem this project uses; defaults to npm if nothing else matches. */
3
+ export async function detectPackageManager(cwd) {
4
+ const adapter = await detectEcosystem(cwd);
5
+ return adapter?.id ?? "npm";
6
+ }
7
+ export async function outdated(pm, cwd) {
8
+ return getAdapter(pm).outdated(cwd);
9
+ }
10
+ export async function install(pm, cwd, name, version) {
11
+ return getAdapter(pm).install(cwd, name, version);
12
+ }
13
+ export { ADAPTERS, getAdapter, detectEcosystem };
14
+ //# sourceMappingURL=pm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pm.js","sourceRoot":"","sources":["../../src/engine/pm.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAiB,MAAM,uBAAuB,CAAC;AAU7F,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,GAAW;IACpD,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;IAC3C,OAAO,OAAO,EAAE,EAAE,IAAI,KAAK,CAAC;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,EAAkB,EAAE,GAAW;IAC5D,OAAO,UAAU,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,EAAkB,EAClB,GAAW,EACX,IAAY,EACZ,OAAe;IAEf,OAAO,UAAU,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AACpD,CAAC;AAED,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,167 @@
1
+ import { detectOutdated } from "./detect.js";
2
+ import { runChecks } from "./checks.js";
3
+ import { upgradeDependency } from "./upgrade.js";
4
+ import { detectPackageManager } from "./pm.js";
5
+ import { fetchChangelog } from "./changelog.js";
6
+ import { isGitRepo, isTreeClean, currentBranch, createBranch, commitAll, diffStat, fullDiff, } from "./git.js";
7
+ import { runFixLoop } from "../agent/fixer.js";
8
+ import { createProvider } from "../agent/factory.js";
9
+ export class RunError extends Error {
10
+ }
11
+ /**
12
+ * Pure decision logic for `needsReview`, split out so it's directly
13
+ * testable without spinning up a real npm/fix-loop run. `fixed`/`neededFix`
14
+ * are the fix loop's own outcome; `unverifiable` and `testFilesTouched` are
15
+ * the two independent triggers (see the `needsReview` field doc above).
16
+ */
17
+ export function computeNeedsReview(input) {
18
+ if (input.unverifiable)
19
+ return true;
20
+ if (input.budgetExceeded)
21
+ return true;
22
+ if (!input.neededFix)
23
+ return false;
24
+ return input.fixed && input.testFilesTouched.length > 0;
25
+ }
26
+ export async function run(opts) {
27
+ const log = opts.onLog ?? (() => { });
28
+ const { cwd } = opts;
29
+ const startedAt = Date.now();
30
+ const pm = opts.ecosystem ?? (await detectPackageManager(cwd));
31
+ const checkOverrides = { buildCmd: opts.buildCmd, testCmd: opts.testCmd };
32
+ log(`ecosystem: ${pm}`);
33
+ // 1. detect
34
+ log("detecting outdated dependencies…");
35
+ const outdated = await detectOutdated(pm, cwd);
36
+ if (outdated.length === 0) {
37
+ throw new RunError("No outdated dependencies found — nothing to upgrade.");
38
+ }
39
+ // 2. select target
40
+ const target = opts.dep
41
+ ? outdated.find((o) => o.name === opts.dep)
42
+ : outdated[0];
43
+ if (!target) {
44
+ throw new RunError(`\`${opts.dep}\` is not outdated (or not a direct dependency). Available: ${outdated
45
+ .map((o) => o.name)
46
+ .join(", ")}`);
47
+ }
48
+ const from = target.current;
49
+ const to = opts.to ?? target.latest;
50
+ log(`target: ${target.name} ${from} → ${to}`);
51
+ // 3. git isolation
52
+ let branch;
53
+ const gitRepo = await isGitRepo(cwd);
54
+ if (gitRepo && !opts.noGit) {
55
+ if (!(await isTreeClean(cwd))) {
56
+ throw new RunError("Working tree is dirty. Commit or stash your changes first (or pass --no-git).");
57
+ }
58
+ await currentBranch(cwd); // ensure HEAD resolves
59
+ branch = `greenbump/${target.name.replace(/[^a-zA-Z0-9._-]/g, "-")}-${to}`;
60
+ await createBranch(cwd, branch);
61
+ log(`created branch ${branch}`);
62
+ }
63
+ // 4. baseline — refuse to run if it's already broken, so we never chase
64
+ // failures that predate the upgrade.
65
+ log("running baseline build + tests…");
66
+ const baseline = await runChecks(pm, cwd, checkOverrides);
67
+ if (!baseline.ok && !baseline.unverifiable) {
68
+ throw new RunError(`Baseline is already failing (${baseline.failedStep}) before any upgrade. ` +
69
+ `Fix that first — greenbump can't tell your pre-existing failures from upgrade breakage.`);
70
+ }
71
+ const baselineGreen = baseline.ok && !baseline.unverifiable;
72
+ // 5. upgrade
73
+ log(`installing ${target.name}@${to}…`);
74
+ const up = await upgradeDependency(pm, cwd, target.name, to);
75
+ if (!up.ok) {
76
+ throw new RunError(`${pm} failed to install ${target.name}@${to}:\n${up.output}`);
77
+ }
78
+ // 6. verify
79
+ const post = await runChecks(pm, cwd, checkOverrides);
80
+ const summary = {
81
+ dep: target.name,
82
+ from,
83
+ to,
84
+ packageManager: pm,
85
+ branch,
86
+ baselineGreen,
87
+ neededFix: false,
88
+ fixed: post.ok,
89
+ unverifiable: post.unverifiable,
90
+ needsReview: false,
91
+ committed: false,
92
+ rounds: 0,
93
+ usage: { inputTokens: 0, outputTokens: 0 },
94
+ editedFiles: [],
95
+ testFilesTouched: [],
96
+ durationMs: 0,
97
+ };
98
+ if (post.unverifiable) {
99
+ // no way to verify — still a valid PR, just flagged
100
+ log("no build/test scripts — upgrade applied but UNVERIFIED");
101
+ summary.needsReview = true;
102
+ await maybeCommit(cwd, summary, true);
103
+ summary.durationMs = Date.now() - startedAt;
104
+ return summary;
105
+ }
106
+ if (post.ok) {
107
+ // clean upgrade, nothing broke
108
+ log("clean upgrade — build + tests green with no code changes");
109
+ await maybeCommit(cwd, summary, true);
110
+ summary.durationMs = Date.now() - startedAt;
111
+ return summary;
112
+ }
113
+ // 7. broke — fetch changelog context, then run the fix agent
114
+ summary.neededFix = true;
115
+ const changelog = await fetchChangelog(target.name, from, to);
116
+ if (changelog)
117
+ log(`found changelog/release notes for ${target.name}`);
118
+ const provider = createProvider({
119
+ provider: opts.provider,
120
+ model: opts.model,
121
+ baseURL: opts.baseURL,
122
+ apiKey: opts.apiKey,
123
+ });
124
+ log(`upgrade broke ${post.failedStep} — starting fix loop via ${provider.name} (${provider.model})`);
125
+ const fix = await runFixLoop({
126
+ cwd,
127
+ pm,
128
+ checkOverrides,
129
+ provider,
130
+ maxRounds: opts.maxRounds,
131
+ maxTokens: opts.maxTokens,
132
+ dep: target.name,
133
+ from,
134
+ to,
135
+ failureOutput: post.output,
136
+ changelog,
137
+ onLog: log,
138
+ });
139
+ summary.fixed = fix.fixed;
140
+ summary.rounds = fix.rounds;
141
+ summary.usage = fix.usage;
142
+ summary.editedFiles = fix.editedFiles;
143
+ summary.testFilesTouched = fix.editedFiles.filter((f) => /(^|\/)(test|tests|__tests__|spec)(\/|\.)|\.(test|spec)\./i.test(f));
144
+ summary.needsReview = computeNeedsReview({
145
+ unverifiable: false,
146
+ neededFix: true,
147
+ fixed: fix.fixed,
148
+ testFilesTouched: summary.testFilesTouched,
149
+ budgetExceeded: fix.budgetExceeded,
150
+ });
151
+ await maybeCommit(cwd, summary, fix.fixed);
152
+ summary.durationMs = Date.now() - startedAt;
153
+ return summary;
154
+ }
155
+ async function maybeCommit(cwd, summary, shouldCommit) {
156
+ if (!summary.branch || !shouldCommit)
157
+ return;
158
+ const note = summary.neededFix
159
+ ? ` and fix ${summary.editedFiles.length} file(s)`
160
+ : "";
161
+ await commitAll(cwd, `chore(deps): bump ${summary.dep} ${summary.from} → ${summary.to}${note}\n\nAutomated by greenbump.`);
162
+ summary.committed = true;
163
+ summary.diffStat = await diffStat(cwd, "HEAD~1");
164
+ if (summary.neededFix)
165
+ summary.fullDiff = await fullDiff(cwd, "HEAD~1");
166
+ }
167
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/engine/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { test } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { computeNeedsReview } from "./run.js";
4
+ test("computeNeedsReview: unverifiable always needs review, regardless of anything else", () => {
5
+ assert.equal(computeNeedsReview({ unverifiable: true, neededFix: false, fixed: true, testFilesTouched: [] }), true);
6
+ });
7
+ test("computeNeedsReview: clean upgrade (no fix needed) never needs review", () => {
8
+ assert.equal(computeNeedsReview({ unverifiable: false, neededFix: false, fixed: true, testFilesTouched: [] }), false);
9
+ });
10
+ test("computeNeedsReview: fixed with a test file touched needs review", () => {
11
+ assert.equal(computeNeedsReview({
12
+ unverifiable: false,
13
+ neededFix: true,
14
+ fixed: true,
15
+ testFilesTouched: ["src/foo.test.ts"],
16
+ }), true);
17
+ });
18
+ test("computeNeedsReview: fixed with no test file touched does not need review", () => {
19
+ assert.equal(computeNeedsReview({ unverifiable: false, neededFix: true, fixed: true, testFilesTouched: [] }), false);
20
+ });
21
+ test("computeNeedsReview: fix loop failed (unfixed) never needs review — that's exit code 2's job, not 3's", () => {
22
+ assert.equal(computeNeedsReview({
23
+ unverifiable: false,
24
+ neededFix: true,
25
+ fixed: false,
26
+ testFilesTouched: ["src/foo.test.ts"],
27
+ }), false);
28
+ });
29
+ test("computeNeedsReview: budgetExceeded always needs review, even on a clean/no-fix-needed run", () => {
30
+ assert.equal(computeNeedsReview({
31
+ unverifiable: false,
32
+ neededFix: false,
33
+ fixed: true,
34
+ testFilesTouched: [],
35
+ budgetExceeded: true,
36
+ }), true);
37
+ });
38
+ test("computeNeedsReview: budgetExceeded still needs review even when fixed with no test file touched", () => {
39
+ assert.equal(computeNeedsReview({
40
+ unverifiable: false,
41
+ neededFix: true,
42
+ fixed: true,
43
+ testFilesTouched: [],
44
+ budgetExceeded: true,
45
+ }), true);
46
+ });
47
+ //# sourceMappingURL=run.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.test.js","sourceRoot":"","sources":["../../src/engine/run.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAE9C,IAAI,CAAC,mFAAmF,EAAE,GAAG,EAAE;IAC7F,MAAM,CAAC,KAAK,CACV,kBAAkB,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC,EAC/F,IAAI,CACL,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,sEAAsE,EAAE,GAAG,EAAE;IAChF,MAAM,CAAC,KAAK,CACV,kBAAkB,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC,EAChG,KAAK,CACN,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iEAAiE,EAAE,GAAG,EAAE;IAC3E,MAAM,CAAC,KAAK,CACV,kBAAkB,CAAC;QACjB,YAAY,EAAE,KAAK;QACnB,SAAS,EAAE,IAAI;QACf,KAAK,EAAE,IAAI;QACX,gBAAgB,EAAE,CAAC,iBAAiB,CAAC;KACtC,CAAC,EACF,IAAI,CACL,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0EAA0E,EAAE,GAAG,EAAE;IACpF,MAAM,CAAC,KAAK,CACV,kBAAkB,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC,EAC/F,KAAK,CACN,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,sGAAsG,EAAE,GAAG,EAAE;IAChH,MAAM,CAAC,KAAK,CACV,kBAAkB,CAAC;QACjB,YAAY,EAAE,KAAK;QACnB,SAAS,EAAE,IAAI;QACf,KAAK,EAAE,KAAK;QACZ,gBAAgB,EAAE,CAAC,iBAAiB,CAAC;KACtC,CAAC,EACF,KAAK,CACN,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2FAA2F,EAAE,GAAG,EAAE;IACrG,MAAM,CAAC,KAAK,CACV,kBAAkB,CAAC;QACjB,YAAY,EAAE,KAAK;QACnB,SAAS,EAAE,KAAK;QAChB,KAAK,EAAE,IAAI;QACX,gBAAgB,EAAE,EAAE;QACpB,cAAc,EAAE,IAAI;KACrB,CAAC,EACF,IAAI,CACL,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iGAAiG,EAAE,GAAG,EAAE;IAC3G,MAAM,CAAC,KAAK,CACV,kBAAkB,CAAC;QACjB,YAAY,EAAE,KAAK;QACnB,SAAS,EAAE,IAAI;QACf,KAAK,EAAE,IAAI;QACX,gBAAgB,EAAE,EAAE;QACpB,cAAc,EAAE,IAAI;KACrB,CAAC,EACF,IAAI,CACL,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { install } from "./pm.js";
2
+ /**
3
+ * Install a specific version of a dependency, pinned exactly, so the
4
+ * resulting PR is reproducible.
5
+ */
6
+ export async function upgradeDependency(pm, cwd, name, version) {
7
+ const r = await install(pm, cwd, name, version);
8
+ return { ok: r.code === 0, output: r.combined };
9
+ }
10
+ //# sourceMappingURL=upgrade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../src/engine/upgrade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAuB,MAAM,SAAS,CAAC;AAOvD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,EAAkB,EAClB,GAAW,EACX,IAAY,EACZ,OAAe;IAEf,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAChD,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;AAClD,CAAC"}
@@ -0,0 +1,155 @@
1
+ import { join, relative } from "node:path";
2
+ import { readdir, readFile } from "node:fs/promises";
3
+ import { pathExists, safeJson } from "./ecosystems/types.js";
4
+ import { getAdapter } from "./ecosystems/index.js";
5
+ /** Sentinel workspacePath meaning "the repo root itself", distinct from any real member path. */
6
+ export const WORKSPACE_ROOT = ".";
7
+ async function readPackageJson(dir) {
8
+ try {
9
+ const raw = await readFile(join(dir, "package.json"), "utf8");
10
+ return safeJson(raw);
11
+ }
12
+ catch {
13
+ return null;
14
+ }
15
+ }
16
+ /**
17
+ * Minimal `packages:` list reader for pnpm-workspace.yaml — no full YAML
18
+ * parser dependency, just the one shape pnpm actually emits:
19
+ * packages:
20
+ * - "packages/*"
21
+ * - "apps/*"
22
+ */
23
+ async function readPnpmWorkspaceGlobs(cwd) {
24
+ let raw;
25
+ try {
26
+ raw = await readFile(join(cwd, "pnpm-workspace.yaml"), "utf8");
27
+ }
28
+ catch {
29
+ return [];
30
+ }
31
+ const globs = [];
32
+ let inPackages = false;
33
+ for (const line of raw.split("\n")) {
34
+ const trimmed = line.trim();
35
+ if (/^packages\s*:/.test(trimmed)) {
36
+ inPackages = true;
37
+ continue;
38
+ }
39
+ if (!inPackages)
40
+ continue;
41
+ const m = /^-\s*["']?([^"'#]+)["']?/.exec(trimmed);
42
+ if (m) {
43
+ globs.push(m[1].trim());
44
+ }
45
+ else if (trimmed && !trimmed.startsWith("#")) {
46
+ // a non-list, non-comment line ends the packages block
47
+ inPackages = false;
48
+ }
49
+ }
50
+ return globs;
51
+ }
52
+ /** Expand a glob with at most one trailing `*` segment (e.g. "packages/*") into real subdirectories. */
53
+ async function expandGlob(cwd, glob) {
54
+ const star = glob.indexOf("*");
55
+ if (star === -1) {
56
+ return (await pathExists(join(cwd, glob))) ? [glob] : [];
57
+ }
58
+ const base = glob.slice(0, star).replace(/\/$/, "");
59
+ const baseDir = join(cwd, base);
60
+ let entries;
61
+ try {
62
+ entries = (await readdir(baseDir, { withFileTypes: true }))
63
+ .filter((e) => e.isDirectory())
64
+ .map((e) => e.name);
65
+ }
66
+ catch {
67
+ return [];
68
+ }
69
+ return entries.map((name) => (base ? `${base}/${name}` : name));
70
+ }
71
+ async function globsToMembers(cwd, globs) {
72
+ const members = [];
73
+ const seen = new Set();
74
+ for (const glob of globs) {
75
+ for (const relPath of await expandGlob(cwd, glob)) {
76
+ if (seen.has(relPath))
77
+ continue;
78
+ const pkg = await readPackageJson(join(cwd, relPath));
79
+ if (!pkg)
80
+ continue; // not an actual package (e.g. an empty scaffold dir)
81
+ seen.add(relPath);
82
+ members.push({ path: relPath, name: pkg.name ?? relPath });
83
+ }
84
+ }
85
+ return members;
86
+ }
87
+ /**
88
+ * Detect workspace members for npm/yarn (`workspaces` field) or pnpm
89
+ * (`pnpm-workspace.yaml`). Returns `[]` for non-monorepo projects — this is
90
+ * intentionally JS-ecosystem-only; other ecosystems' own workspace/module
91
+ * conventions (Cargo workspaces, Go modules, Gradle multi-project, …) are out
92
+ * of scope for this pass.
93
+ */
94
+ export async function detectWorkspaceMembers(cwd) {
95
+ const pnpmGlobs = await readPnpmWorkspaceGlobs(cwd);
96
+ if (pnpmGlobs.length > 0)
97
+ return globsToMembers(cwd, pnpmGlobs);
98
+ const root = await readPackageJson(cwd);
99
+ const raw = root?.workspaces;
100
+ const globs = Array.isArray(raw) ? raw : raw?.packages ?? [];
101
+ if (globs.length === 0)
102
+ return [];
103
+ return globsToMembers(cwd, globs);
104
+ }
105
+ /**
106
+ * Outdated deps across the repo root and every workspace member, flattened
107
+ * into one list. Each entry is tagged with the package.json it came from so
108
+ * batch/monorepo targets can disambiguate same-named deps at different
109
+ * versions in different packages.
110
+ */
111
+ export async function detectOutdatedAll(pm, cwd) {
112
+ const adapter = getAdapter(pm);
113
+ const members = await detectWorkspaceMembers(cwd);
114
+ const scopes = [
115
+ { workspacePath: WORKSPACE_ROOT, dir: cwd },
116
+ ...members.map((m) => ({ workspacePath: m.path, dir: join(cwd, m.path) })),
117
+ ];
118
+ const results = [];
119
+ for (const scope of scopes) {
120
+ const outdated = await adapter.outdated(scope.dir);
121
+ for (const o of outdated) {
122
+ results.push({ ...o, workspacePath: scope.workspacePath });
123
+ }
124
+ }
125
+ return results;
126
+ }
127
+ export class WorkspaceAmbiguityError extends Error {
128
+ constructor(dep, candidates) {
129
+ const list = candidates
130
+ .map((c) => ` - ${c.workspacePath === WORKSPACE_ROOT ? "(root)" : c.workspacePath}: ${c.current} → ${c.latest}`)
131
+ .join("\n");
132
+ super(`\`${dep}\` is outdated at different versions in multiple workspace packages — ` +
133
+ `pass --workspace <path> to disambiguate:\n${list}`);
134
+ }
135
+ }
136
+ /**
137
+ * Resolve a dependency name to exactly one (dep, workspace) target across
138
+ * the flattened outdated list. Throws WorkspaceAmbiguityError if the name
139
+ * appears in 2+ packages at different current versions and no `workspace`
140
+ * hint was given; picks the matching one if `workspace` is given.
141
+ */
142
+ export function resolveWorkspaceTarget(dep, candidates, workspace) {
143
+ const matches = candidates.filter((c) => c.name === dep);
144
+ if (matches.length === 0)
145
+ return undefined;
146
+ if (workspace !== undefined) {
147
+ return matches.find((c) => c.workspacePath === workspace || relative(workspace, c.workspacePath) === "");
148
+ }
149
+ const distinctVersions = new Set(matches.map((c) => c.current));
150
+ if (matches.length > 1 && distinctVersions.size > 1) {
151
+ throw new WorkspaceAmbiguityError(dep, matches);
152
+ }
153
+ return matches[0];
154
+ }
155
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/engine/workspace.ts"],"names":[],"mappings":"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"}