@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
package/dist/index.d.mts CHANGED
@@ -1,20 +1,16 @@
1
1
  //#region src/types.d.ts
2
2
  type BumpType = 'major' | 'minor' | 'patch';
3
- type BumpTypeWithIsolated = BumpType | 'minor-isolated' | 'patch-isolated';
3
+ type BumpTypeWithNone = BumpType | 'none';
4
4
  declare const BUMP_LEVELS: Record<BumpType, number>;
5
5
  declare function bumpLevel(type: BumpType): number;
6
- declare function parseIsolatedBump(type: BumpTypeWithIsolated): {
7
- bump: BumpType;
8
- isolated: boolean;
9
- };
10
6
  declare function maxBump(a: BumpType | undefined, b: BumpType): BumpType;
11
7
  interface DependencyBumpRule {
12
8
  /** What bump level in the dependency triggers propagation */
13
- trigger: BumpType | 'none';
9
+ trigger: BumpType;
14
10
  /** What bump to apply to the dependent */
15
11
  bumpAs: BumpType | 'match';
16
12
  }
17
- declare const DEFAULT_BUMP_RULES: Record<string, DependencyBumpRule>;
13
+ declare const DEFAULT_BUMP_RULES: Record<string, DependencyBumpRule | false>;
18
14
  type DepType = 'dependencies' | 'devDependencies' | 'peerDependencies' | 'optionalDependencies';
19
15
  declare const DEP_TYPES: DepType[];
20
16
  interface PublishConfig {
@@ -44,12 +40,22 @@ interface BumpyConfig {
44
40
  ignore: string[];
45
41
  /** Package names/globs to explicitly include (overrides private + ignore) */
46
42
  include: string[];
47
- updateInternalDependencies: 'patch' | 'minor' | 'out-of-range' | 'none';
48
- dependencyBumpRules: Partial<Record<DepType, DependencyBumpRule>>;
43
+ updateInternalDependencies: 'patch' | 'minor' | 'out-of-range';
44
+ dependencyBumpRules: Partial<Record<DepType, DependencyBumpRule | false>>;
49
45
  privatePackages: {
50
46
  version: boolean;
51
47
  tag: boolean;
52
48
  };
49
+ /**
50
+ * Allow per-package custom commands (buildCommand, publishCommand, checkPublished)
51
+ * defined in package.json "bumpy" fields.
52
+ * Commands defined in the root config's `packages` map are always trusted.
53
+ *
54
+ * true = allow all packages to define custom commands
55
+ * string[] = allow only matching package names/globs
56
+ * false = only root-config commands are allowed (default)
57
+ */
58
+ allowCustomCommands: boolean | string[];
53
59
  packages: Record<string, PackageConfig>;
54
60
  publish: PublishConfig;
55
61
  /**
@@ -84,26 +90,25 @@ interface PackageConfig {
84
90
  skipNpmPublish?: boolean;
85
91
  /** Command to check if a version is already published. Should output the published version string. */
86
92
  checkPublished?: string;
87
- dependencyBumpRules?: Partial<Record<DepType, DependencyBumpRule>>;
88
- specificDependencyRules?: Record<string, DependencyBumpRule>;
93
+ dependencyBumpRules?: Partial<Record<DepType, DependencyBumpRule | false>>;
89
94
  cascadeTo?: Record<string, DependencyBumpRule>;
90
95
  }
91
96
  declare const DEFAULT_PUBLISH_CONFIG: PublishConfig;
92
97
  declare const DEFAULT_CONFIG: BumpyConfig;
93
- interface ChangesetReleaseSimple {
98
+ interface BumpFileReleaseSimple {
94
99
  name: string;
95
- type: BumpTypeWithIsolated;
100
+ type: BumpTypeWithNone;
96
101
  }
97
- interface ChangesetReleaseCascade {
102
+ interface BumpFileReleaseCascade {
98
103
  name: string;
99
- type: BumpTypeWithIsolated;
104
+ type: BumpTypeWithNone;
100
105
  cascade: Record<string, BumpType>;
101
106
  }
102
- type ChangesetRelease = ChangesetReleaseSimple | ChangesetReleaseCascade;
103
- declare function hasCascade(r: ChangesetRelease): r is ChangesetReleaseCascade;
104
- interface Changeset {
107
+ type BumpFileRelease = BumpFileReleaseSimple | BumpFileReleaseCascade;
108
+ declare function hasCascade(r: BumpFileRelease): r is BumpFileReleaseCascade;
109
+ interface BumpFile {
105
110
  id: string;
106
- releases: ChangesetRelease[];
111
+ releases: BumpFileRelease[];
107
112
  summary: string;
108
113
  }
109
114
  interface WorkspacePackage {
@@ -131,13 +136,14 @@ interface PlannedRelease {
131
136
  type: BumpType;
132
137
  oldVersion: string;
133
138
  newVersion: string;
134
- changesets: string[];
139
+ bumpFiles: string[];
135
140
  isDependencyBump: boolean;
136
141
  isCascadeBump: boolean;
137
142
  }
138
143
  interface ReleasePlan {
139
- changesets: Changeset[];
144
+ bumpFiles: BumpFile[];
140
145
  releases: PlannedRelease[];
146
+ warnings: string[];
141
147
  }
142
148
  //#endregion
143
149
  //#region src/core/config.d.ts
@@ -175,30 +181,35 @@ declare class DependencyGraph {
175
181
  topologicalSort(packages: Map<string, WorkspacePackage>): string[];
176
182
  }
177
183
  //#endregion
178
- //#region src/core/changeset.d.ts
179
- /** Read all changeset files from .bumpy/ directory */
180
- declare function readChangesets(rootDir: string): Promise<Changeset[]>;
181
- /** Parse changeset content (for testing) */
182
- declare function parseChangeset(content: string, id: string): Changeset | null;
183
- /** Write a changeset file */
184
- declare function writeChangeset(rootDir: string, filename: string, releases: ChangesetRelease[], summary: string): Promise<string>;
184
+ //#region src/core/bump-file.d.ts
185
+ /** Read all bump files from .bumpy/ directory, sorted by git creation order */
186
+ declare function readBumpFiles(rootDir: string): Promise<BumpFile[]>;
187
+ /** Parse bump file content (for testing) */
188
+ declare function parseBumpFile(content: string, id: string): BumpFile | null;
189
+ /** Write a bump file */
190
+ declare function writeBumpFile(rootDir: string, filename: string, releases: BumpFileRelease[], summary: string): Promise<string>;
185
191
  //#endregion
186
192
  //#region src/core/release-plan.d.ts
187
193
  /**
188
- * Build a release plan from pending changesets, the dependency graph, and config.
194
+ * Build a release plan from pending bump files, the dependency graph, and config.
189
195
  * This is the core algorithm of bumpy.
196
+ *
197
+ * The propagation loop runs three phases until stable:
198
+ * Phase A — fix out-of-range dependencies (always runs)
199
+ * Phase B — enforce fixed/linked group constraints
200
+ * Phase C — apply cascades and proactive propagation rules
190
201
  */
191
- declare function assembleReleasePlan(changesets: Changeset[], packages: Map<string, WorkspacePackage>, depGraph: DependencyGraph, config: BumpyConfig): ReleasePlan;
202
+ declare function assembleReleasePlan(bumpFiles: BumpFile[], packages: Map<string, WorkspacePackage>, depGraph: DependencyGraph, config: BumpyConfig): ReleasePlan;
192
203
  //#endregion
193
204
  //#region src/core/apply-release-plan.d.ts
194
- /** Apply the release plan: bump versions, update changelogs, delete changesets */
205
+ /** Apply the release plan: bump versions, update changelogs, delete bump files */
195
206
  declare function applyReleasePlan(releasePlan: ReleasePlan, packages: Map<string, WorkspacePackage>, rootDir: string, config: BumpyConfig): Promise<void>;
196
207
  //#endregion
197
208
  //#region src/core/changelog.d.ts
198
209
  interface ChangelogContext {
199
210
  release: PlannedRelease;
200
- /** Changesets that contributed to this release */
201
- changesets: Changeset[];
211
+ /** Bump files that contributed to this release */
212
+ bumpFiles: BumpFile[];
202
213
  /** ISO date string (YYYY-MM-DD) */
203
214
  date: string;
204
215
  }
@@ -215,14 +226,29 @@ declare const defaultFormatter: ChangelogFormatter;
215
226
  */
216
227
  declare function loadFormatter(changelog: BumpyConfig['changelog'], rootDir: string): Promise<ChangelogFormatter>;
217
228
  /** Generate a changelog entry using the configured formatter */
218
- declare function generateChangelogEntry(release: PlannedRelease, changesets: Changeset[], formatter?: ChangelogFormatter, date?: string): Promise<string>;
229
+ declare function generateChangelogEntry(release: PlannedRelease, bumpFiles: BumpFile[], formatter?: ChangelogFormatter, date?: string): Promise<string>;
219
230
  /** Prepend a new entry to an existing CHANGELOG.md content */
220
231
  declare function prependToChangelog(existingContent: string, newEntry: string): string;
221
232
  //#endregion
233
+ //#region src/core/changelog-github.d.ts
234
+ interface GithubChangelogOptions {
235
+ /** "owner/repo" — auto-detected from gh CLI if not provided */
236
+ repo?: string;
237
+ /** Whether to include "Thanks @user" messages for contributors (default: true) */
238
+ thankContributors?: boolean;
239
+ /** GitHub usernames (without @) to skip "Thanks" messages for (e.g. internal team members) */
240
+ internalAuthors?: string[];
241
+ }
242
+ //#endregion
222
243
  //#region src/core/semver.d.ts
223
244
  declare function bumpVersion(version: string, type: BumpType): string;
224
- /** Check if a version satisfies a range */
225
- declare function satisfies(version: string, range: string): boolean;
245
+ /**
246
+ * Check if a version satisfies a range.
247
+ * @param version - The version to check
248
+ * @param range - The version range (may include workspace: or catalog: protocol)
249
+ * @param currentVersion - The dependency's current version, used to resolve workspace:^ and workspace:~
250
+ */
251
+ declare function satisfies(version: string, range: string, currentVersion?: string): boolean;
226
252
  /** Strip workspace: protocol from version ranges */
227
253
  declare function stripProtocol(range: string): string;
228
254
  //#endregion
@@ -251,4 +277,4 @@ interface PublishResult {
251
277
  */
252
278
  declare function publishPackages(releasePlan: ReleasePlan, packages: Map<string, WorkspacePackage>, depGraph: DependencyGraph, config: BumpyConfig, rootDir: string, opts?: PublishOptions, catalogs?: CatalogMap, detectedPm?: PackageManager): Promise<PublishResult>;
253
279
  //#endregion
254
- export { BUMP_LEVELS, BumpType, BumpTypeWithIsolated, BumpyConfig, type ChangelogContext, type ChangelogFormatter, Changeset, ChangesetRelease, ChangesetReleaseCascade, ChangesetReleaseSimple, DEFAULT_BUMP_RULES, DEFAULT_CONFIG, DEFAULT_PUBLISH_CONFIG, DEP_TYPES, DepType, DependencyBumpRule, DependencyGraph, DependentInfo, PackageConfig, PackageManager, PlannedRelease, PublishConfig, ReleasePlan, WorkspacePackage, applyReleasePlan, assembleReleasePlan, bumpLevel, bumpVersion, defaultFormatter, discoverPackages, findRoot, generateChangelogEntry, getBumpyDir, hasCascade, loadConfig, loadFormatter, matchGlob, maxBump, parseChangeset, parseIsolatedBump, prependToChangelog, publishPackages, readChangesets, satisfies, stripProtocol, writeChangeset };
280
+ export { BUMP_LEVELS, BumpFile, BumpFileRelease, BumpFileReleaseCascade, BumpFileReleaseSimple, BumpType, BumpTypeWithNone, BumpyConfig, type ChangelogContext, type ChangelogFormatter, DEFAULT_BUMP_RULES, DEFAULT_CONFIG, DEFAULT_PUBLISH_CONFIG, DEP_TYPES, DepType, DependencyBumpRule, DependencyGraph, DependentInfo, type GithubChangelogOptions, PackageConfig, PackageManager, PlannedRelease, PublishConfig, ReleasePlan, WorkspacePackage, applyReleasePlan, assembleReleasePlan, bumpLevel, bumpVersion, defaultFormatter, discoverPackages, findRoot, generateChangelogEntry, getBumpyDir, hasCascade, loadConfig, loadFormatter, matchGlob, maxBump, parseBumpFile, prependToChangelog, publishPackages, readBumpFiles, satisfies, stripProtocol, writeBumpFile };
package/dist/index.mjs CHANGED
@@ -1,9 +1,9 @@
1
- import { a as loadConfig, c as BUMP_LEVELS, d as DEFAULT_PUBLISH_CONFIG, f as DEP_TYPES, g as parseIsolatedBump, h as maxBump, l as DEFAULT_BUMP_RULES, m as hasCascade, n as findRoot, p as bumpLevel, r as getBumpyDir, s as matchGlob, u as DEFAULT_CONFIG } from "./config-CJ2orhTL.mjs";
2
- import { t as discoverPackages } from "./workspace-mVjawG8g.mjs";
3
- import { t as DependencyGraph } from "./dep-graph-DiLeAhl9.mjs";
4
- import { i as writeChangeset, n as parseChangeset, r as readChangesets } from "./changeset-ClCYsChu.mjs";
5
- import { n as satisfies, r as stripProtocol, t as bumpVersion } from "./semver-DWO6NFKN.mjs";
6
- import { t as assembleReleasePlan } from "./release-plan-CFnutSHD.mjs";
7
- import { a as prependToChangelog, i as loadFormatter, n as defaultFormatter, r as generateChangelogEntry, t as applyReleasePlan } from "./apply-release-plan-DtU3rVyL.mjs";
8
- import { t as publishPackages } from "./publish-pipeline-1M5GmbdP.mjs";
9
- export { BUMP_LEVELS, DEFAULT_BUMP_RULES, DEFAULT_CONFIG, DEFAULT_PUBLISH_CONFIG, DEP_TYPES, DependencyGraph, applyReleasePlan, assembleReleasePlan, bumpLevel, bumpVersion, defaultFormatter, discoverPackages, findRoot, generateChangelogEntry, getBumpyDir, hasCascade, loadConfig, loadFormatter, matchGlob, maxBump, parseChangeset, parseIsolatedBump, prependToChangelog, publishPackages, readChangesets, satisfies, stripProtocol, writeChangeset };
1
+ import { a as loadConfig, c as BUMP_LEVELS, d as DEFAULT_PUBLISH_CONFIG, f as DEP_TYPES, h as maxBump, l as DEFAULT_BUMP_RULES, m as hasCascade, n as findRoot, p as bumpLevel, r as getBumpyDir, s as matchGlob, u as DEFAULT_CONFIG } from "./config-XZWUL3ma.mjs";
2
+ import { t as discoverPackages } from "./workspace-C5ULTyUN.mjs";
3
+ import { t as DependencyGraph } from "./dep-graph-E-9-eQ2J.mjs";
4
+ import { i as writeBumpFile, n as parseBumpFile, r as readBumpFiles } from "./bump-file-CCLXMLA8.mjs";
5
+ import { n as satisfies, r as stripProtocol, t as bumpVersion } from "./semver-DfQyVLM_.mjs";
6
+ import { t as assembleReleasePlan } from "./release-plan-Bi5QNSEo.mjs";
7
+ import { a as prependToChangelog, i as loadFormatter, n as defaultFormatter, r as generateChangelogEntry, t as applyReleasePlan } from "./apply-release-plan-CczGWJTk.mjs";
8
+ import { t as publishPackages } from "./publish-pipeline-BwBuKCIk.mjs";
9
+ export { BUMP_LEVELS, DEFAULT_BUMP_RULES, DEFAULT_CONFIG, DEFAULT_PUBLISH_CONFIG, DEP_TYPES, DependencyGraph, applyReleasePlan, assembleReleasePlan, bumpLevel, bumpVersion, defaultFormatter, discoverPackages, findRoot, generateChangelogEntry, getBumpyDir, hasCascade, loadConfig, loadFormatter, matchGlob, maxBump, parseBumpFile, prependToChangelog, publishPackages, readBumpFiles, satisfies, stripProtocol, writeBumpFile };
@@ -1,5 +1,5 @@
1
- import { n as log } from "./logger-ZqggsyGZ.mjs";
2
- import { c as writeJson, l as writeText, n as exists, t as ensureDir } from "./fs-DbNNEyzq.mjs";
1
+ import { n as log } from "./logger-C2dEe5Su.mjs";
2
+ import { d as writeText, n as exists, t as ensureDir, u as writeJson } from "./fs-DYR2XuFE.mjs";
3
3
  import { resolve } from "node:path";
4
4
  //#region src/commands/init.ts
5
5
  async function initCommand(rootDir) {
@@ -13,7 +13,7 @@ async function initCommand(rootDir) {
13
13
  baseBranch: "main",
14
14
  changelog: "default"
15
15
  });
16
- await writeText(resolve(bumpyDir, "README.md"), `# 🐸 Bumpy\n\nThis directory is used by [bumpy](https://github.com/dmno-dev/bumpy) to manage versioning.\n\nChangeset files (\`.md\`) in this directory describe pending version bumps.\nRun \`bumpy add\` to create a new changeset.\n`);
16
+ await writeText(resolve(bumpyDir, "README.md"), `# 🐸 Bumpy\n\nThis directory is used by [bumpy](https://github.com/dmno-dev/bumpy) to manage versioning.\n\nBump files (\`.md\`) in this directory describe pending version bumps.\nRun \`bumpy add\` to create a new bump file.\n`);
17
17
  log.success("Initialized .bumpy/ directory");
18
18
  log.dim(" Created .bumpy/_config.json");
19
19
  log.dim(" Created .bumpy/README.md");
@@ -0,0 +1,135 @@
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
+ //#endregion
33
+ //#region ../../node_modules/.bun/picocolors@1.1.1/node_modules/picocolors/picocolors.js
34
+ var require_picocolors = /* @__PURE__ */ __commonJSMin(((exports, module) => {
35
+ let p = process || {}, argv = p.argv || [], env = p.env || {};
36
+ let isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
37
+ let formatter = (open, close, replace = open) => (input) => {
38
+ let string = "" + input, index = string.indexOf(close, open.length);
39
+ return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
40
+ };
41
+ let replaceClose = (string, close, replace, index) => {
42
+ let result = "", cursor = 0;
43
+ do {
44
+ result += string.substring(cursor, index) + replace;
45
+ cursor = index + close.length;
46
+ index = string.indexOf(close, cursor);
47
+ } while (~index);
48
+ return result + string.substring(cursor);
49
+ };
50
+ let createColors = (enabled = isColorSupported) => {
51
+ let f = enabled ? formatter : () => String;
52
+ return {
53
+ isColorSupported: enabled,
54
+ reset: f("\x1B[0m", "\x1B[0m"),
55
+ bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
56
+ dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
57
+ italic: f("\x1B[3m", "\x1B[23m"),
58
+ underline: f("\x1B[4m", "\x1B[24m"),
59
+ inverse: f("\x1B[7m", "\x1B[27m"),
60
+ hidden: f("\x1B[8m", "\x1B[28m"),
61
+ strikethrough: f("\x1B[9m", "\x1B[29m"),
62
+ black: f("\x1B[30m", "\x1B[39m"),
63
+ red: f("\x1B[31m", "\x1B[39m"),
64
+ green: f("\x1B[32m", "\x1B[39m"),
65
+ yellow: f("\x1B[33m", "\x1B[39m"),
66
+ blue: f("\x1B[34m", "\x1B[39m"),
67
+ magenta: f("\x1B[35m", "\x1B[39m"),
68
+ cyan: f("\x1B[36m", "\x1B[39m"),
69
+ white: f("\x1B[37m", "\x1B[39m"),
70
+ gray: f("\x1B[90m", "\x1B[39m"),
71
+ bgBlack: f("\x1B[40m", "\x1B[49m"),
72
+ bgRed: f("\x1B[41m", "\x1B[49m"),
73
+ bgGreen: f("\x1B[42m", "\x1B[49m"),
74
+ bgYellow: f("\x1B[43m", "\x1B[49m"),
75
+ bgBlue: f("\x1B[44m", "\x1B[49m"),
76
+ bgMagenta: f("\x1B[45m", "\x1B[49m"),
77
+ bgCyan: f("\x1B[46m", "\x1B[49m"),
78
+ bgWhite: f("\x1B[47m", "\x1B[49m"),
79
+ blackBright: f("\x1B[90m", "\x1B[39m"),
80
+ redBright: f("\x1B[91m", "\x1B[39m"),
81
+ greenBright: f("\x1B[92m", "\x1B[39m"),
82
+ yellowBright: f("\x1B[93m", "\x1B[39m"),
83
+ blueBright: f("\x1B[94m", "\x1B[39m"),
84
+ magentaBright: f("\x1B[95m", "\x1B[39m"),
85
+ cyanBright: f("\x1B[96m", "\x1B[39m"),
86
+ whiteBright: f("\x1B[97m", "\x1B[39m"),
87
+ bgBlackBright: f("\x1B[100m", "\x1B[49m"),
88
+ bgRedBright: f("\x1B[101m", "\x1B[49m"),
89
+ bgGreenBright: f("\x1B[102m", "\x1B[49m"),
90
+ bgYellowBright: f("\x1B[103m", "\x1B[49m"),
91
+ bgBlueBright: f("\x1B[104m", "\x1B[49m"),
92
+ bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
93
+ bgCyanBright: f("\x1B[106m", "\x1B[49m"),
94
+ bgWhiteBright: f("\x1B[107m", "\x1B[49m")
95
+ };
96
+ };
97
+ module.exports = createColors();
98
+ module.exports.createColors = createColors;
99
+ }));
100
+ //#endregion
101
+ //#region src/utils/logger.ts
102
+ var import_picocolors = /* @__PURE__ */ __toESM(require_picocolors(), 1);
103
+ const log = {
104
+ info(msg) {
105
+ console.log(`${import_picocolors.default.blue("info")} ${msg}`);
106
+ },
107
+ success(msg) {
108
+ console.log(`${import_picocolors.default.green("done")} ${msg}`);
109
+ },
110
+ warn(msg) {
111
+ console.log(`${import_picocolors.default.yellow("warn")} ${msg}`);
112
+ },
113
+ error(msg) {
114
+ console.error(`${import_picocolors.default.red("error")} ${msg}`);
115
+ },
116
+ step(msg) {
117
+ console.log(`${import_picocolors.default.cyan("=>")} ${msg}`);
118
+ },
119
+ dim(msg) {
120
+ console.log(import_picocolors.default.dim(msg));
121
+ },
122
+ bold(msg) {
123
+ console.log(import_picocolors.default.bold(msg));
124
+ },
125
+ table(rows) {
126
+ if (rows.length === 0) return;
127
+ const colWidths = rows[0].map((_, i) => Math.max(...rows.map((r) => (r[i] ?? "").length)));
128
+ for (const row of rows) console.log(row.map((cell, i) => cell.padEnd(colWidths[i])).join(" "));
129
+ }
130
+ };
131
+ function colorize(text, color) {
132
+ return import_picocolors.default[color](text);
133
+ }
134
+ //#endregion
135
+ export { __exportAll as a, __commonJSMin as i, log as n, __toESM as o, require_picocolors as r, colorize as t };
@@ -1,12 +1,13 @@
1
- import { n as log } from "./logger-ZqggsyGZ.mjs";
2
- import { a as readJson, n as exists, o as readText } from "./fs-DbNNEyzq.mjs";
3
- import { r as getBumpyDir } from "./config-CJ2orhTL.mjs";
4
- import { i as writeChangeset } from "./changeset-ClCYsChu.mjs";
5
- import { n as confirm } from "./prompt-BP8toAOI.mjs";
6
- import { initCommand } from "./init-Blw2GfC_.mjs";
1
+ import { n as log, o as __toESM, r as require_picocolors } from "./logger-C2dEe5Su.mjs";
2
+ import { a as readJson, n as exists, o as readText } from "./fs-DYR2XuFE.mjs";
3
+ import { r as getBumpyDir } from "./config-XZWUL3ma.mjs";
4
+ import { i as writeBumpFile } from "./bump-file-CCLXMLA8.mjs";
5
+ import { a as fe, c as ot, n as O, o as gt, s as mt, t as unwrap } from "./clack-CDRCHrC-.mjs";
6
+ import { initCommand } from "./init-lA9E5pEc.mjs";
7
7
  import { resolve } from "node:path";
8
8
  import { readdir } from "node:fs/promises";
9
9
  //#region src/commands/migrate.ts
10
+ var import_picocolors = /* @__PURE__ */ __toESM(require_picocolors(), 1);
10
11
  async function migrateCommand(rootDir, opts) {
11
12
  const changesetDir = resolve(rootDir, ".changeset");
12
13
  if (!await exists(changesetDir)) {
@@ -25,7 +26,7 @@ async function migrateCommand(rootDir, opts) {
25
26
  }
26
27
  const mdFiles = (await readdir(changesetDir)).filter((f) => f.endsWith(".md") && f !== "README.md");
27
28
  if (mdFiles.length > 0) {
28
- log.step(`Migrating ${mdFiles.length} pending changeset(s)...`);
29
+ log.step(`Migrating ${mdFiles.length} pending changeset(s) to bump files...`);
29
30
  let migrated = 0;
30
31
  for (const file of mdFiles) {
31
32
  const result = parseChangesetFile(await readText(resolve(changesetDir, file)));
@@ -38,26 +39,32 @@ async function migrateCommand(rootDir, opts) {
38
39
  log.dim(` Skipped ${file} (already exists in .bumpy/)`);
39
40
  continue;
40
41
  }
41
- await writeChangeset(rootDir, name, result.releases, result.summary);
42
+ await writeBumpFile(rootDir, name, result.releases, result.summary);
42
43
  migrated++;
43
44
  log.dim(` Migrated ${file}`);
44
45
  }
45
- log.success(`Migrated ${migrated} changeset(s)`);
46
+ log.success(`Migrated ${migrated} bump file(s)`);
46
47
  } else log.info("No pending changesets to migrate.");
47
48
  if (!opts.force) {
48
- console.log();
49
- if (await confirm("Remove .changeset/ directory?", false)) {
49
+ mt(import_picocolors.default.bgCyan(import_picocolors.default.black(" bumpy migrate ")));
50
+ if (unwrap(await ot({
51
+ message: "Remove .changeset/ directory?",
52
+ initialValue: false
53
+ }))) {
54
+ const spin = fe();
55
+ spin.start("Removing .changeset/");
50
56
  const { rm } = await import("node:fs/promises");
51
57
  await rm(changesetDir, { recursive: true });
52
- log.success("Removed .changeset/ directory");
53
- } else log.dim("Keeping .changeset/ — you can remove it manually when ready.");
58
+ spin.stop("Removed .changeset/ directory");
59
+ } else O.info("Keeping .changeset/ — you can remove it manually when ready.");
60
+ gt(import_picocolors.default.green("Cleanup complete"));
54
61
  }
55
62
  console.log();
56
63
  log.success("Migration complete!");
57
64
  log.dim("Review .bumpy/_config.json and adjust settings as needed.");
58
65
  log.dim("Key differences from changesets:");
59
- log.dim(" - peerDependency bumps only propagate on major (not minor)");
60
- log.dim(" - Use 'patch-isolated'/'minor-isolated' to skip propagation");
66
+ log.dim(" - Out-of-range peer dep bumps match the triggering bump level (not always major)");
67
+ log.dim(" - Use 'none' in a bump file to suppress a propagated bump");
61
68
  log.dim(" - Per-package config goes in package.json[\"bumpy\"]");
62
69
  }
63
70
  async function migrateConfig(changesetConfigPath, bumpyDir) {
@@ -75,7 +82,7 @@ async function migrateConfig(changesetConfigPath, bumpyDir) {
75
82
  "updateInternalDependencies",
76
83
  "privatePackages"
77
84
  ]) if (csConfig[field] !== void 0) bumpyConfig[field] = csConfig[field];
78
- const { writeJson } = await import("./fs-DbNNEyzq.mjs").then((n) => n.r);
85
+ const { writeJson } = await import("./fs-DYR2XuFE.mjs").then((n) => n.r);
79
86
  await writeJson(bumpyConfigPath, bumpyConfig);
80
87
  log.dim(" Migrated config fields: " + Object.keys(bumpyConfig).filter((k) => k !== "baseBranch" || bumpyConfig[k] !== "main").join(", "));
81
88
  }
@@ -1,7 +1,8 @@
1
1
  //#region src/utils/names.ts
2
- /** Generate a random adjective-noun name for changeset files */
2
+ /** Generate a random adjective-noun name for bump files */
3
3
  function randomName() {
4
- return `${ADJECTIVES[Math.floor(Math.random() * ADJECTIVES.length)]}-${NOUNS[Math.floor(Math.random() * NOUNS.length)]}`;
4
+ const pick = (arr) => arr[Math.floor(Math.random() * arr.length)];
5
+ return `${pick(ADJECTIVES)}-${pick(ADJECTIVES)}-${pick(NOUNS)}`;
5
6
  }
6
7
  /** Sanitize a user-provided name into a valid filename slug */
7
8
  function slugify(name) {
@@ -0,0 +1,80 @@
1
+ import { a as readJson, n as exists, o as readText } from "./fs-DYR2XuFE.mjs";
2
+ import { t as jsYaml } from "./js-yaml-DpZfOoD4.mjs";
3
+ import { resolve } from "node:path";
4
+ //#region src/utils/package-manager.ts
5
+ /** Detect the package manager, extract workspace globs, and load catalogs */
6
+ async function detectWorkspaces(rootDir) {
7
+ const pm = await detectPackageManager(rootDir);
8
+ return {
9
+ packageManager: pm,
10
+ globs: await getWorkspaceGlobs(rootDir, pm),
11
+ catalogs: await loadCatalogs(rootDir, pm)
12
+ };
13
+ }
14
+ async function detectPackageManager(rootDir) {
15
+ if (await exists(resolve(rootDir, "bun.lock")) || await exists(resolve(rootDir, "bun.lockb"))) return "bun";
16
+ if (await exists(resolve(rootDir, "pnpm-lock.yaml"))) return "pnpm";
17
+ if (await exists(resolve(rootDir, "yarn.lock"))) return "yarn";
18
+ try {
19
+ const pkg = await readJson(resolve(rootDir, "package.json"));
20
+ if (typeof pkg.packageManager === "string") {
21
+ const name = pkg.packageManager.split("@")[0];
22
+ if (name === "pnpm" || name === "yarn" || name === "bun") return name;
23
+ }
24
+ } catch {}
25
+ return "npm";
26
+ }
27
+ async function getWorkspaceGlobs(rootDir, pm) {
28
+ if (pm === "pnpm") {
29
+ const wsFile = resolve(rootDir, "pnpm-workspace.yaml");
30
+ if (await exists(wsFile)) {
31
+ const content = await readText(wsFile);
32
+ const parsed = jsYaml.load(content);
33
+ if (parsed?.packages) return parsed.packages;
34
+ }
35
+ }
36
+ try {
37
+ const workspaces = (await readJson(resolve(rootDir, "package.json"))).workspaces;
38
+ if (Array.isArray(workspaces)) return workspaces;
39
+ if (workspaces && typeof workspaces === "object" && "packages" in workspaces) {
40
+ const pkgs = workspaces.packages;
41
+ if (Array.isArray(pkgs)) return pkgs;
42
+ }
43
+ } catch {}
44
+ return [];
45
+ }
46
+ /** Load catalog definitions from pnpm-workspace.yaml or root package.json */
47
+ async function loadCatalogs(rootDir, pm) {
48
+ const catalogs = /* @__PURE__ */ new Map();
49
+ if (pm === "pnpm") {
50
+ const wsFile = resolve(rootDir, "pnpm-workspace.yaml");
51
+ if (await exists(wsFile)) {
52
+ const content = await readText(wsFile);
53
+ const parsed = jsYaml.load(content);
54
+ if (parsed?.catalog) catalogs.set("", parsed.catalog);
55
+ if (parsed?.catalogs) for (const [name, deps] of Object.entries(parsed.catalogs)) catalogs.set(name, deps);
56
+ }
57
+ }
58
+ try {
59
+ const pkg = await readJson(resolve(rootDir, "package.json"));
60
+ if (pkg.catalog && typeof pkg.catalog === "object") catalogs.set("", pkg.catalog);
61
+ if (pkg.catalogs && typeof pkg.catalogs === "object") for (const [name, deps] of Object.entries(pkg.catalogs)) catalogs.set(name, deps);
62
+ const workspaces = pkg.workspaces;
63
+ if (workspaces && typeof workspaces === "object" && !Array.isArray(workspaces)) {
64
+ const ws = workspaces;
65
+ if (ws.catalog && typeof ws.catalog === "object") catalogs.set("", ws.catalog);
66
+ if (ws.catalogs && typeof ws.catalogs === "object") for (const [name, deps] of Object.entries(ws.catalogs)) catalogs.set(name, deps);
67
+ }
68
+ } catch {}
69
+ return catalogs;
70
+ }
71
+ /** Resolve a specific dependency's catalog: reference */
72
+ function resolveCatalogDep(depName, range, catalogs) {
73
+ if (!range.startsWith("catalog:")) return null;
74
+ const catalogName = range.slice(8).trim() || "";
75
+ const catalog = catalogs.get(catalogName);
76
+ if (!catalog) return null;
77
+ return catalog[depName] ?? null;
78
+ }
79
+ //#endregion
80
+ export { detectWorkspaces as n, resolveCatalogDep as r, detectPackageManager as t };