@varlock/bumpy 0.0.1 → 1.0.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 (44) hide show
  1. package/.claude-plugin/plugin.json +2 -2
  2. package/dist/add-CgCjs4d-.mjs +313 -0
  3. package/dist/{ai-B8ZL2x8z.mjs → ai-sMYUf3lP.mjs} +22 -5
  4. package/dist/{apply-release-plan-DtU3rVyL.mjs → apply-release-plan-CczGWJTk.mjs} +34 -25
  5. package/dist/bump-file-CCLXMLA8.mjs +143 -0
  6. package/dist/changelog-github-Cd8uJHZI.mjs +195 -0
  7. package/dist/{check-CkRubvuk.mjs → check-BOoxpWqk.mjs} +11 -17
  8. package/dist/ci-Bhx--Tj6.mjs +629 -0
  9. package/dist/ci-setup-qz4Y3v7T.mjs +211 -0
  10. package/dist/clack-CDRCHrC-.mjs +1216 -0
  11. package/dist/cli.mjs +37 -31
  12. package/dist/{config-CJ2orhTL.mjs → config-XZWUL3ma.mjs} +28 -23
  13. package/dist/fs-DYR2XuFE.mjs +81 -0
  14. package/dist/{generate-oOFD9ABC.mjs → generate-gYKTpvex.mjs} +31 -12
  15. package/dist/git-CGHVXXKw.mjs +78 -0
  16. package/dist/index.d.mts +63 -37
  17. package/dist/index.mjs +9 -9
  18. package/dist/{init-Blw2GfC_.mjs → init-lA9E5pEc.mjs} +3 -3
  19. package/dist/logger-C2dEe5Su.mjs +135 -0
  20. package/dist/{migrate-DvOrXSw0.mjs → migrate-DmOYgmfD.mjs} +23 -16
  21. package/dist/{names-C-u50ofE.mjs → names-9VubBmL0.mjs} +3 -2
  22. package/dist/package-manager-VCe10bjc.mjs +80 -0
  23. package/dist/{publish-DZ3m7qkX.mjs → publish-Cun-zQ1b.mjs} +90 -35
  24. package/dist/{publish-pipeline-1M5GmbdP.mjs → publish-pipeline-BwBuKCIk.mjs} +56 -65
  25. package/dist/release-plan-Bi5QNSEo.mjs +264 -0
  26. package/dist/{semver-DWO6NFKN.mjs → semver-DfQyVLM_.mjs} +14 -4
  27. package/dist/shell-Dj7JRD_q.mjs +92 -0
  28. package/dist/{status-DRpq_Mha.mjs → status-CfE63ti5.mjs} +27 -23
  29. package/dist/version-19vVt9dv.mjs +124 -0
  30. package/dist/workspace-C5ULTyUN.mjs +107 -0
  31. package/package.json +16 -2
  32. package/skills/add-change/SKILL.md +8 -12
  33. package/dist/add-u5V9V3L7.mjs +0 -131
  34. package/dist/changelog-github-n-3zV1p9.mjs +0 -59
  35. package/dist/changeset-ClCYsChu.mjs +0 -75
  36. package/dist/ci-8KWWhjXl.mjs +0 -224
  37. package/dist/fs-DbNNEyzq.mjs +0 -51
  38. package/dist/logger-ZqggsyGZ.mjs +0 -176
  39. package/dist/prompt-BP8toAOI.mjs +0 -46
  40. package/dist/release-plan-CFnutSHD.mjs +0 -173
  41. package/dist/shell-DPlltpzb.mjs +0 -44
  42. package/dist/version-CJwf8XIA.mjs +0 -81
  43. package/dist/workspace-mVjawG8g.mjs +0 -183
  44. /package/dist/{dep-graph-DiLeAhl9.mjs → dep-graph-E-9-eQ2J.mjs} +0 -0
@@ -1,224 +0,0 @@
1
- import { n as log, t as colorize } from "./logger-ZqggsyGZ.mjs";
2
- import { a as loadConfig } from "./config-CJ2orhTL.mjs";
3
- import { n as discoverWorkspace } from "./workspace-mVjawG8g.mjs";
4
- import { t as DependencyGraph } from "./dep-graph-DiLeAhl9.mjs";
5
- import { r as readChangesets } from "./changeset-ClCYsChu.mjs";
6
- import { t as assembleReleasePlan } from "./release-plan-CFnutSHD.mjs";
7
- import { i as tryRun, n as runAsync, t as run } from "./shell-DPlltpzb.mjs";
8
- //#region src/commands/ci.ts
9
- /** Configure git identity for CI commits if not already set */
10
- function ensureGitIdentity(rootDir, config) {
11
- if (!tryRun("git config user.name", { cwd: rootDir })) {
12
- const { name: gitName, email: gitEmail } = config.gitUser;
13
- run(`git config user.name "${gitName}"`, { cwd: rootDir });
14
- run(`git config user.email "${gitEmail}"`, { cwd: rootDir });
15
- log.dim(` Using git identity: ${gitName} <${gitEmail}>`);
16
- }
17
- }
18
- /**
19
- * CI check: report on pending changesets.
20
- * Designed for PR workflows — shows what would be released and optionally comments on the PR.
21
- */
22
- async function ciCheckCommand(rootDir, opts) {
23
- const config = await loadConfig(rootDir);
24
- const { packages } = await discoverWorkspace(rootDir, config);
25
- const depGraph = new DependencyGraph(packages);
26
- const changesets = await readChangesets(rootDir);
27
- const inCI = !!process.env.CI;
28
- const shouldComment = opts.comment ?? inCI;
29
- const prNumber = detectPrNumber();
30
- if (changesets.length === 0) {
31
- log.info("No changesets found in this PR.");
32
- if (shouldComment && prNumber) await postOrUpdatePrComment(prNumber, formatNoChangesetsComment(), rootDir);
33
- if (opts.failOnMissing) process.exit(1);
34
- return;
35
- }
36
- const plan = assembleReleasePlan(changesets, packages, depGraph, config);
37
- log.bold(`${changesets.length} changeset(s) → ${plan.releases.length} package(s) to release\n`);
38
- for (const r of plan.releases) {
39
- const tag = r.isDependencyBump ? " (dep)" : r.isCascadeBump ? " (cascade)" : "";
40
- console.log(` ${r.name}: ${r.oldVersion} → ${colorize(r.newVersion, "cyan")}${tag}`);
41
- }
42
- if (shouldComment && prNumber) await postOrUpdatePrComment(prNumber, formatReleasePlanComment(plan, changesets.length), rootDir);
43
- }
44
- /**
45
- * CI release: either auto-publish or create a version PR.
46
- * Designed for merge-to-main workflows.
47
- */
48
- async function ciReleaseCommand(rootDir, opts) {
49
- const config = await loadConfig(rootDir);
50
- ensureGitIdentity(rootDir, config);
51
- const { packages } = await discoverWorkspace(rootDir, config);
52
- const depGraph = new DependencyGraph(packages);
53
- const changesets = await readChangesets(rootDir);
54
- if (changesets.length === 0) {
55
- log.info("No pending changesets — checking for unpublished packages...");
56
- const { publishCommand } = await import("./publish-DZ3m7qkX.mjs");
57
- await publishCommand(rootDir, { tag: opts.tag });
58
- return;
59
- }
60
- const plan = assembleReleasePlan(changesets, packages, depGraph, config);
61
- if (plan.releases.length === 0) {
62
- log.info("Changesets found but no packages would be released.");
63
- return;
64
- }
65
- if (opts.mode === "auto-publish") await autoPublish(rootDir, config, opts.tag);
66
- else await createVersionPr(rootDir, plan, config, opts.branch);
67
- }
68
- async function autoPublish(rootDir, config, tag) {
69
- log.step("Running bumpy version...");
70
- const { versionCommand } = await import("./version-CJwf8XIA.mjs");
71
- await versionCommand(rootDir);
72
- log.step("Committing version changes...");
73
- run("git add -A", { cwd: rootDir });
74
- if (tryRun("git status --porcelain", { cwd: rootDir })) {
75
- run("git commit -m \"Version packages\"", { cwd: rootDir });
76
- run("git push", { cwd: rootDir });
77
- }
78
- log.step("Running bumpy publish...");
79
- const { publishCommand } = await import("./publish-DZ3m7qkX.mjs");
80
- await publishCommand(rootDir, { tag });
81
- }
82
- async function createVersionPr(rootDir, plan, config, branchName) {
83
- const branch = branchName || config.versionPr.branch;
84
- const baseBranch = tryRun("git rev-parse --abbrev-ref HEAD", { cwd: rootDir }) || "main";
85
- const existingPr = tryRun(`gh pr list --head "${branch}" --json number --jq ".[0].number"`, { cwd: rootDir });
86
- log.step(`Creating branch ${branch}...`);
87
- if (tryRun(`git rev-parse --verify ${branch}`, { cwd: rootDir }) !== null) {
88
- run(`git checkout ${branch}`, { cwd: rootDir });
89
- run(`git reset --hard ${baseBranch}`, { cwd: rootDir });
90
- } else run(`git checkout -b ${branch}`, { cwd: rootDir });
91
- log.step("Running bumpy version...");
92
- const { versionCommand } = await import("./version-CJwf8XIA.mjs");
93
- await versionCommand(rootDir);
94
- run("git add -A", { cwd: rootDir });
95
- if (!tryRun("git status --porcelain", { cwd: rootDir })) {
96
- log.info("No version changes to commit.");
97
- run(`git checkout ${baseBranch}`, { cwd: rootDir });
98
- return;
99
- }
100
- run("git commit -F -", {
101
- cwd: rootDir,
102
- input: [
103
- "Version packages",
104
- "",
105
- ...plan.releases.map((r) => `${r.name}@${r.newVersion}`)
106
- ].join("\n")
107
- });
108
- run(`git push -u origin ${branch} --force`, { cwd: rootDir });
109
- const prBody = formatVersionPrBody(plan, config.versionPr.preamble);
110
- if (existingPr) {
111
- log.step(`Updating existing PR #${existingPr}...`);
112
- await runAsync(`gh pr edit ${existingPr} --title "${config.versionPr.title}" --body-file -`, {
113
- cwd: rootDir,
114
- input: prBody
115
- });
116
- log.success(`Updated PR #${existingPr}`);
117
- } else {
118
- log.step("Creating version PR...");
119
- const prTitle = config.versionPr.title;
120
- const result = await runAsync(`gh pr create --title "${prTitle}" --body-file - --base "${baseBranch}" --head "${branch}"`, {
121
- cwd: rootDir,
122
- input: prBody
123
- });
124
- log.success(`Created PR: ${result}`);
125
- }
126
- run(`git checkout ${baseBranch}`, { cwd: rootDir });
127
- }
128
- function formatReleasePlanComment(plan, changesetCount) {
129
- const lines = [];
130
- lines.push("## 🐸 Bumpy Release Plan\n");
131
- lines.push(`**${changesetCount}** changeset(s) → **${plan.releases.length}** package(s) to release\n`);
132
- const groups = [
133
- ["🔴 Major", plan.releases.filter((r) => r.type === "major")],
134
- ["🟡 Minor", plan.releases.filter((r) => r.type === "minor")],
135
- ["🟢 Patch", plan.releases.filter((r) => r.type === "patch")]
136
- ];
137
- for (const [label, group] of groups) {
138
- if (group.length === 0) continue;
139
- lines.push(`### ${label}\n`);
140
- lines.push("| Package | Change |");
141
- lines.push("|---------|--------|");
142
- for (const r of group) {
143
- const suffix = r.isDependencyBump ? " _(dep)_" : r.isCascadeBump ? " _(cascade)_" : "";
144
- lines.push(`| \`${r.name}\` | ${r.oldVersion} → **${r.newVersion}**${suffix} |`);
145
- }
146
- lines.push("");
147
- }
148
- lines.push("---");
149
- lines.push(`_This comment is maintained by [bumpy](https://github.com/dmno-dev/bumpy)._`);
150
- return lines.join("\n");
151
- }
152
- function formatNoChangesetsComment() {
153
- return [
154
- "## 🐸 Bumpy Release Plan\n",
155
- "No changesets found in this PR. If this PR should trigger a release, run:\n",
156
- "```bash",
157
- "bumpy add",
158
- "```\n",
159
- "---",
160
- `_This comment is maintained by [bumpy](https://github.com/dmno-dev/bumpy)._`
161
- ].join("\n");
162
- }
163
- const FROG_IMG_BASE = "https://raw.githubusercontent.com/dmno-dev/bumpy/main/images";
164
- function bumpSectionHeader(type) {
165
- return `### ${`<img src="${FROG_IMG_BASE}/frog-${type}.png" alt="${type}" width="52" style="image-rendering: pixelated;" align="right" />`} ${type.charAt(0).toUpperCase() + type.slice(1)} releases`;
166
- }
167
- function formatVersionPrBody(plan, preamble) {
168
- const lines = [];
169
- lines.push(preamble);
170
- lines.push("");
171
- const groups = {
172
- major: [],
173
- minor: [],
174
- patch: []
175
- };
176
- for (const r of plan.releases) groups[r.type]?.push(r);
177
- for (const type of [
178
- "major",
179
- "minor",
180
- "patch"
181
- ]) {
182
- const releases = groups[type];
183
- if (!releases || releases.length === 0) continue;
184
- lines.push(bumpSectionHeader(type));
185
- lines.push("");
186
- for (const r of releases) {
187
- const suffix = r.isDependencyBump ? " (dep)" : r.isCascadeBump ? " (cascade)" : "";
188
- lines.push(`- \`${r.name}\` ${r.oldVersion} → **${r.newVersion}**${suffix}`);
189
- }
190
- lines.push("");
191
- }
192
- return lines.join("\n");
193
- }
194
- const COMMENT_MARKER = "<!-- bumpy-release-plan -->";
195
- async function postOrUpdatePrComment(prNumber, body, rootDir) {
196
- const markedBody = `${COMMENT_MARKER}\n${body}`;
197
- try {
198
- const existingComment = tryRun(`gh pr view ${prNumber} --json comments --jq '.comments[] | select(.body | startswith("${COMMENT_MARKER}")) | .id' | head -1`, { cwd: rootDir });
199
- if (existingComment) {
200
- await runAsync(`gh api repos/{owner}/{repo}/issues/comments/${existingComment} -X PATCH -f body=@-`, {
201
- cwd: rootDir,
202
- input: markedBody
203
- });
204
- log.dim(" Updated PR comment");
205
- } else {
206
- await runAsync(`gh pr comment ${prNumber} --body-file -`, {
207
- cwd: rootDir,
208
- input: markedBody
209
- });
210
- log.dim(" Posted PR comment");
211
- }
212
- } catch (err) {
213
- log.warn(` Failed to comment on PR: ${err instanceof Error ? err.message : err}`);
214
- }
215
- }
216
- function detectPrNumber() {
217
- if (process.env.GITHUB_EVENT_NAME === "pull_request") {
218
- const match = process.env.GITHUB_REF?.match(/refs\/pull\/(\d+)\//);
219
- if (match) return match[1];
220
- }
221
- return process.env.BUMPY_PR_NUMBER || process.env.PR_NUMBER || null;
222
- }
223
- //#endregion
224
- export { ciCheckCommand, ciReleaseCommand };
@@ -1,51 +0,0 @@
1
- import { i as __exportAll } from "./logger-ZqggsyGZ.mjs";
2
- import { access, mkdir, readFile, readdir, unlink, writeFile } from "node:fs/promises";
3
- //#region src/utils/fs.ts
4
- var fs_exports = /* @__PURE__ */ __exportAll({
5
- ensureDir: () => ensureDir,
6
- exists: () => exists,
7
- listFiles: () => listFiles,
8
- readJson: () => readJson,
9
- readText: () => readText,
10
- removeFile: () => removeFile,
11
- writeJson: () => writeJson,
12
- writeText: () => writeText
13
- });
14
- async function readJson(filePath) {
15
- const content = await readFile(filePath, "utf-8");
16
- return JSON.parse(content);
17
- }
18
- async function writeJson(filePath, data, indent = 2) {
19
- await writeFile(filePath, JSON.stringify(data, null, indent) + "\n", "utf-8");
20
- }
21
- async function readText(filePath) {
22
- return readFile(filePath, "utf-8");
23
- }
24
- async function writeText(filePath, content) {
25
- await writeFile(filePath, content, "utf-8");
26
- }
27
- async function exists(filePath) {
28
- try {
29
- await access(filePath);
30
- return true;
31
- } catch {
32
- return false;
33
- }
34
- }
35
- async function listFiles(dir, ext) {
36
- try {
37
- const entries = await readdir(dir);
38
- if (ext) return entries.filter((e) => e.endsWith(ext));
39
- return entries;
40
- } catch {
41
- return [];
42
- }
43
- }
44
- async function removeFile(filePath) {
45
- await unlink(filePath);
46
- }
47
- async function ensureDir(dir) {
48
- await mkdir(dir, { recursive: true });
49
- }
50
- //#endregion
51
- export { readJson as a, writeJson as c, listFiles as i, writeText as l, exists as n, readText as o, fs_exports as r, removeFile as s, ensureDir as t };
@@ -1,176 +0,0 @@
1
- //#region \0rolldown/runtime.js
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
9
- var __exportAll = (all, no_symbols) => {
10
- let target = {};
11
- for (var name in all) __defProp(target, name, {
12
- get: all[name],
13
- enumerable: true
14
- });
15
- if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
16
- return target;
17
- };
18
- var __copyProps = (to, from, except, desc) => {
19
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
20
- key = keys[i];
21
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
22
- get: ((k) => from[k]).bind(null, key),
23
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
24
- });
25
- }
26
- return to;
27
- };
28
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
29
- value: mod,
30
- enumerable: true
31
- }) : target, mod));
32
- const { Ansis, fg, bg, rgb, bgRgb, hex, bgHex, reset, inverse, hidden, visible, bold, dim, italic, underline, strikethrough, black, red, green, yellow, blue, magenta, cyan, white, gray, redBright, greenBright, yellowBright, blueBright, magentaBright, cyanBright, whiteBright, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bgGray, bgRedBright, bgGreenBright, bgYellowBright, bgBlueBright, bgMagentaBright, bgCyanBright, bgWhiteBright } = (/* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
33
- let e, t, r, { defineProperty: l, setPrototypeOf: n, create: o, keys: s } = Object, i = "", { round: c, max: a } = Math, p = (e) => {
34
- let t = /([a-f\d]{3,6})/i.exec(e)?.[1], r = t?.length, l = parseInt(6 ^ r ? 3 ^ r ? "0" : t[0] + t[0] + t[1] + t[1] + t[2] + t[2] : t, 16);
35
- return [
36
- l >> 16 & 255,
37
- l >> 8 & 255,
38
- 255 & l
39
- ];
40
- }, u = (e, t, r) => e ^ t || t ^ r ? 16 + 36 * c(e / 51) + 6 * c(t / 51) + c(r / 51) : 8 > e ? 16 : e > 248 ? 231 : c(24 * (e - 8) / 247) + 232, d = (e) => {
41
- let t, r, l, n, o;
42
- return 8 > e ? 30 + e : 16 > e ? e - 8 + 90 : (232 > e ? (o = (e -= 16) % 36, t = (e / 36 | 0) / 5, r = (o / 6 | 0) / 5, l = o % 6 / 5) : t = r = l = (10 * (e - 232) + 8) / 255, n = 2 * a(t, r, l), n ? 30 + (c(l) << 2 | c(r) << 1 | c(t)) + (2 ^ n ? 0 : 60) : 30);
43
- }, f = (() => {
44
- let r = (e) => o.some(((t) => e.test(t))), l = globalThis, n = l.process ?? {}, o = n.argv ?? [], i = n.env ?? {}, c = -1;
45
- try {
46
- e = "," + s(i).join(",");
47
- } catch (e) {
48
- i = {}, c = 0;
49
- }
50
- let a = "FORCE_COLOR", p = {
51
- false: 0,
52
- 0: 0,
53
- 1: 1,
54
- 2: 2,
55
- 3: 3
56
- }[i[a]] ?? -1, u = a in i && p || r(/^--color=?(true|always)?$/);
57
- return u && (c = p), ~c || (c = ((r, l, n) => (t = r.TERM, {
58
- "24bit": 3,
59
- truecolor: 3,
60
- ansi256: 2,
61
- ansi: 1
62
- }[r.COLORTERM] || (r.CI ? /,GITHUB/.test(e) ? 3 : 1 : l && "dumb" !== t ? n ? 3 : /-256/.test(t) ? 2 : 1 : 0)))(i, !!i.PM2_HOME || i.NEXT_RUNTIME?.includes("edge") || !!n.stdout?.isTTY, "win32" === n.platform)), !p || i.NO_COLOR || r(/^--(no-color|color=(false|never))$/) ? 0 : l.window?.chrome || u && !c ? 3 : c;
63
- })(), g = {
64
- open: i,
65
- close: i
66
- }, h = 39, b = 49, O = {}, m = ({ p: e }, { open: t, close: l }) => {
67
- let o = (e, ...r) => {
68
- if (!e) {
69
- if (t && t === l) return t;
70
- if ((e ?? i) === i) return i;
71
- }
72
- let n, s = e.raw ? String.raw({ raw: e }, ...r) : i + e, c = o.p, a = c.o, p = c.c;
73
- if (s.includes("\x1B")) for (; c; c = c.p) {
74
- let { open: e, close: t } = c, r = t.length, l = i, o = 0;
75
- if (r) for (; ~(n = s.indexOf(t, o)); o = n + r) l += s.slice(o, n) + e;
76
- s = l + s.slice(o);
77
- }
78
- return a + (s.includes("\n") ? s.replace(/(\r?\n)/g, p + "$1" + a) : s) + p;
79
- }, s = t, c = l;
80
- return e && (s = e.o + t, c = l + e.c), n(o, r), o.p = {
81
- open: t,
82
- close: l,
83
- o: s,
84
- c,
85
- p: e
86
- }, o.open = s, o.close = c, o;
87
- };
88
- const w = new function e(t = f) {
89
- let s = {
90
- Ansis: e,
91
- level: t,
92
- isSupported: () => a,
93
- strip: (e) => e.replace(/[›][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, i),
94
- extend(e) {
95
- for (let t in e) {
96
- let r = e[t], l = (typeof r)[0];
97
- "s" === l ? (c(t, T(...p(r))), c(_(t), v(...p(r)))) : c(t, r, "f" === l);
98
- }
99
- return r = o({}, O), n(s, r), s;
100
- }
101
- }, c = (e, t, r) => {
102
- O[e] = { get() {
103
- let n = r ? (...e) => m(this, t(...e)) : m(this, t);
104
- return l(this, e, { value: n }), n;
105
- } };
106
- }, a = t > 0, w = (e, t) => a ? {
107
- open: `[${e}m`,
108
- close: `[${t}m`
109
- } : g, y = (e) => (t) => e(...p(t)), R = (e, t) => (r, l, n) => w(`${e}8;2;${r};${l};${n}`, t), $ = (e, t) => (r, l, n) => w(((e, t, r) => d(u(e, t, r)))(r, l, n) + e, t), x = (e) => (t, r, l) => e(u(t, r, l)), T = R(3, h), v = R(4, b), C = (e) => w("38;5;" + e, h), E = (e) => w("48;5;" + e, b);
110
- 2 === t ? (T = x(C), v = x(E)) : 1 === t && (T = $(0, h), v = $(10, b), C = (e) => w(d(e), h), E = (e) => w(d(e) + 10, b));
111
- let M, I = {
112
- fg: C,
113
- bg: E,
114
- rgb: T,
115
- bgRgb: v,
116
- hex: y(T),
117
- bgHex: y(v),
118
- visible: g,
119
- reset: w(0, 0),
120
- bold: w(1, 22),
121
- dim: w(2, 22),
122
- italic: w(3, 23),
123
- underline: w(4, 24),
124
- inverse: w(7, 27),
125
- hidden: w(8, 28),
126
- strikethrough: w(9, 29)
127
- }, _ = (e) => "bg" + e[0].toUpperCase() + e.slice(1), k = "Bright";
128
- return "black,red,green,yellow,blue,magenta,cyan,white,gray".split(",").map(((e, t) => {
129
- M = _(e), 8 > t ? (I[e + k] = w(90 + t, h), I[M + k] = w(100 + t, b)) : t = 60, I[e] = w(30 + t, h), I[M] = w(40 + t, b);
130
- })), s.extend(I);
131
- }();
132
- module.exports = w, w.default = w;
133
- })))(), 1)).default;
134
- //#endregion
135
- //#region src/utils/logger.ts
136
- const log = {
137
- info(msg) {
138
- console.log(`${blue`info`} ${msg}`);
139
- },
140
- success(msg) {
141
- console.log(`${green`done`} ${msg}`);
142
- },
143
- warn(msg) {
144
- console.log(`${yellow`warn`} ${msg}`);
145
- },
146
- error(msg) {
147
- console.error(`${red`error`} ${msg}`);
148
- },
149
- step(msg) {
150
- console.log(`${cyan`=>`} ${msg}`);
151
- },
152
- dim(msg) {
153
- console.log(dim`${msg}`);
154
- },
155
- bold(msg) {
156
- console.log(bold`${msg}`);
157
- },
158
- table(rows) {
159
- if (rows.length === 0) return;
160
- const colWidths = rows[0].map((_, i) => Math.max(...rows.map((r) => (r[i] ?? "").length)));
161
- for (const row of rows) console.log(row.map((cell, i) => cell.padEnd(colWidths[i])).join(" "));
162
- }
163
- };
164
- function colorize(text, color) {
165
- return {
166
- red,
167
- green,
168
- yellow,
169
- blue,
170
- cyan,
171
- dim,
172
- bold
173
- }[color](text);
174
- }
175
- //#endregion
176
- export { __toESM as a, __exportAll as i, log as n, __commonJSMin as r, colorize as t };
@@ -1,46 +0,0 @@
1
- import * as readline from "node:readline";
2
- //#region src/utils/prompt.ts
3
- function createInterface() {
4
- return readline.createInterface({
5
- input: process.stdin,
6
- output: process.stdout
7
- });
8
- }
9
- async function ask(question, defaultValue) {
10
- const rl = createInterface();
11
- const suffix = defaultValue ? ` (${defaultValue})` : "";
12
- return new Promise((resolve) => {
13
- rl.question(`${question}${suffix}: `, (answer) => {
14
- rl.close();
15
- resolve(answer.trim() || defaultValue || "");
16
- });
17
- });
18
- }
19
- async function confirm(question, defaultYes = true) {
20
- const answer = await ask(`${question} [${defaultYes ? "Y/n" : "y/N"}]`);
21
- if (!answer) return defaultYes;
22
- return answer.toLowerCase().startsWith("y");
23
- }
24
- async function select(question, options) {
25
- console.log(question);
26
- for (let i = 0; i < options.length; i++) console.log(` ${i + 1}) ${options[i].label}`);
27
- const answer = await ask("Choose");
28
- const idx = parseInt(answer, 10) - 1;
29
- if (idx >= 0 && idx < options.length) return options[idx].value;
30
- const match = options.find((o) => o.value === answer || o.label.toLowerCase() === answer.toLowerCase());
31
- if (match) return match.value;
32
- return options[0].value;
33
- }
34
- async function multiSelect(question, options) {
35
- console.log(question);
36
- for (let i = 0; i < options.length; i++) {
37
- const mark = options[i].checked ? "[x]" : "[ ]";
38
- console.log(` ${i + 1}) ${mark} ${options[i].label}`);
39
- }
40
- const answer = await ask("Select (comma-separated numbers, or 'all')");
41
- if (answer.toLowerCase() === "all") return options.map((o) => o.value);
42
- if (!answer) return options.filter((o) => o.checked).map((o) => o.value);
43
- return answer.split(",").map((s) => parseInt(s.trim(), 10) - 1).filter((i) => i >= 0 && i < options.length).map((i) => options[i].value);
44
- }
45
- //#endregion
46
- export { select as i, confirm as n, multiSelect as r, ask as t };
@@ -1,173 +0,0 @@
1
- import { g as parseIsolatedBump, h as maxBump, l as DEFAULT_BUMP_RULES, m as hasCascade, p as bumpLevel, s as matchGlob } from "./config-CJ2orhTL.mjs";
2
- import { n as satisfies, r as stripProtocol, t as bumpVersion } from "./semver-DWO6NFKN.mjs";
3
- //#region src/core/release-plan.ts
4
- /**
5
- * Build a release plan from pending changesets, the dependency graph, and config.
6
- * This is the core algorithm of bumpy.
7
- */
8
- function assembleReleasePlan(changesets, packages, depGraph, config) {
9
- if (changesets.length === 0) return {
10
- changesets: [],
11
- releases: []
12
- };
13
- const planned = /* @__PURE__ */ new Map();
14
- const cascadeOverrides = /* @__PURE__ */ new Map();
15
- for (const cs of changesets) for (const release of cs.releases) {
16
- if (!packages.has(release.name)) continue;
17
- const { bump, isolated } = parseIsolatedBump(release.type);
18
- const existing = planned.get(release.name);
19
- if (existing) {
20
- existing.type = maxBump(existing.type, bump);
21
- if (!isolated) existing.isolated = false;
22
- existing.changesets.add(cs.id);
23
- } else planned.set(release.name, {
24
- type: bump,
25
- isolated,
26
- isDependencyBump: false,
27
- isCascadeBump: false,
28
- changesets: new Set([cs.id])
29
- });
30
- if (hasCascade(release)) {
31
- if (!cascadeOverrides.has(release.name)) cascadeOverrides.set(release.name, /* @__PURE__ */ new Map());
32
- const overrides = cascadeOverrides.get(release.name);
33
- for (const [pattern, bumpType] of Object.entries(release.cascade)) {
34
- const existing = overrides.get(pattern);
35
- overrides.set(pattern, maxBump(existing, bumpType));
36
- }
37
- }
38
- }
39
- for (const group of config.fixed) {
40
- let groupBump;
41
- let groupIsolated = true;
42
- for (const nameOrGlob of group) for (const [name, bump] of planned) if (matchGlob(name, nameOrGlob)) {
43
- groupBump = maxBump(groupBump, bump.type);
44
- if (!bump.isolated) groupIsolated = false;
45
- }
46
- if (!groupBump) continue;
47
- for (const nameOrGlob of group) for (const [name] of packages) {
48
- if (!matchGlob(name, nameOrGlob)) continue;
49
- const existing = planned.get(name);
50
- if (existing) {
51
- existing.type = groupBump;
52
- existing.isolated = groupIsolated;
53
- } else planned.set(name, {
54
- type: groupBump,
55
- isolated: groupIsolated,
56
- isDependencyBump: false,
57
- isCascadeBump: false,
58
- changesets: /* @__PURE__ */ new Set()
59
- });
60
- }
61
- }
62
- for (const group of config.linked) {
63
- let groupBump;
64
- for (const nameOrGlob of group) for (const [name, bump] of planned) if (matchGlob(name, nameOrGlob)) groupBump = maxBump(groupBump, bump.type);
65
- if (!groupBump) continue;
66
- for (const nameOrGlob of group) for (const [name] of packages) {
67
- if (!matchGlob(name, nameOrGlob)) continue;
68
- const existing = planned.get(name);
69
- if (existing) existing.type = groupBump;
70
- }
71
- }
72
- let changed = true;
73
- let iterations = 0;
74
- const MAX_ITERATIONS = 100;
75
- while (changed && iterations < MAX_ITERATIONS) {
76
- changed = false;
77
- iterations++;
78
- for (const [pkgName, bump] of planned) {
79
- if (bump.isolated) continue;
80
- const csOverrides = cascadeOverrides.get(pkgName);
81
- if (csOverrides) for (const [pattern, cascadeBumpType] of csOverrides) for (const [targetName] of packages) {
82
- if (!matchGlob(targetName, pattern)) continue;
83
- if (applyBump(planned, targetName, cascadeBumpType, false, true, bump.changesets)) changed = true;
84
- }
85
- const cascadeTo = packages.get(pkgName)?.bumpy?.cascadeTo;
86
- if (cascadeTo) for (const [pattern, rule] of Object.entries(cascadeTo)) {
87
- if (!shouldTrigger(bump.type, rule.trigger)) continue;
88
- const cascadeBump = rule.bumpAs === "match" ? bump.type : rule.bumpAs;
89
- for (const [targetName] of packages) {
90
- if (!matchGlob(targetName, pattern)) continue;
91
- if (applyBump(planned, targetName, cascadeBump, false, true, bump.changesets)) changed = true;
92
- }
93
- }
94
- const dependents = depGraph.getDependents(pkgName);
95
- for (const dep of dependents) {
96
- const rule = resolveRule(dep.name, pkgName, dep.depType, packages, config);
97
- if (!shouldTrigger(bump.type, rule.trigger)) continue;
98
- if (config.updateInternalDependencies === "out-of-range") {
99
- if (satisfies(bumpVersion(packages.get(pkgName).version, bump.type), stripProtocol(dep.versionRange))) continue;
100
- }
101
- if (config.updateInternalDependencies === "none") continue;
102
- if (config.updateInternalDependencies === "minor" && bumpLevel(bump.type) < bumpLevel("minor")) continue;
103
- const depBump = rule.bumpAs === "match" ? bump.type : rule.bumpAs;
104
- if (applyBump(planned, dep.name, depBump, true, false, bump.changesets)) changed = true;
105
- }
106
- }
107
- }
108
- const releases = [];
109
- for (const [name, bump] of planned) {
110
- const pkg = packages.get(name);
111
- if (!pkg) continue;
112
- const newVersion = bumpVersion(pkg.version, bump.type);
113
- releases.push({
114
- name,
115
- type: bump.type,
116
- oldVersion: pkg.version,
117
- newVersion,
118
- changesets: [...bump.changesets],
119
- isDependencyBump: bump.isDependencyBump,
120
- isCascadeBump: bump.isCascadeBump
121
- });
122
- }
123
- releases.sort((a, b) => a.name.localeCompare(b.name));
124
- return {
125
- changesets,
126
- releases
127
- };
128
- }
129
- /** Apply a bump to a package, upgrading if already planned. Returns true if anything changed. */
130
- function applyBump(planned, name, type, isDependencyBump, isCascadeBump, sourceChangesets) {
131
- const existing = planned.get(name);
132
- if (existing) {
133
- const newType = maxBump(existing.type, type);
134
- if (newType === existing.type) return false;
135
- existing.type = newType;
136
- if (isDependencyBump) existing.isDependencyBump = true;
137
- if (isCascadeBump) existing.isCascadeBump = true;
138
- for (const cs of sourceChangesets) existing.changesets.add(cs);
139
- return true;
140
- }
141
- planned.set(name, {
142
- type,
143
- isolated: false,
144
- isDependencyBump,
145
- isCascadeBump,
146
- changesets: new Set(sourceChangesets)
147
- });
148
- return true;
149
- }
150
- /** Check if a bump level meets the trigger threshold */
151
- function shouldTrigger(bumpType, trigger) {
152
- if (trigger === "none") return false;
153
- return bumpLevel(bumpType) >= bumpLevel(trigger);
154
- }
155
- /**
156
- * Resolve the dependency bump rule for a specific dependent/dependency pair.
157
- * Priority: specificDependencyRules > per-package depType rules > global depType rules > defaults
158
- */
159
- function resolveRule(dependentName, dependencyName, depType, packages, config) {
160
- const dependent = packages.get(dependentName);
161
- if (dependent?.bumpy?.specificDependencyRules?.[dependencyName]) return dependent.bumpy.specificDependencyRules[dependencyName];
162
- if (dependent?.bumpy?.specificDependencyRules) {
163
- for (const [pattern, rule] of Object.entries(dependent.bumpy.specificDependencyRules)) if (matchGlob(dependencyName, pattern)) return rule;
164
- }
165
- if (dependent?.bumpy?.dependencyBumpRules?.[depType]) return dependent.bumpy.dependencyBumpRules[depType];
166
- if (config.dependencyBumpRules[depType]) return config.dependencyBumpRules[depType];
167
- return DEFAULT_BUMP_RULES[depType] || {
168
- trigger: "patch",
169
- bumpAs: "patch"
170
- };
171
- }
172
- //#endregion
173
- export { assembleReleasePlan as t };