@pubm/core 0.5.2 → 0.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -14356,6 +14356,8 @@ var init_de = __esm(() => {
14356
14356
  "task.release.resolvingMetadata": "Repository-Metadaten für den Release-Entwurf werden aufgelöst...",
14357
14357
  "task.release.openingDraft": "Release-Entwurf für {tag} wird geöffnet...",
14358
14358
  "task.release.collectedCommits": "{count} Commits für {tag} gesammelt.",
14359
+ "task.release.copiedToClipboard": "Release-Notizen in die Zwischenablage kopiert — in den Release-Text einfügen",
14360
+ "task.release.truncated": "Release-Notizen wurden aufgrund der URL-Längenbeschränkung gekürzt",
14359
14361
  "task.publish.registryLabel": "In {registry} veröffentlichen",
14360
14362
  "task.dryRun.registryLabel": "Dry-run {registry}",
14361
14363
  "output.ciPrepareComplete": "CI-Vorbereitung abgeschlossen. Release-Tags gepusht — CI sollte die Veröffentlichung übernehmen.",
@@ -14525,6 +14527,7 @@ Token von {url} generieren`,
14525
14527
  "prompt.add.bumpMinor": "minor — Neue Funktionen, rückwärtskompatibel",
14526
14528
  "prompt.add.bumpMajor": "major — Nicht rückwärtskompatible Änderungen",
14527
14529
  "prompt.add.selectBump": "Hochstufungstyp für {name} auswählen",
14530
+ "prompt.add.selectBumpAll": "Hochstufungstyp für alle Pakete auswählen",
14528
14531
  "prompt.add.summary": "Zusammenfassung der Änderungen",
14529
14532
  "cmd.status.description": "Status der ausstehenden Changesets anzeigen",
14530
14533
  "cmd.status.optionVerbose": "Vollständige Changeset-Inhalte anzeigen",
@@ -14781,6 +14784,8 @@ var init_en = __esm(() => {
14781
14784
  "task.release.resolvingMetadata": "Resolving repository metadata for the release draft...",
14782
14785
  "task.release.openingDraft": "Opening release draft for {tag}...",
14783
14786
  "task.release.collectedCommits": "Collected {count} commits for {tag}.",
14787
+ "task.release.copiedToClipboard": "Release notes copied to clipboard — paste into the release body",
14788
+ "task.release.truncated": "Release notes were truncated due to URL length limit",
14784
14789
  "task.publish.registryLabel": "Publish to {registry}",
14785
14790
  "task.dryRun.registryLabel": "Dry-run {registry}",
14786
14791
  "output.ciPrepareComplete": "CI prepare completed. Release tags pushed — CI should pick up the publish.",
@@ -14950,6 +14955,7 @@ Generate a token from {url}`,
14950
14955
  "prompt.add.bumpMinor": "minor — New features, backward compatible",
14951
14956
  "prompt.add.bumpMajor": "major — Breaking changes",
14952
14957
  "prompt.add.selectBump": "Select bump type for {name}",
14958
+ "prompt.add.selectBumpAll": "Select bump type for all packages",
14953
14959
  "prompt.add.summary": "Summary of changes",
14954
14960
  "cmd.status.description": "Show pending changeset status",
14955
14961
  "cmd.status.optionVerbose": "Show full changeset contents",
@@ -15206,6 +15212,8 @@ var init_es = __esm(() => {
15206
15212
  "task.release.resolvingMetadata": "Resolviendo metadatos del repositorio para el borrador de publicación...",
15207
15213
  "task.release.openingDraft": "Abriendo borrador de publicación para {tag}...",
15208
15214
  "task.release.collectedCommits": "{count} commits recopilados para {tag}.",
15215
+ "task.release.copiedToClipboard": "Notas de la versión copiadas al portapapeles — pégalas en el cuerpo del release",
15216
+ "task.release.truncated": "Las notas de la versión fueron truncadas debido al límite de longitud de la URL",
15209
15217
  "task.publish.registryLabel": "Publicar en {registry}",
15210
15218
  "task.dryRun.registryLabel": "Dry-run {registry}",
15211
15219
  "output.ciPrepareComplete": "Preparación de CI completada. Etiquetas de publicación enviadas — CI debería encargarse de la publicación.",
@@ -15375,6 +15383,7 @@ Generar un token desde {url}`,
15375
15383
  "prompt.add.bumpMinor": "minor — Nuevas características, compatible con versiones anteriores",
15376
15384
  "prompt.add.bumpMajor": "major — Cambios incompatibles con versiones anteriores",
15377
15385
  "prompt.add.selectBump": "Seleccionar tipo de incremento para {name}",
15386
+ "prompt.add.selectBumpAll": "Seleccionar tipo de incremento para todos los paquetes",
15378
15387
  "prompt.add.summary": "Resumen de los cambios",
15379
15388
  "cmd.status.description": "Mostrar el estado de los changesets pendientes",
15380
15389
  "cmd.status.optionVerbose": "Mostrar el contenido completo del changeset",
@@ -15631,6 +15640,8 @@ var init_fr = __esm(() => {
15631
15640
  "task.release.resolvingMetadata": "Résolution des métadonnées du dépôt pour le brouillon de publication...",
15632
15641
  "task.release.openingDraft": "Ouverture du brouillon de publication pour {tag}...",
15633
15642
  "task.release.collectedCommits": "{count} commits collectés pour {tag}.",
15643
+ "task.release.copiedToClipboard": "Notes de version copiées dans le presse-papiers — collez-les dans le corps de la release",
15644
+ "task.release.truncated": "Les notes de version ont été tronquées en raison de la limite de longueur de l'URL",
15634
15645
  "task.publish.registryLabel": "Publier vers {registry}",
15635
15646
  "task.dryRun.registryLabel": "Dry-run {registry}",
15636
15647
  "output.ciPrepareComplete": "Préparation CI terminée. Tags de publication poussés — CI devrait prendre en charge la publication.",
@@ -15800,6 +15811,7 @@ Générer un token depuis {url}`,
15800
15811
  "prompt.add.bumpMinor": "minor — Nouvelles fonctionnalités, rétrocompatible",
15801
15812
  "prompt.add.bumpMajor": "major — Changements non rétrocompatibles",
15802
15813
  "prompt.add.selectBump": "Sélectionner le type d'incrément pour {name}",
15814
+ "prompt.add.selectBumpAll": "Sélectionner le type d'incrément pour tous les paquets",
15803
15815
  "prompt.add.summary": "Résumé des modifications",
15804
15816
  "cmd.status.description": "Afficher le statut des changesets en attente",
15805
15817
  "cmd.status.optionVerbose": "Afficher le contenu complet des changesets",
@@ -16056,6 +16068,8 @@ var init_ko = __esm(() => {
16056
16068
  "task.release.resolvingMetadata": "릴리스 초안을 위한 저장소 메타데이터 확인 중...",
16057
16069
  "task.release.openingDraft": "{tag} 릴리스 초안 열기 중...",
16058
16070
  "task.release.collectedCommits": "{tag}에 대한 {count}개 커밋 수집됨.",
16071
+ "task.release.copiedToClipboard": "릴리즈 노트가 클립보드에 복사되었습니다 — 릴리즈 본문에 붙여넣기 하세요",
16072
+ "task.release.truncated": "URL 길이 제한으로 릴리즈 노트가 잘렸습니다",
16059
16073
  "task.publish.registryLabel": "{registry}에 배포",
16060
16074
  "task.dryRun.registryLabel": "{registry} Dry-run",
16061
16075
  "output.ciPrepareComplete": "CI 준비 완료. 릴리스 태그가 푸시되었습니다 — CI가 배포를 처리합니다.",
@@ -16225,6 +16239,7 @@ var init_ko = __esm(() => {
16225
16239
  "prompt.add.bumpMinor": "minor — 새 기능, 하위 호환",
16226
16240
  "prompt.add.bumpMajor": "major — 호환성이 깨지는 변경",
16227
16241
  "prompt.add.selectBump": "{name}의 버전 업 유형 선택",
16242
+ "prompt.add.selectBumpAll": "모든 패키지의 버전 업 유형 선택",
16228
16243
  "prompt.add.summary": "변경사항 요약",
16229
16244
  "cmd.status.description": "대기 중인 changeset 상태 표시",
16230
16245
  "cmd.status.optionVerbose": "전체 changeset 내용 표시",
@@ -16481,6 +16496,8 @@ var init_zh_cn = __esm(() => {
16481
16496
  "task.release.resolvingMetadata": "正在解析发布草稿的仓库元数据...",
16482
16497
  "task.release.openingDraft": "正在打开 {tag} 的发布草稿...",
16483
16498
  "task.release.collectedCommits": "已为 {tag} 收集 {count} 个提交。",
16499
+ "task.release.copiedToClipboard": "发布说明已复制到剪贴板 — 请粘贴到发布正文中",
16500
+ "task.release.truncated": "由于URL长度限制,发布说明已被截断",
16484
16501
  "task.publish.registryLabel": "发布到 {registry}",
16485
16502
  "task.dryRun.registryLabel": "{registry} Dry-run",
16486
16503
  "output.ciPrepareComplete": "CI 准备完成。发布标签已推送 — CI 应处理发布。",
@@ -16650,6 +16667,7 @@ var init_zh_cn = __esm(() => {
16650
16667
  "prompt.add.bumpMinor": "minor — 新功能,向后兼容",
16651
16668
  "prompt.add.bumpMajor": "major — 破坏性变更",
16652
16669
  "prompt.add.selectBump": "选择 {name} 的升级类型",
16670
+ "prompt.add.selectBumpAll": "选择所有包的升级类型",
16653
16671
  "prompt.add.summary": "变更摘要",
16654
16672
  "cmd.status.description": "显示待处理的 changeset 状态",
16655
16673
  "cmd.status.optionVerbose": "显示完整的 changeset 内容",
@@ -17641,7 +17659,7 @@ var package_default;
17641
17659
  var init_package = __esm(() => {
17642
17660
  package_default = {
17643
17661
  name: "@pubm/core",
17644
- version: "0.5.2",
17662
+ version: "0.5.5",
17645
17663
  type: "module",
17646
17664
  description: "Core SDK for pubm - publish manager for multiple registries",
17647
17665
  types: "./dist/index.d.ts",
@@ -17720,7 +17738,7 @@ var coreEngines, PUBM_VERSION, PUBM_ENGINES;
17720
17738
  var init_pubm_metadata = __esm(() => {
17721
17739
  init_package();
17722
17740
  coreEngines = package_default.engines ?? {};
17723
- PUBM_VERSION = resolveDefine("0.5.2", package_default.version);
17741
+ PUBM_VERSION = resolveDefine("0.5.5", package_default.version);
17724
17742
  PUBM_ENGINES = {
17725
17743
  node: resolveDefine(">=24", coreEngines.node ?? ">=18"),
17726
17744
  git: resolveDefine(">=2.11.0", coreEngines.git ?? ">=2.11.0"),
@@ -22375,9 +22393,11 @@ function createNpmPublishTask(packagePath) {
22375
22393
  task.output = t("task.npm.publishing");
22376
22394
  try {
22377
22395
  if (ctx.runtime.promptEnabled) {
22378
- const result = await npm.publish(ctx.runtime.npmOtp);
22396
+ const result = await npm.publish(ctx.runtime.npmOtp, ctx.runtime.tag);
22379
22397
  if (!result) {
22398
+ let isOtpCreator = false;
22380
22399
  if (!ctx.runtime.npmOtpPromise) {
22400
+ isOtpCreator = true;
22381
22401
  ctx.runtime.npmOtpPromise = (async () => {
22382
22402
  task.title = t("task.npm.otpTitle", { name: npm.packageName });
22383
22403
  const maxAttempts = 3;
@@ -22391,7 +22411,7 @@ function createNpmPublishTask(packagePath) {
22391
22411
  }) : ""
22392
22412
  })
22393
22413
  });
22394
- const success2 = await npm.publish(otp2);
22414
+ const success2 = await npm.publish(otp2, ctx.runtime.tag);
22395
22415
  if (success2) {
22396
22416
  ctx.runtime.npmOtp = otp2;
22397
22417
  task.title = t("task.npm.otpPassed", {
@@ -22407,8 +22427,8 @@ function createNpmPublishTask(packagePath) {
22407
22427
  })();
22408
22428
  }
22409
22429
  const otp = await ctx.runtime.npmOtpPromise;
22410
- if (!ctx.runtime.npmOtp || ctx.runtime.npmOtp !== otp) {
22411
- await npm.publish(otp);
22430
+ if (!isOtpCreator) {
22431
+ await npm.publish(otp, ctx.runtime.tag);
22412
22432
  }
22413
22433
  }
22414
22434
  } else {
@@ -22416,7 +22436,7 @@ function createNpmPublishTask(packagePath) {
22416
22436
  if (!npmTokenEnv) {
22417
22437
  throw new NpmAvailableError(t("error.npm.noAuthToken"));
22418
22438
  }
22419
- const result = await npm.publishProvenance();
22439
+ const result = await npm.publishProvenance(ctx.runtime.tag);
22420
22440
  if (!result) {
22421
22441
  throw new NpmAvailableError(t("error.npm.2faInCi", { name: npm.packageName }));
22422
22442
  }
@@ -22544,7 +22564,7 @@ function createNpmDryRunPublishTask(packagePath) {
22544
22564
  }
22545
22565
  task.output = t("task.dryRun.npm.running");
22546
22566
  await withTokenRetry("npm", ctx, task, async () => {
22547
- await npm.dryRunPublish();
22567
+ await npm.dryRunPublish(ctx.runtime.tag);
22548
22568
  });
22549
22569
  }
22550
22570
  };
@@ -23143,6 +23163,43 @@ function spawnInteractive(command) {
23143
23163
  }
23144
23164
 
23145
23165
  // src/registry/npm.ts
23166
+ function validateNpmLoginUrl(rawUrl) {
23167
+ let parsed;
23168
+ try {
23169
+ parsed = new URL(rawUrl);
23170
+ } catch {
23171
+ return null;
23172
+ }
23173
+ if (parsed.origin !== "https://www.npmjs.com") {
23174
+ return null;
23175
+ }
23176
+ if (parsed.pathname.startsWith("/auth/cli/")) {
23177
+ const authPath2 = parsed.pathname.slice("/auth/cli/".length);
23178
+ return authPath2 ? rawUrl : null;
23179
+ }
23180
+ if (parsed.pathname !== "/login") {
23181
+ return null;
23182
+ }
23183
+ const next = parsed.searchParams.get("next");
23184
+ if (!next?.startsWith("/login/cli/")) {
23185
+ return null;
23186
+ }
23187
+ const authPath = next.slice("/login/cli/".length);
23188
+ return authPath ? rawUrl : null;
23189
+ }
23190
+ function extractNpmLoginUrl(text) {
23191
+ const matches = text.match(/https:\/\/www\.npmjs\.com\/[^\s"'`<>]+/g);
23192
+ if (!matches) {
23193
+ return null;
23194
+ }
23195
+ for (const match of matches) {
23196
+ const validUrl = validateNpmLoginUrl(match);
23197
+ if (validUrl) {
23198
+ return validUrl;
23199
+ }
23200
+ }
23201
+ return null;
23202
+ }
23146
23203
  async function runNpm(args, cwd) {
23147
23204
  const { stdout } = await exec3("npm", args, {
23148
23205
  throwOnError: true,
@@ -23157,7 +23214,7 @@ async function npmPackageRegistry(packagePath) {
23157
23214
  const manifest = await NpmPackageRegistry.reader.read(packagePath);
23158
23215
  return new NpmPackageRegistry(manifest.name, packagePath);
23159
23216
  }
23160
- var import_promises4, import_node_os3, import_node_path6, import_node_process12, NpmError, NpmConnector, NpmPackageRegistry;
23217
+ var import_promises4, import_node_os3, import_node_path6, import_node_process12, NpmError, NPM_OFFICIAL_REGISTRY = "https://registry.npmjs.org", NpmConnector, NpmPackageRegistry;
23161
23218
  var init_npm2 = __esm(() => {
23162
23219
  init_dist();
23163
23220
  init_error4();
@@ -23349,8 +23406,11 @@ var init_npm2 = __esm(() => {
23349
23406
  throw new NpmError(`Failed to run \`npm view ${this.packageName} dist-tags --json\``, { cause: error4 });
23350
23407
  }
23351
23408
  }
23352
- async publish(otp) {
23409
+ async publish(otp, tag) {
23353
23410
  const args = otp ? ["publish", "--otp", otp] : ["publish"];
23411
+ if (tag && tag !== "latest") {
23412
+ args.push("--tag", tag);
23413
+ }
23354
23414
  try {
23355
23415
  await this.npm(args, this.packagePath);
23356
23416
  return true;
@@ -23361,16 +23421,20 @@ var init_npm2 = __esm(() => {
23361
23421
  throw this.classifyPublishError(error4);
23362
23422
  }
23363
23423
  }
23364
- async publishProvenance() {
23424
+ async publishProvenance(tag) {
23425
+ const args = ["publish", "--provenance", "--access", "public"];
23426
+ if (tag && tag !== "latest") {
23427
+ args.push("--tag", tag);
23428
+ }
23365
23429
  try {
23366
- await this.npm(["publish", "--provenance", "--access", "public"], this.packagePath);
23430
+ await this.npm(args, this.packagePath);
23367
23431
  return true;
23368
23432
  } catch (error4) {
23369
23433
  if (error4 instanceof NonZeroExitError && error4.output?.stderr.includes("EOTP")) {
23370
23434
  return false;
23371
23435
  }
23372
23436
  if (this.isProvenanceError(error4)) {
23373
- return this.publish();
23437
+ return this.publish(undefined, tag);
23374
23438
  }
23375
23439
  throw this.classifyPublishError(error4);
23376
23440
  }
@@ -23381,9 +23445,13 @@ var init_npm2 = __esm(() => {
23381
23445
  async unpublish(packageName, version) {
23382
23446
  await this.npm(["unpublish", `${packageName}@${version}`], this.packagePath);
23383
23447
  }
23384
- async dryRunPublish() {
23448
+ async dryRunPublish(tag) {
23449
+ const args = ["publish", "--dry-run"];
23450
+ if (tag && tag !== "latest") {
23451
+ args.push("--tag", tag);
23452
+ }
23385
23453
  try {
23386
- await exec3("npm", ["publish", "--dry-run"], {
23454
+ await exec3("npm", args, {
23387
23455
  throwOnError: true,
23388
23456
  nodeOptions: {
23389
23457
  cwd: this.packagePath,
@@ -23415,44 +23483,21 @@ ${stderr}` : ""}`, { cause: error4 });
23415
23483
  if (!await this.isLoggedIn()) {
23416
23484
  if (ctx.runtime.promptEnabled) {
23417
23485
  try {
23418
- task.output = "Launching npm login...";
23419
- const { spawnInteractive: spawnInteractive2 } = await Promise.resolve().then(() => exports_spawn_interactive);
23420
- const child = spawnInteractive2(["npm", "login"]);
23421
- let opened = false;
23422
- const readStream = async (stream, onData) => {
23423
- const reader = stream.getReader();
23424
- const decoder = new TextDecoder;
23425
- try {
23426
- while (true) {
23427
- const { done, value } = await reader.read();
23428
- if (done)
23429
- break;
23430
- onData(decoder.decode(value));
23486
+ let loginPromise = ctx.runtime.npmLoginPromise;
23487
+ if (!loginPromise) {
23488
+ loginPromise = this.runInteractiveLogin(task).finally(() => {
23489
+ if (ctx.runtime.npmLoginPromise === loginPromise) {
23490
+ ctx.runtime.npmLoginPromise = undefined;
23431
23491
  }
23432
- } finally {
23433
- reader.releaseLock();
23434
- }
23435
- };
23436
- await new Promise((resolve, reject) => {
23437
- const onData = (text) => {
23438
- const urlMatch = text.match(/https:\/\/www\.npmjs\.com\/login[^\s]*/);
23439
- if (urlMatch && !opened) {
23440
- opened = true;
23441
- task.output = `Login at: ${color.cyan(urlMatch[0])}`;
23442
- Promise.resolve().then(() => (init_open_url(), exports_open_url)).then(({ openUrl: openUrl2 }) => openUrl2(urlMatch[0]));
23443
- child.stdin.write(`
23444
- `);
23445
- child.stdin.flush();
23446
- }
23447
- };
23448
- Promise.all([
23449
- readStream(child.stdout, onData),
23450
- readStream(child.stderr, onData)
23451
- ]).catch(reject);
23452
- child.exited.then((code) => code === 0 ? resolve() : reject(new Error(`npm login exited with code ${code}`))).catch(reject);
23453
- });
23492
+ });
23493
+ ctx.runtime.npmLoginPromise = loginPromise;
23494
+ } else {
23495
+ task.output = "Waiting for npm login...";
23496
+ }
23497
+ await loginPromise;
23454
23498
  } catch (error4) {
23455
- throw new NpmError("npm login failed. Please run `npm login` manually and try again.", { cause: error4 });
23499
+ const detail = error4 instanceof Error ? `: ${error4.message}` : "";
23500
+ throw new NpmError(`npm login failed${detail}. Please run \`npm login\` manually and try again.`, { cause: error4 });
23456
23501
  }
23457
23502
  if (!await this.isLoggedIn()) {
23458
23503
  throw new NpmError("Still not logged in after npm login. Please verify your credentials.");
@@ -23482,6 +23527,11 @@ ${stderr}` : ""}`, { cause: error4 });
23482
23527
  requiredManifest: "package.json"
23483
23528
  };
23484
23529
  }
23530
+ isOfficialNpmRegistry() {
23531
+ if (!this.registry)
23532
+ return true;
23533
+ return normalizeRegistryUrl(this.registry) === "registry.npmjs.org";
23534
+ }
23485
23535
  isProvenanceError(error4) {
23486
23536
  if (!(error4 instanceof NonZeroExitError))
23487
23537
  return false;
@@ -23507,6 +23557,110 @@ ${stderr}` : ""}`, { cause: error4 });
23507
23557
  }
23508
23558
  return new NpmError("Failed to publish to npm", { cause: error4 });
23509
23559
  }
23560
+ async runDirectWebLogin(task) {
23561
+ task.output = "Launching npm login...";
23562
+ const isValidUrl = (url) => {
23563
+ try {
23564
+ return /^https?:$/.test(new URL(url).protocol);
23565
+ } catch {
23566
+ return false;
23567
+ }
23568
+ };
23569
+ const loginEndpoint = `${NPM_OFFICIAL_REGISTRY}/-/v1/login`;
23570
+ const res = await fetch(loginEndpoint, {
23571
+ method: "POST",
23572
+ headers: { "content-type": "application/json" },
23573
+ body: JSON.stringify({})
23574
+ });
23575
+ if (!res.ok) {
23576
+ throw new NpmError(`npm web login initiation failed (HTTP ${res.status})`);
23577
+ }
23578
+ const body = await res.json();
23579
+ const { loginUrl, doneUrl } = body;
23580
+ if (!loginUrl || !doneUrl || !isValidUrl(loginUrl) || !isValidUrl(doneUrl)) {
23581
+ throw new NpmError("npm web login response missing valid loginUrl or doneUrl");
23582
+ }
23583
+ task.output = `Login at: ${color.cyan(loginUrl)}`;
23584
+ const { openUrl: openUrl2 } = await Promise.resolve().then(() => (init_open_url(), exports_open_url));
23585
+ openUrl2(loginUrl).catch(() => {});
23586
+ while (true) {
23587
+ const pollRes = await fetch(doneUrl);
23588
+ if (pollRes.status === 200) {
23589
+ const pollBody = await pollRes.json();
23590
+ if (!pollBody.token) {
23591
+ throw new NpmError("npm web login completed but no token received");
23592
+ }
23593
+ try {
23594
+ await exec3("npm", [
23595
+ "config",
23596
+ "set",
23597
+ "//registry.npmjs.org/:_authToken",
23598
+ pollBody.token,
23599
+ "--location=user"
23600
+ ], { throwOnError: true });
23601
+ } catch (error4) {
23602
+ throw new NpmError("Failed to save npm auth token", { cause: error4 });
23603
+ }
23604
+ return;
23605
+ }
23606
+ if (pollRes.status === 202) {
23607
+ const retryAfter = Number(pollRes.headers.get("retry-after")) * 1000;
23608
+ const delay2 = retryAfter > 0 ? retryAfter : 1000;
23609
+ await new Promise((resolve) => setTimeout(resolve, delay2));
23610
+ continue;
23611
+ }
23612
+ throw new NpmError(`npm web login polling failed (HTTP ${pollRes.status})`);
23613
+ }
23614
+ }
23615
+ async runInteractiveLogin(task) {
23616
+ if (this.isOfficialNpmRegistry()) {
23617
+ return this.runDirectWebLogin(task);
23618
+ }
23619
+ task.output = "Launching npm login...";
23620
+ const [{ spawnInteractive: spawnInteractive2 }, { openUrl: openUrl2 }] = await Promise.all([
23621
+ Promise.resolve().then(() => exports_spawn_interactive),
23622
+ Promise.resolve().then(() => (init_open_url(), exports_open_url))
23623
+ ]);
23624
+ const child = spawnInteractive2(["npm", "login"]);
23625
+ let openedUrl = null;
23626
+ let bufferedText = "";
23627
+ const onData = (text) => {
23628
+ bufferedText = `${bufferedText}${text}`.slice(-4096);
23629
+ const canonicalUrl = extractNpmLoginUrl(bufferedText);
23630
+ if (!canonicalUrl || openedUrl) {
23631
+ return;
23632
+ }
23633
+ openedUrl = canonicalUrl;
23634
+ task.output = `Login at: ${color.cyan(canonicalUrl)}`;
23635
+ openUrl2(canonicalUrl);
23636
+ };
23637
+ await Promise.all([
23638
+ this.readInteractiveStream(child.stdout, onData),
23639
+ this.readInteractiveStream(child.stderr, onData),
23640
+ child.exited.then((code) => {
23641
+ if (code !== 0) {
23642
+ throw new Error(`npm login exited with code ${code}`);
23643
+ }
23644
+ })
23645
+ ]);
23646
+ if (!openedUrl) {
23647
+ throw new Error("npm login did not provide a supported web login URL.");
23648
+ }
23649
+ }
23650
+ async readInteractiveStream(stream, onData) {
23651
+ const reader = stream.getReader();
23652
+ const decoder = new TextDecoder;
23653
+ try {
23654
+ while (true) {
23655
+ const { done, value } = await reader.read();
23656
+ if (done)
23657
+ break;
23658
+ onData(decoder.decode(value));
23659
+ }
23660
+ } finally {
23661
+ reader.releaseLock();
23662
+ }
23663
+ }
23510
23664
  };
23511
23665
  });
23512
23666
 
@@ -33656,7 +33810,7 @@ __export(exports_src, {
33656
33810
  module.exports = __toCommonJS(exports_src);
33657
33811
 
33658
33812
  // src/tasks/runner.ts
33659
- var import_node_process19 = __toESM(require("node:process"));
33813
+ var import_node_process20 = __toESM(require("node:process"));
33660
33814
 
33661
33815
  // ../../node_modules/.bun/std-env@4.0.0/node_modules/std-env/dist/index.mjs
33662
33816
  var e2 = globalThis.process?.env || Object.create(null);
@@ -35999,29 +36153,11 @@ function createPublishTasks(hasPublish, dryRun, skipPublish) {
35999
36153
 
36000
36154
  // src/tasks/phases/push-release.ts
36001
36155
  init_dist2();
36002
- var import_node_fs14 = require("node:fs");
36003
- var import_node_path23 = require("node:path");
36004
- var import_node_process17 = __toESM(require("node:process"));
36005
- var import_semver4 = __toESM(require_semver2(), 1);
36006
-
36007
- // src/changeset/changelog-parser.ts
36008
- function parseChangelogSection(changelog, version) {
36009
- const normalizedVersion = version.replace(/^v/, "");
36010
- const escapedVersion = normalizedVersion.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
36011
- const headerPattern = new RegExp(`^## v?${escapedVersion}\\b[^\\n]*\\n`, "m");
36012
- const headerMatch = headerPattern.exec(changelog);
36013
- if (!headerMatch)
36014
- return null;
36015
- const start = headerMatch.index + headerMatch[0].length;
36016
- const nextHeader = changelog.indexOf(`
36017
- ## `, start);
36018
- const end = nextHeader === -1 ? changelog.length : nextHeader;
36019
- return changelog.slice(start, end).trim();
36020
- }
36021
-
36022
- // src/tasks/phases/push-release.ts
36023
36156
  init_git();
36024
36157
  init_i18n();
36158
+ var import_node_fs15 = require("node:fs");
36159
+ var import_node_process18 = __toESM(require("node:process"));
36160
+ var import_semver4 = __toESM(require_semver2(), 1);
36025
36161
 
36026
36162
  // src/utils/github-token.ts
36027
36163
  init_secure_store();
@@ -36058,13 +36194,6 @@ var { prerelease } = import_semver3.default;
36058
36194
  class GitHubReleaseError extends AbstractError {
36059
36195
  name = t("error.githubRelease.name");
36060
36196
  }
36061
- function formatReleaseNotes(commits, repositoryUrl, previousTag, latestTag) {
36062
- const lines = commits.map(({ id, message }) => `- ${message.replace(/#(\d+)/g, `[#$1](${repositoryUrl}/issues/$1)`)} ([${id.slice(0, 7)}](${repositoryUrl}/commit/${id}))`);
36063
- lines.push("");
36064
- lines.push(`**Full Changelog**: ${repositoryUrl}/compare/${previousTag}...${latestTag}`);
36065
- return lines.join(`
36066
- `);
36067
- }
36068
36197
  async function createGitHubRelease(_ctx, options) {
36069
36198
  const token = process.env.GITHUB_TOKEN;
36070
36199
  if (!token) {
@@ -36072,16 +36201,7 @@ async function createGitHubRelease(_ctx, options) {
36072
36201
  }
36073
36202
  const git = new Git;
36074
36203
  const remoteUrl = await git.repository();
36075
- const repositoryUrl = remoteUrl.replace(/^git@github\.com:/, "https://github.com/").replace(/\.git$/, "");
36076
36204
  const { owner, repo } = parseOwnerRepo(remoteUrl);
36077
- const previousTag = await git.previousTag(options.tag) || await git.firstCommit();
36078
- let body;
36079
- if (options.changelogBody) {
36080
- body = options.changelogBody;
36081
- } else {
36082
- const commits = (await git.commits(previousTag, options.tag)).slice(1);
36083
- body = formatReleaseNotes(commits, repositoryUrl, previousTag, options.tag);
36084
- }
36085
36205
  const createResponse = await fetch(`https://api.github.com/repos/${owner}/${repo}/releases`, {
36086
36206
  method: "POST",
36087
36207
  headers: {
@@ -36092,7 +36212,7 @@ async function createGitHubRelease(_ctx, options) {
36092
36212
  body: JSON.stringify({
36093
36213
  tag_name: options.tag,
36094
36214
  name: options.tag,
36095
- body,
36215
+ body: options.body,
36096
36216
  draft: !!options.draft,
36097
36217
  prerelease: !!prerelease(options.version)
36098
36218
  })
@@ -36174,65 +36294,446 @@ async function deleteGitHubRelease(releaseId) {
36174
36294
  }
36175
36295
  }
36176
36296
 
36177
- // src/tasks/runner-utils/version-pr.ts
36297
+ // src/tasks/release-notes.ts
36178
36298
  var import_node_fs13 = require("node:fs");
36179
- var import_node_path22 = __toESM(require("node:path"));
36180
- var import_node_process16 = __toESM(require("node:process"));
36181
- init_error4();
36182
- init_git();
36183
- init_i18n();
36299
+ var import_node_path23 = require("node:path");
36184
36300
 
36185
- // src/tasks/create-version-pr.ts
36186
- init_error4();
36187
- init_i18n();
36188
- init_exec();
36301
+ // src/conventional-commit/types.ts
36302
+ var DEFAULT_TYPE_BUMP_MAP = {
36303
+ feat: "minor",
36304
+ fix: "patch",
36305
+ perf: "patch",
36306
+ chore: false,
36307
+ docs: false,
36308
+ test: false,
36309
+ ci: false,
36310
+ style: false,
36311
+ refactor: false
36312
+ };
36313
+ var COMMIT_TYPE_CATEGORY_MAP = {
36314
+ feat: "Features",
36315
+ fix: "Bug Fixes",
36316
+ perf: "Performance",
36317
+ refactor: "Refactoring",
36318
+ docs: "Documentation"
36319
+ };
36320
+ var DEFAULT_CATEGORY = "Other Changes";
36189
36321
 
36190
- class VersionPrError extends AbstractError {
36191
- name = "Version PR Error";
36192
- }
36193
- async function createVersionPr(options) {
36194
- try {
36195
- return await createPrViaGhCli(options);
36196
- } catch {
36197
- return await createPrViaApi(options);
36322
+ // src/changelog/conventional-commit-writer.ts
36323
+ var CATEGORY_ORDER = [
36324
+ "Features",
36325
+ "Bug Fixes",
36326
+ "Performance",
36327
+ "Refactoring",
36328
+ "Documentation",
36329
+ "Other Changes"
36330
+ ];
36331
+
36332
+ class ConventionalCommitChangelogWriter {
36333
+ formatEntries(entries) {
36334
+ if (entries.length === 0)
36335
+ return [];
36336
+ const groups = new Map;
36337
+ for (const entry of entries) {
36338
+ const category = entry.type && COMMIT_TYPE_CATEGORY_MAP[entry.type] || DEFAULT_CATEGORY;
36339
+ const hashSuffix = entry.hash ? ` (${entry.hash})` : "";
36340
+ const item = `- ${entry.summary}${hashSuffix}`;
36341
+ const existing = groups.get(category);
36342
+ if (existing) {
36343
+ existing.push(item);
36344
+ } else {
36345
+ groups.set(category, [item]);
36346
+ }
36347
+ }
36348
+ const sections = [];
36349
+ for (const category of CATEGORY_ORDER) {
36350
+ const items = groups.get(category);
36351
+ if (items)
36352
+ sections.push({ category, items });
36353
+ }
36354
+ return sections;
36198
36355
  }
36199
36356
  }
36200
- async function closeVersionPr(options) {
36201
- try {
36202
- await closePrViaGhCli(options);
36203
- } catch {
36204
- await closePrViaApi(options);
36205
- }
36357
+
36358
+ // src/changeset/changelog-parser.ts
36359
+ function parseChangelogSection(changelog, version) {
36360
+ const normalizedVersion = version.replace(/^v/, "");
36361
+ const escapedVersion = normalizedVersion.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
36362
+ const headerPattern = new RegExp(`^## v?${escapedVersion}\\b[^\\n]*\\n`, "m");
36363
+ const headerMatch = headerPattern.exec(changelog);
36364
+ if (!headerMatch)
36365
+ return null;
36366
+ const start = headerMatch.index + headerMatch[0].length;
36367
+ const nextHeader = changelog.indexOf(`
36368
+ ## `, start);
36369
+ const end = nextHeader === -1 ? changelog.length : nextHeader;
36370
+ return changelog.slice(start, end).trim();
36206
36371
  }
36207
- async function createPrViaGhCli(options) {
36208
- const args = [
36209
- "pr",
36210
- "create",
36211
- "--title",
36212
- options.title,
36213
- "--body",
36214
- options.body,
36215
- "--base",
36216
- options.base,
36217
- "--head",
36218
- options.branch
36219
- ];
36220
- if (options.labels && options.labels.length > 0) {
36221
- args.push("--label", options.labels.join(","));
36372
+
36373
+ // src/conventional-commit/git-log.ts
36374
+ var import_node_child_process = require("node:child_process");
36375
+ var COMMIT_START_MARKER = "COMMIT_START";
36376
+ var COMMIT_FILES_MARKER = "COMMIT_FILES";
36377
+ function findLastReleaseRef(cwd, packageName) {
36378
+ if (packageName) {
36379
+ const scopedTags = execGit(cwd, [
36380
+ "tag",
36381
+ "--list",
36382
+ `${packageName}@[0-9]*.[0-9]*.[0-9]*`,
36383
+ "--sort=-v:refname"
36384
+ ]);
36385
+ if (scopedTags.length > 0)
36386
+ return scopedTags[0];
36222
36387
  }
36223
- const { stdout } = await exec3("gh", args, { throwOnError: true });
36224
- const url = stdout.trim();
36225
- const numberMatch = url.match(/\/pull\/(\d+)/);
36226
- const number2 = numberMatch ? Number.parseInt(numberMatch[1], 10) : 0;
36227
- return { url, number: number2 };
36388
+ const vTags = execGit(cwd, [
36389
+ "tag",
36390
+ "--list",
36391
+ "v[0-9]*.[0-9]*.[0-9]*",
36392
+ "--sort=-v:refname"
36393
+ ]);
36394
+ if (vTags.length > 0)
36395
+ return vTags[0];
36396
+ const versionCommit = execGit(cwd, [
36397
+ "log",
36398
+ "--format=%H",
36399
+ "--grep=^Version Packages$",
36400
+ "-1"
36401
+ ]);
36402
+ if (versionCommit.length > 0)
36403
+ return versionCommit[0];
36404
+ return;
36228
36405
  }
36229
- async function createPrViaApi(options) {
36230
- const response = await fetch(`https://api.github.com/repos/${options.owner}/${options.repo}/pulls`, {
36231
- method: "POST",
36232
- headers: {
36233
- Authorization: `Bearer ${options.token}`,
36234
- Accept: "application/vnd.github+json",
36235
- "X-GitHub-Api-Version": "2022-11-28"
36406
+ function getCommitsSinceRef(cwd, ref, toRef) {
36407
+ const range = ref ? `${ref}..${toRef ?? "HEAD"}` : toRef ?? "HEAD";
36408
+ const format3 = `${COMMIT_START_MARKER} %h%n%B%n${COMMIT_FILES_MARKER}`;
36409
+ const output = execGitRaw(cwd, [
36410
+ "log",
36411
+ `--format=${format3}`,
36412
+ "--name-only",
36413
+ range
36414
+ ]);
36415
+ if (!output.trim())
36416
+ return [];
36417
+ const commits = [];
36418
+ const lines = output.split(`
36419
+ `);
36420
+ let i2 = 0;
36421
+ while (i2 < lines.length) {
36422
+ if (!lines[i2].startsWith(COMMIT_START_MARKER)) {
36423
+ i2++;
36424
+ continue;
36425
+ }
36426
+ const hash = lines[i2].slice(COMMIT_START_MARKER.length + 1).trim();
36427
+ i2++;
36428
+ const messageLines = [];
36429
+ while (i2 < lines.length && !lines[i2].startsWith(COMMIT_FILES_MARKER)) {
36430
+ if (lines[i2].startsWith(COMMIT_START_MARKER))
36431
+ break;
36432
+ messageLines.push(lines[i2]);
36433
+ i2++;
36434
+ }
36435
+ if (i2 < lines.length && lines[i2].startsWith(COMMIT_FILES_MARKER)) {
36436
+ i2++;
36437
+ }
36438
+ const files = [];
36439
+ while (i2 < lines.length && !lines[i2].startsWith(COMMIT_START_MARKER)) {
36440
+ const file = lines[i2].trim();
36441
+ if (file)
36442
+ files.push(file);
36443
+ i2++;
36444
+ }
36445
+ const message = messageLines.join(`
36446
+ `).trim();
36447
+ if (hash && message) {
36448
+ commits.push({ hash, message, files });
36449
+ }
36450
+ }
36451
+ return commits;
36452
+ }
36453
+ function execGit(cwd, args) {
36454
+ return execGitRaw(cwd, args).split(`
36455
+ `).map((l3) => l3.trim()).filter(Boolean);
36456
+ }
36457
+ function execGitRaw(cwd, args) {
36458
+ try {
36459
+ return import_node_child_process.execFileSync("git", args, { cwd, encoding: "utf-8" });
36460
+ } catch {
36461
+ return "";
36462
+ }
36463
+ }
36464
+
36465
+ // src/conventional-commit/parser.ts
36466
+ var HEADER_REGEX = /^(\w+)(?:\(([^)]+)\))?(!)?\s*:\s*(.+)$/;
36467
+ var FOOTER_REGEX = /^([\w-]+|BREAKING CHANGE)\s*:\s*(.+)$/;
36468
+ function parseConventionalCommit(hash, message, files = []) {
36469
+ const lines = message.split(`
36470
+ `);
36471
+ const firstLine = lines[0];
36472
+ const headerMatch = firstLine.match(HEADER_REGEX);
36473
+ if (!headerMatch)
36474
+ return null;
36475
+ const [, type, scope, bang, description] = headerMatch;
36476
+ let body;
36477
+ const footers = new Map;
36478
+ let breaking = bang === "!";
36479
+ if (lines.length > 1) {
36480
+ const rest = lines.slice(1);
36481
+ let footerStartIndex = rest.length;
36482
+ for (let i2 = rest.length - 1;i2 >= 0; i2--) {
36483
+ if (rest[i2] === "") {
36484
+ footerStartIndex = i2 + 1;
36485
+ break;
36486
+ }
36487
+ }
36488
+ const bodyStartIndex = rest.findIndex((line) => line !== "");
36489
+ if (bodyStartIndex !== -1 && bodyStartIndex < footerStartIndex) {
36490
+ const bodyLines = rest.slice(bodyStartIndex, footerStartIndex - 1);
36491
+ const bodyText = bodyLines.join(`
36492
+ `).trim();
36493
+ if (bodyText)
36494
+ body = bodyText;
36495
+ }
36496
+ let currentFooterKey;
36497
+ for (let i2 = footerStartIndex;i2 < rest.length; i2++) {
36498
+ const footerMatch = rest[i2].match(FOOTER_REGEX);
36499
+ if (footerMatch) {
36500
+ const [, key, value] = footerMatch;
36501
+ footers.set(key, value);
36502
+ currentFooterKey = key;
36503
+ if (key === "BREAKING CHANGE" || key === "BREAKING-CHANGE") {
36504
+ breaking = true;
36505
+ }
36506
+ } else if (currentFooterKey && rest[i2].startsWith(" ")) {
36507
+ const existing = footers.get(currentFooterKey) ?? "";
36508
+ footers.set(currentFooterKey, `${existing}
36509
+ ${rest[i2].trimStart()}`);
36510
+ }
36511
+ }
36512
+ }
36513
+ return { hash, type, scope, breaking, description, body, footers, files };
36514
+ }
36515
+
36516
+ // src/conventional-commit/scope-resolver.ts
36517
+ var import_node_path22 = __toESM(require("node:path"));
36518
+ function resolveCommitPackages(commit, packagePaths) {
36519
+ const matched = new Set;
36520
+ if (commit.scope) {
36521
+ for (const pkgPath of packagePaths) {
36522
+ const dirName = import_node_path22.default.basename(pkgPath);
36523
+ if (dirName === commit.scope) {
36524
+ matched.add(pkgPath);
36525
+ }
36526
+ }
36527
+ if (matched.size > 0)
36528
+ return [...matched];
36529
+ }
36530
+ for (const file of commit.files) {
36531
+ const normalized = file.replace(/\\/g, "/");
36532
+ for (const pkgPath of packagePaths) {
36533
+ if (pkgPath === ".") {
36534
+ matched.add(pkgPath);
36535
+ continue;
36536
+ }
36537
+ const normalizedPkg = pkgPath.replace(/\\/g, "/");
36538
+ if (normalized.startsWith(`${normalizedPkg}/`) || normalized === normalizedPkg) {
36539
+ matched.add(pkgPath);
36540
+ }
36541
+ }
36542
+ }
36543
+ return [...matched];
36544
+ }
36545
+
36546
+ // src/tasks/release-notes.ts
36547
+ init_git();
36548
+
36549
+ // src/utils/clipboard.ts
36550
+ var import_node_process16 = __toESM(require("node:process"));
36551
+ async function copyToClipboard(text) {
36552
+ const commands = getClipboardCommands();
36553
+ for (const cmd of commands) {
36554
+ try {
36555
+ const proc = Bun.spawn(cmd, {
36556
+ stdin: "pipe",
36557
+ stdout: "ignore",
36558
+ stderr: "ignore"
36559
+ });
36560
+ proc.stdin.write(text);
36561
+ proc.stdin.end();
36562
+ const exitCode = await proc.exited;
36563
+ if (exitCode === 0)
36564
+ return true;
36565
+ } catch {}
36566
+ }
36567
+ return false;
36568
+ }
36569
+ function getClipboardCommands() {
36570
+ switch (import_node_process16.default.platform) {
36571
+ case "darwin":
36572
+ return [["pbcopy"]];
36573
+ case "win32":
36574
+ return [["clip"]];
36575
+ default:
36576
+ return [["xclip", "-selection", "clipboard"], ["wl-copy"]];
36577
+ }
36578
+ }
36579
+
36580
+ // src/tasks/release-notes.ts
36581
+ function renderReleaseNoteSections(sections) {
36582
+ if (sections.length === 0)
36583
+ return "";
36584
+ const parts = [];
36585
+ for (const section of sections) {
36586
+ if (section.category) {
36587
+ parts.push(`### ${section.category}
36588
+
36589
+ ${section.items.join(`
36590
+ `)}`);
36591
+ } else {
36592
+ parts.push(section.items.join(`
36593
+ `));
36594
+ }
36595
+ }
36596
+ return parts.join(`
36597
+
36598
+ `);
36599
+ }
36600
+ async function buildReleaseBody(ctx, options) {
36601
+ const { pkgPath, version, tag, repositoryUrl } = options;
36602
+ const appendCompareLink = options.appendCompareLink ?? true;
36603
+ const git = new Git;
36604
+ const previousTag = options.previousTag ?? (await git.previousTag(tag) || await git.firstCommit());
36605
+ const compareLink = `**Full Changelog**: ${repositoryUrl}/compare/${previousTag}...${tag}`;
36606
+ const changelogBody = extractChangelog(ctx, pkgPath, version);
36607
+ if (changelogBody) {
36608
+ return appendCompareLink ? `${changelogBody}
36609
+
36610
+ ${compareLink}` : changelogBody;
36611
+ }
36612
+ const commits = await git.commits(previousTag, tag);
36613
+ if (commits.length === 0) {
36614
+ return appendCompareLink ? compareLink : "";
36615
+ }
36616
+ const rawCommits = getCommitsSinceRef(ctx.cwd, previousTag, tag);
36617
+ const parsed = rawCommits.map((c2) => parseConventionalCommit(c2.hash, c2.message, c2.files)).filter((c2) => c2 !== null);
36618
+ const filtered = pkgPath ? parsed.filter((c2) => {
36619
+ const packages = resolveCommitPackages(c2, [pkgPath]);
36620
+ return packages.length > 0;
36621
+ }) : parsed;
36622
+ if (filtered.length > 0) {
36623
+ const entries = filtered.map((c2) => ({
36624
+ summary: c2.description,
36625
+ type: c2.type,
36626
+ hash: c2.hash.slice(0, 7)
36627
+ }));
36628
+ const writer = new ConventionalCommitChangelogWriter;
36629
+ const sections = writer.formatEntries(entries);
36630
+ const body2 = renderReleaseNoteSections(sections);
36631
+ return appendCompareLink ? `${body2}
36632
+
36633
+ ${compareLink}` : body2;
36634
+ }
36635
+ const lines = commits.map(({ id, message }) => `- ${message} (${id.slice(0, 7)})`);
36636
+ const body = lines.join(`
36637
+ `);
36638
+ return appendCompareLink ? `${body}
36639
+
36640
+ ${compareLink}` : body;
36641
+ }
36642
+ function extractChangelog(ctx, pkgPath, version) {
36643
+ const changelogPath = pkgPath ? import_node_path23.join(ctx.cwd, pkgPath, "CHANGELOG.md") : import_node_path23.join(ctx.cwd, "CHANGELOG.md");
36644
+ if (!import_node_fs13.existsSync(changelogPath))
36645
+ return null;
36646
+ return parseChangelogSection(import_node_fs13.readFileSync(changelogPath, "utf-8"), version);
36647
+ }
36648
+ var MAX_URL_LENGTH = 8000;
36649
+ async function truncateForUrl(body, baseUrl) {
36650
+ const testUrl = `${baseUrl}${encodeURIComponent(body)}`;
36651
+ if (testUrl.length <= MAX_URL_LENGTH) {
36652
+ return { body, truncated: false, clipboardCopied: false };
36653
+ }
36654
+ const clipboardCopied = await copyToClipboard(body);
36655
+ const suffix = clipboardCopied ? `
36656
+
36657
+ ... (truncated, full notes copied to clipboard)` : `
36658
+
36659
+ ... (truncated)`;
36660
+ const availableLength = MAX_URL_LENGTH - baseUrl.length - encodeURIComponent(suffix).length;
36661
+ let lo = 0;
36662
+ let hi = body.length;
36663
+ while (lo < hi) {
36664
+ const mid = Math.ceil((lo + hi) / 2);
36665
+ if (encodeURIComponent(body.slice(0, mid)).length <= availableLength) {
36666
+ lo = mid;
36667
+ } else {
36668
+ hi = mid - 1;
36669
+ }
36670
+ }
36671
+ return {
36672
+ body: body.slice(0, lo) + suffix,
36673
+ truncated: true,
36674
+ clipboardCopied
36675
+ };
36676
+ }
36677
+
36678
+ // src/tasks/runner-utils/version-pr.ts
36679
+ var import_node_fs14 = require("node:fs");
36680
+ var import_node_path24 = __toESM(require("node:path"));
36681
+ var import_node_process17 = __toESM(require("node:process"));
36682
+ init_error4();
36683
+ init_git();
36684
+ init_i18n();
36685
+
36686
+ // src/tasks/create-version-pr.ts
36687
+ init_error4();
36688
+ init_i18n();
36689
+ init_exec();
36690
+
36691
+ class VersionPrError extends AbstractError {
36692
+ name = "Version PR Error";
36693
+ }
36694
+ async function createVersionPr(options) {
36695
+ try {
36696
+ return await createPrViaGhCli(options);
36697
+ } catch {
36698
+ return await createPrViaApi(options);
36699
+ }
36700
+ }
36701
+ async function closeVersionPr(options) {
36702
+ try {
36703
+ await closePrViaGhCli(options);
36704
+ } catch {
36705
+ await closePrViaApi(options);
36706
+ }
36707
+ }
36708
+ async function createPrViaGhCli(options) {
36709
+ const args = [
36710
+ "pr",
36711
+ "create",
36712
+ "--title",
36713
+ options.title,
36714
+ "--body",
36715
+ options.body,
36716
+ "--base",
36717
+ options.base,
36718
+ "--head",
36719
+ options.branch
36720
+ ];
36721
+ if (options.labels && options.labels.length > 0) {
36722
+ args.push("--label", options.labels.join(","));
36723
+ }
36724
+ const { stdout } = await exec3("gh", args, { throwOnError: true });
36725
+ const url = stdout.trim();
36726
+ const numberMatch = url.match(/\/pull\/(\d+)/);
36727
+ const number2 = numberMatch ? Number.parseInt(numberMatch[1], 10) : 0;
36728
+ return { url, number: number2 };
36729
+ }
36730
+ async function createPrViaApi(options) {
36731
+ const response = await fetch(`https://api.github.com/repos/${options.owner}/${options.repo}/pulls`, {
36732
+ method: "POST",
36733
+ headers: {
36734
+ Authorization: `Bearer ${options.token}`,
36735
+ Accept: "application/vnd.github+json",
36736
+ "X-GitHub-Api-Version": "2022-11-28"
36236
36737
  },
36237
36738
  body: JSON.stringify({
36238
36739
  title: options.title,
@@ -36329,7 +36830,7 @@ async function pushViaPr(ctx, git, task) {
36329
36830
  const prBody = buildPrBodyFromContext(ctx, plan);
36330
36831
  const remoteUrl = await git.repository();
36331
36832
  const { owner, repo } = parseOwnerRepo(remoteUrl);
36332
- const token = import_node_process16.default.env.GITHUB_TOKEN;
36833
+ const token = import_node_process17.default.env.GITHUB_TOKEN;
36333
36834
  if (!token) {
36334
36835
  throw new AbstractError(t("error.githubRelease.tokenRequired"));
36335
36836
  }
@@ -36361,10 +36862,10 @@ function buildPrBodyFromContext(ctx, plan) {
36361
36862
  const pkgConfig = ctx.config.packages.find((p2) => p2.path === pkgPath);
36362
36863
  const name = pkgConfig?.name ?? pkgPath;
36363
36864
  packages.push({ name, version: pkgVersion, bump: "" });
36364
- const changelogDir = pkgConfig ? import_node_path22.default.resolve(ctx.cwd, pkgConfig.path) : ctx.cwd;
36365
- const changelogPath = import_node_path22.default.join(changelogDir, "CHANGELOG.md");
36366
- if (import_node_fs13.existsSync(changelogPath)) {
36367
- const section = parseChangelogSection(import_node_fs13.readFileSync(changelogPath, "utf-8"), pkgVersion);
36865
+ const changelogDir = pkgConfig ? import_node_path24.default.resolve(ctx.cwd, pkgConfig.path) : ctx.cwd;
36866
+ const changelogPath = import_node_path24.default.join(changelogDir, "CHANGELOG.md");
36867
+ if (import_node_fs14.existsSync(changelogPath)) {
36868
+ const section = parseChangelogSection(import_node_fs14.readFileSync(changelogPath, "utf-8"), pkgVersion);
36368
36869
  if (section)
36369
36870
  changelogs.set(name, section);
36370
36871
  }
@@ -36375,17 +36876,17 @@ function buildPrBodyFromContext(ctx, plan) {
36375
36876
  packages.push({ name: pkg.name, version, bump: "" });
36376
36877
  }
36377
36878
  if (plan.mode === "single") {
36378
- const changelogPath = import_node_path22.default.join(ctx.cwd, "CHANGELOG.md");
36379
- if (import_node_fs13.existsSync(changelogPath)) {
36380
- const section = parseChangelogSection(import_node_fs13.readFileSync(changelogPath, "utf-8"), version);
36879
+ const changelogPath = import_node_path24.default.join(ctx.cwd, "CHANGELOG.md");
36880
+ if (import_node_fs14.existsSync(changelogPath)) {
36881
+ const section = parseChangelogSection(import_node_fs14.readFileSync(changelogPath, "utf-8"), version);
36381
36882
  if (section)
36382
36883
  changelogs.set(packages[0]?.name ?? "", section);
36383
36884
  }
36384
36885
  } else {
36385
36886
  for (const pkg of ctx.config.packages) {
36386
- const changelogPath = import_node_path22.default.join(ctx.cwd, pkg.path, "CHANGELOG.md");
36387
- if (import_node_fs13.existsSync(changelogPath)) {
36388
- const section = parseChangelogSection(import_node_fs13.readFileSync(changelogPath, "utf-8"), version);
36887
+ const changelogPath = import_node_path24.default.join(ctx.cwd, pkg.path, "CHANGELOG.md");
36888
+ if (import_node_fs14.existsSync(changelogPath)) {
36889
+ const section = parseChangelogSection(import_node_fs14.readFileSync(changelogPath, "utf-8"), version);
36389
36890
  if (section)
36390
36891
  changelogs.set(pkg.name, section);
36391
36892
  }
@@ -36443,7 +36944,7 @@ function createReleaseTask(hasPublish, dryRun, mode, skipReleaseDraft) {
36443
36944
  const tokenResult = resolveGitHubToken();
36444
36945
  let hasToken = !!tokenResult;
36445
36946
  if (tokenResult) {
36446
- import_node_process17.default.env.GITHUB_TOKEN = tokenResult.token;
36947
+ import_node_process18.default.env.GITHUB_TOKEN = tokenResult.token;
36447
36948
  } else if (mode !== "ci") {
36448
36949
  const answer = await task.prompt(ListrEnquirerPromptAdapter).run({
36449
36950
  type: "select",
@@ -36463,7 +36964,7 @@ function createReleaseTask(hasPublish, dryRun, mode, skipReleaseDraft) {
36463
36964
  message: t("task.release.tokenPrompt")
36464
36965
  });
36465
36966
  if (token) {
36466
- import_node_process17.default.env.GITHUB_TOKEN = token;
36967
+ import_node_process18.default.env.GITHUB_TOKEN = token;
36467
36968
  saveGitHubToken(token);
36468
36969
  hasToken = true;
36469
36970
  }
@@ -36483,22 +36984,20 @@ function createReleaseTask(hasPublish, dryRun, mode, skipReleaseDraft) {
36483
36984
  const pkgName = getPackageName(ctx, pkgPath);
36484
36985
  const tag = `${pkgName}@${pkgVersion}`;
36485
36986
  task.output = t("task.release.creating", { tag });
36486
- let changelogBody;
36487
- const pkgConfig = ctx.config.packages.find((p2) => p2.path === pkgPath);
36488
- if (pkgConfig) {
36489
- const changelogPath = import_node_path23.join(ctx.cwd, pkgConfig.path, "CHANGELOG.md");
36490
- if (import_node_fs14.existsSync(changelogPath)) {
36491
- const section = parseChangelogSection(import_node_fs14.readFileSync(changelogPath, "utf-8"), pkgVersion);
36492
- if (section)
36493
- changelogBody = section;
36494
- }
36495
- }
36987
+ const git = new Git;
36988
+ const repositoryUrl = (await git.repository()).replace(/^git@github\.com:/, "https://github.com/").replace(/\.git$/, "");
36989
+ const body = await buildReleaseBody(ctx, {
36990
+ pkgPath,
36991
+ version: pkgVersion,
36992
+ tag,
36993
+ repositoryUrl
36994
+ });
36496
36995
  const { assets: preparedAssets, tempDir } = await prepareReleaseAssets(ctx, pkgName, pkgVersion, pkgPath);
36497
36996
  const result = await createGitHubRelease(ctx, {
36498
36997
  displayLabel: pkgName,
36499
36998
  version: pkgVersion,
36500
36999
  tag,
36501
- changelogBody,
37000
+ body,
36502
37001
  assets: preparedAssets,
36503
37002
  draft: !!ctx.options.releaseDraft
36504
37003
  });
@@ -36530,45 +37029,20 @@ function createReleaseTask(hasPublish, dryRun, mode, skipReleaseDraft) {
36530
37029
  task.output = t("task.release.alreadyExists", { tag });
36531
37030
  }
36532
37031
  if (tempDir)
36533
- import_node_fs14.rmSync(tempDir, { recursive: true, force: true });
37032
+ import_node_fs15.rmSync(tempDir, { recursive: true, force: true });
36534
37033
  }
36535
37034
  } else {
36536
37035
  const version = plan.version;
36537
37036
  const tag = `v${version}`;
36538
37037
  task.output = t("task.release.creating", { tag });
36539
- let changelogBody;
36540
- if (plan.mode === "fixed") {
36541
- const sections = [];
36542
- for (const [pkgPath2, pkgVersion] of plan.packages) {
36543
- const pkgName = getPackageName(ctx, pkgPath2);
36544
- const pkgConfig = ctx.config.packages.find((p2) => p2.path === pkgPath2);
36545
- if (!pkgConfig)
36546
- continue;
36547
- const changelogPath = import_node_path23.join(ctx.cwd, pkgConfig.path, "CHANGELOG.md");
36548
- if (import_node_fs14.existsSync(changelogPath)) {
36549
- const section = parseChangelogSection(import_node_fs14.readFileSync(changelogPath, "utf-8"), pkgVersion);
36550
- if (section) {
36551
- sections.push(`## ${pkgName} v${pkgVersion}
36552
-
36553
- ${section}`);
36554
- }
36555
- }
36556
- }
36557
- if (sections.length > 0) {
36558
- changelogBody = sections.join(`
36559
-
36560
- ---
36561
-
36562
- `);
36563
- }
36564
- } else {
36565
- const changelogPath = import_node_path23.join(ctx.cwd, "CHANGELOG.md");
36566
- if (import_node_fs14.existsSync(changelogPath)) {
36567
- const section = parseChangelogSection(import_node_fs14.readFileSync(changelogPath, "utf-8"), version);
36568
- if (section)
36569
- changelogBody = section;
36570
- }
36571
- }
37038
+ const git = new Git;
37039
+ const repositoryUrl = (await git.repository()).replace(/^git@github\.com:/, "https://github.com/").replace(/\.git$/, "");
37040
+ const body = await buildReleaseBody(ctx, {
37041
+ pkgPath: plan.mode === "single" ? plan.packagePath : undefined,
37042
+ version,
37043
+ tag,
37044
+ repositoryUrl
37045
+ });
36572
37046
  const packageName = plan.mode === "single" ? getPackageName(ctx, plan.packagePath) : ctx.config.packages[0]?.name ?? "";
36573
37047
  const pkgPath = plan.mode === "single" ? plan.packagePath : ctx.config.packages[0]?.path;
36574
37048
  const { assets: preparedAssets, tempDir } = await prepareReleaseAssets(ctx, packageName, version, pkgPath);
@@ -36576,7 +37050,7 @@ ${section}`);
36576
37050
  displayLabel: packageName,
36577
37051
  version,
36578
37052
  tag,
36579
- changelogBody,
37053
+ body,
36580
37054
  assets: preparedAssets,
36581
37055
  draft: !!ctx.options.releaseDraft
36582
37056
  });
@@ -36606,7 +37080,7 @@ ${section}`);
36606
37080
  task.output = t("task.release.alreadyExists", { tag });
36607
37081
  }
36608
37082
  if (tempDir)
36609
- import_node_fs14.rmSync(tempDir, { recursive: true, force: true });
37083
+ import_node_fs15.rmSync(tempDir, { recursive: true, force: true });
36610
37084
  }
36611
37085
  } else {
36612
37086
  const git = new Git;
@@ -36622,21 +37096,31 @@ ${section}`);
36622
37096
  continue;
36623
37097
  const pkgName = getPackageName(ctx, pkgPath);
36624
37098
  const tag = `${pkgName}@${pkgVersion}`;
36625
- const lastRev = await git.previousTag(tag) || await git.firstCommit();
36626
- const commits = (await git.commits(lastRev, tag)).slice(1);
36627
- let body = commits.map(({ id, message }) => `- ${message.replace(/#/g, `${repositoryUrl}/issues/`)} ${repositoryUrl}/commit/${id}`).join(`
36628
- `);
36629
- body += `
36630
-
36631
- ${repositoryUrl}/compare/${lastRev}...${tag}`;
37099
+ const body = await buildReleaseBody(ctx, {
37100
+ pkgPath,
37101
+ version: pkgVersion,
37102
+ tag,
37103
+ repositoryUrl
37104
+ });
36632
37105
  const releaseDraftUrl = new URL(`${repositoryUrl}/releases/new`);
36633
37106
  releaseDraftUrl.searchParams.set("tag", tag);
36634
- releaseDraftUrl.searchParams.set("body", body);
36635
37107
  releaseDraftUrl.searchParams.set("prerelease", `${!!prerelease2(pkgVersion)}`);
37108
+ const baseUrl = `${releaseDraftUrl.toString()}&body=`;
37109
+ const truncated = await truncateForUrl(body, baseUrl);
37110
+ releaseDraftUrl.searchParams.set("body", truncated.body);
36636
37111
  const linkUrl = ui.link(tag, releaseDraftUrl.toString());
36637
37112
  task.title += ` ${linkUrl}`;
36638
37113
  if (first) {
36639
- task.output = t("task.release.openingDraft", { tag });
37114
+ const openingMsg = t("task.release.openingDraft", { tag });
37115
+ if (truncated.clipboardCopied) {
37116
+ task.output = `${t("task.release.copiedToClipboard")}
37117
+ ${openingMsg}`;
37118
+ } else if (truncated.truncated) {
37119
+ task.output = `${t("task.release.truncated")}
37120
+ ${openingMsg}`;
37121
+ } else {
37122
+ task.output = openingMsg;
37123
+ }
36640
37124
  await openUrl(releaseDraftUrl.toString());
36641
37125
  first = false;
36642
37126
  }
@@ -36644,24 +37128,30 @@ ${repositoryUrl}/compare/${lastRev}...${tag}`;
36644
37128
  } else {
36645
37129
  const version = plan.version;
36646
37130
  const tag = `v${version}`;
36647
- const lastRev = await git.previousTag(tag) || await git.firstCommit();
36648
- const commits = (await git.commits(lastRev, tag)).slice(1);
36649
- task.output = t("task.release.collectedCommits", {
36650
- count: commits.length,
36651
- tag
37131
+ const body = await buildReleaseBody(ctx, {
37132
+ pkgPath: plan.mode === "single" ? plan.packagePath : undefined,
37133
+ version,
37134
+ tag,
37135
+ repositoryUrl
36652
37136
  });
36653
- let body = commits.map(({ id, message }) => `- ${message.replace(/#/g, `${repositoryUrl}/issues/`)} ${repositoryUrl}/commit/${id}`).join(`
36654
- `);
36655
- body += `
36656
-
36657
- ${repositoryUrl}/compare/${lastRev}...${tag}`;
36658
37137
  const releaseDraftUrl = new URL(`${repositoryUrl}/releases/new`);
36659
37138
  releaseDraftUrl.searchParams.set("tag", tag);
36660
- releaseDraftUrl.searchParams.set("body", body);
36661
37139
  releaseDraftUrl.searchParams.set("prerelease", `${!!prerelease2(version)}`);
37140
+ const baseUrl = `${releaseDraftUrl.toString()}&body=`;
37141
+ const truncated = await truncateForUrl(body, baseUrl);
37142
+ releaseDraftUrl.searchParams.set("body", truncated.body);
36662
37143
  const linkUrl = ui.link("Link", releaseDraftUrl.toString());
36663
37144
  task.title += ` ${linkUrl}`;
36664
- task.output = t("task.release.openingDraft", { tag });
37145
+ const openingMsg = t("task.release.openingDraft", { tag });
37146
+ if (truncated.clipboardCopied) {
37147
+ task.output = `${t("task.release.copiedToClipboard")}
37148
+ ${openingMsg}`;
37149
+ } else if (truncated.truncated) {
37150
+ task.output = `${t("task.release.truncated")}
37151
+ ${openingMsg}`;
37152
+ } else {
37153
+ task.output = openingMsg;
37154
+ }
36665
37155
  await openUrl(releaseDraftUrl.toString());
36666
37156
  }
36667
37157
  }
@@ -36673,7 +37163,7 @@ ${repositoryUrl}/compare/${lastRev}...${tag}`;
36673
37163
  init_catalog2();
36674
37164
  init_error4();
36675
37165
  init_i18n();
36676
- var import_node_path24 = __toESM(require("node:path"));
37166
+ var import_node_path25 = __toESM(require("node:path"));
36677
37167
  init_exec();
36678
37168
  var JS_WORKSPACE_TYPES = new Set(["pnpm", "npm", "yarn", "bun", "deno"]);
36679
37169
  var ECOSYSTEM_DEFAULTS = {
@@ -36758,7 +37248,7 @@ async function resolveExecutions(ctx, type) {
36758
37248
  });
36759
37249
  } else {
36760
37250
  for (const pkg of group.groupPackages) {
36761
- const pkgCwd = import_node_path24.default.resolve(ctx.cwd, pkg.path);
37251
+ const pkgCwd = import_node_path25.default.resolve(ctx.cwd, pkg.path);
36762
37252
  executions.push({
36763
37253
  label: `${resolved.command} (${pkg.path})`,
36764
37254
  cmd: "sh",
@@ -36779,7 +37269,7 @@ async function resolveExecutions(ctx, type) {
36779
37269
  });
36780
37270
  } else {
36781
37271
  for (const pkg of group.groupPackages) {
36782
- const pkgCwd = import_node_path24.default.resolve(ctx.cwd, pkg.path);
37272
+ const pkgCwd = import_node_path25.default.resolve(ctx.cwd, pkg.path);
36783
37273
  const instance = new descriptor.ecosystemClass(pkgCwd);
36784
37274
  const { cmd, args } = type === "test" ? await instance.resolveTestCommand(resolved.script) : await instance.resolveBuildCommand(resolved.script);
36785
37275
  executions.push({
@@ -36793,7 +37283,7 @@ async function resolveExecutions(ctx, type) {
36793
37283
  }
36794
37284
  }
36795
37285
  for (const pkg of group.individualPackages) {
36796
- const pkgCwd = import_node_path24.default.resolve(ctx.cwd, pkg.path);
37286
+ const pkgCwd = import_node_path25.default.resolve(ctx.cwd, pkg.path);
36797
37287
  const resolved = resolveScript(pkg, group.ecosystemKey, ctx, type);
36798
37288
  if (resolved.command) {
36799
37289
  executions.push({
@@ -36891,16 +37381,16 @@ function createBuildTask(hasPrepare, skipBuild) {
36891
37381
 
36892
37382
  // src/tasks/phases/version.ts
36893
37383
  init_dist2();
36894
- var import_node_path27 = __toESM(require("node:path"));
37384
+ var import_node_path28 = __toESM(require("node:path"));
36895
37385
 
36896
37386
  // src/changelog/file.ts
36897
- var import_node_fs15 = require("node:fs");
36898
- var import_node_path25 = __toESM(require("node:path"));
37387
+ var import_node_fs16 = require("node:fs");
37388
+ var import_node_path26 = __toESM(require("node:path"));
36899
37389
  function writeChangelogToFile(cwd, newContent) {
36900
- const changelogPath = import_node_path25.default.join(cwd, "CHANGELOG.md");
37390
+ const changelogPath = import_node_path26.default.join(cwd, "CHANGELOG.md");
36901
37391
  let existing = "";
36902
- if (import_node_fs15.existsSync(changelogPath)) {
36903
- existing = import_node_fs15.readFileSync(changelogPath, "utf-8");
37392
+ if (import_node_fs16.existsSync(changelogPath)) {
37393
+ existing = import_node_fs16.readFileSync(changelogPath, "utf-8");
36904
37394
  }
36905
37395
  const header = `# Changelog
36906
37396
 
@@ -36909,7 +37399,7 @@ function writeChangelogToFile(cwd, newContent) {
36909
37399
 
36910
37400
  `);
36911
37401
  const body = existing.startsWith("# Changelog") && doubleNewline !== -1 ? existing.slice(doubleNewline + 2) : existing;
36912
- import_node_fs15.writeFileSync(changelogPath, `${header}${newContent}
37402
+ import_node_fs16.writeFileSync(changelogPath, `${header}${newContent}
36913
37403
  ${body}`, "utf-8");
36914
37404
  }
36915
37405
 
@@ -36944,6 +37434,21 @@ function generateChangelog(version, entries, depUpdates) {
36944
37434
  `)}
36945
37435
  `;
36946
37436
  }
37437
+ var BUMP_PRIORITY = {
37438
+ major: 3,
37439
+ minor: 2,
37440
+ patch: 1
37441
+ };
37442
+ function deduplicateEntries(entries) {
37443
+ const map = new Map;
37444
+ for (const entry of entries) {
37445
+ const existing = map.get(entry.id);
37446
+ if (!existing || (BUMP_PRIORITY[entry.type] ?? 0) > (BUMP_PRIORITY[existing.type] ?? 0)) {
37447
+ map.set(entry.id, entry);
37448
+ }
37449
+ }
37450
+ return [...map.values()];
37451
+ }
36947
37452
  function buildChangelogEntries(changesets, packagePath) {
36948
37453
  const entries = [];
36949
37454
  for (const changeset of changesets) {
@@ -36961,9 +37466,9 @@ function buildChangelogEntries(changesets, packagePath) {
36961
37466
  }
36962
37467
 
36963
37468
  // src/changeset/reader.ts
36964
- var import_node_fs16 = require("node:fs");
36965
- var import_node_path26 = __toESM(require("node:path"));
36966
- var import_node_process18 = __toESM(require("node:process"));
37469
+ var import_node_fs17 = require("node:fs");
37470
+ var import_node_path27 = __toESM(require("node:path"));
37471
+ var import_node_process19 = __toESM(require("node:process"));
36967
37472
 
36968
37473
  // src/changeset/parser.ts
36969
37474
  var import_yaml2 = __toESM(require_dist(), 1);
@@ -36983,8 +37488,8 @@ function parseChangeset(content, fileName, resolveKey) {
36983
37488
  if (!VALID_BUMP_TYPES.has(type)) {
36984
37489
  throw new Error(`Invalid bump type "${type}" for package "${key}" in "${fileName}". Expected: patch, minor, or major.`);
36985
37490
  }
36986
- const path16 = resolveKey ? resolveKey(key) : key;
36987
- releases.push({ path: path16, type });
37491
+ const path17 = resolveKey ? resolveKey(key) : key;
37492
+ releases.push({ path: path17, type });
36988
37493
  }
36989
37494
  }
36990
37495
  const id = fileName.replace(/\.md$/, "");
@@ -36996,29 +37501,29 @@ function parseChangeset(content, fileName, resolveKey) {
36996
37501
  }
36997
37502
 
36998
37503
  // src/changeset/reader.ts
36999
- function readChangesets(cwd = import_node_process18.default.cwd(), resolveKey) {
37000
- const changesetsDir = import_node_path26.default.join(cwd, ".pubm", "changesets");
37001
- if (!import_node_fs16.existsSync(changesetsDir)) {
37504
+ function readChangesets(cwd = import_node_process19.default.cwd(), resolveKey) {
37505
+ const changesetsDir = import_node_path27.default.join(cwd, ".pubm", "changesets");
37506
+ if (!import_node_fs17.existsSync(changesetsDir)) {
37002
37507
  return [];
37003
37508
  }
37004
- const files = import_node_fs16.readdirSync(changesetsDir);
37509
+ const files = import_node_fs17.readdirSync(changesetsDir);
37005
37510
  const changesets = [];
37006
37511
  for (const file of files) {
37007
37512
  if (!file.endsWith(".md") || file === "README.md") {
37008
37513
  continue;
37009
37514
  }
37010
- const filePath = import_node_path26.default.join(changesetsDir, file);
37011
- const content = import_node_fs16.readFileSync(filePath, "utf-8");
37515
+ const filePath = import_node_path27.default.join(changesetsDir, file);
37516
+ const content = import_node_fs17.readFileSync(filePath, "utf-8");
37012
37517
  changesets.push(parseChangeset(content, file, resolveKey));
37013
37518
  }
37014
37519
  return changesets;
37015
37520
  }
37016
37521
  function deleteChangesetFiles(cwd, changesets) {
37017
- const changesetsDir = import_node_path26.default.join(cwd, ".pubm", "changesets");
37522
+ const changesetsDir = import_node_path27.default.join(cwd, ".pubm", "changesets");
37018
37523
  for (const changeset of changesets) {
37019
- const filePath = import_node_path26.default.join(changesetsDir, `${changeset.id}.md`);
37020
- if (import_node_fs16.existsSync(filePath)) {
37021
- import_node_fs16.rmSync(filePath);
37524
+ const filePath = import_node_path27.default.join(changesetsDir, `${changeset.id}.md`);
37525
+ if (import_node_fs17.existsSync(filePath)) {
37526
+ import_node_fs17.rmSync(filePath);
37022
37527
  }
37023
37528
  }
37024
37529
  }
@@ -37073,7 +37578,7 @@ function createVersionTask(hasPrepare, dryRun) {
37073
37578
  const changesets = readChangesets(ctx.cwd, resolver);
37074
37579
  if (changesets.length > 0) {
37075
37580
  registerChangesetBackups(ctx, changesets);
37076
- const changelogPath = import_node_path27.default.join(ctx.cwd, "CHANGELOG.md");
37581
+ const changelogPath = import_node_path28.default.join(ctx.cwd, "CHANGELOG.md");
37077
37582
  registerChangelogBackup(ctx, changelogPath);
37078
37583
  const pkgPath = ctx.config.packages[0]?.path ?? "";
37079
37584
  const entries = buildChangelogEntries(changesets, pkgPath);
@@ -37130,9 +37635,9 @@ ${ctx.config.packages.map((pkg) => `- ${pkg.name}: ${plan.version}`).join(`
37130
37635
  const changesets = readChangesets(ctx.cwd, resolver);
37131
37636
  if (changesets.length > 0) {
37132
37637
  registerChangesetBackups(ctx, changesets);
37133
- const changelogPath = import_node_path27.default.join(ctx.cwd, "CHANGELOG.md");
37638
+ const changelogPath = import_node_path28.default.join(ctx.cwd, "CHANGELOG.md");
37134
37639
  registerChangelogBackup(ctx, changelogPath);
37135
- const allEntries = [...plan.packages.keys()].flatMap((pkgPath) => buildChangelogEntries(changesets, pkgPath));
37640
+ const allEntries = deduplicateEntries([...plan.packages.keys()].flatMap((pkgPath) => buildChangelogEntries(changesets, pkgPath)));
37136
37641
  if (allEntries.length > 0) {
37137
37642
  const changelogContent = generateChangelog(plan.version, allEntries);
37138
37643
  writeChangelogToFile(ctx.cwd, changelogContent);
@@ -37190,15 +37695,15 @@ ${[...plan.packages].map(([pkgPath]) => `- ${getPackageName(ctx, pkgPath)}: ${pl
37190
37695
  registerChangesetBackups(ctx, changesets);
37191
37696
  for (const [pkgPath] of plan.packages) {
37192
37697
  const pkgConfig = ctx.config.packages.find((p2) => p2.path === pkgPath);
37193
- const changelogDir = pkgConfig ? import_node_path27.default.resolve(ctx.cwd, pkgConfig.path) : ctx.cwd;
37194
- const changelogPath = import_node_path27.default.join(changelogDir, "CHANGELOG.md");
37698
+ const changelogDir = pkgConfig ? import_node_path28.default.resolve(ctx.cwd, pkgConfig.path) : ctx.cwd;
37699
+ const changelogPath = import_node_path28.default.join(changelogDir, "CHANGELOG.md");
37195
37700
  registerChangelogBackup(ctx, changelogPath);
37196
37701
  }
37197
37702
  for (const [pkgPath, pkgVersion] of plan.packages) {
37198
37703
  const entries = buildChangelogEntries(changesets, pkgPath);
37199
37704
  if (entries.length > 0) {
37200
37705
  const pkgConfig = ctx.config.packages.find((p2) => p2.path === pkgPath);
37201
- const changelogDir = pkgConfig ? import_node_path27.default.resolve(ctx.cwd, pkgConfig.path) : ctx.cwd;
37706
+ const changelogDir = pkgConfig ? import_node_path28.default.resolve(ctx.cwd, pkgConfig.path) : ctx.cwd;
37202
37707
  writeChangelogToFile(changelogDir, generateChangelog(pkgVersion, entries));
37203
37708
  }
37204
37709
  }
@@ -37261,7 +37766,7 @@ function chainCleanup(existing, next) {
37261
37766
  };
37262
37767
  }
37263
37768
  async function run(ctx) {
37264
- ctx.runtime.promptEnabled = !m && import_node_process19.default.stdin.isTTY;
37769
+ ctx.runtime.promptEnabled = !m && import_node_process20.default.stdin.isTTY;
37265
37770
  const mode = ctx.options.mode ?? "local";
37266
37771
  const phases = resolvePhases(ctx.options);
37267
37772
  const dryRun = !!ctx.options.dryRun;
@@ -37276,12 +37781,12 @@ async function run(ctx) {
37276
37781
  interactive: false,
37277
37782
  sigint: true
37278
37783
  });
37279
- import_node_process19.default.exit(130);
37784
+ import_node_process20.default.exit(130);
37280
37785
  };
37281
- import_node_process19.default.on("SIGINT", onSigint);
37786
+ import_node_process20.default.on("SIGINT", onSigint);
37282
37787
  try {
37283
37788
  if (ctx.options.contents)
37284
- import_node_process19.default.chdir(ctx.options.contents);
37789
+ import_node_process20.default.chdir(ctx.options.contents);
37285
37790
  if (mode === "ci" && hasPrepare)
37286
37791
  await runCiPreparePreflight(ctx, chainCleanup, cleanupRef);
37287
37792
  if (mode === "local" && hasPrepare)
@@ -37309,7 +37814,7 @@ async function run(ctx) {
37309
37814
  parts.push(`${ui.chalk.bold(name)} on ${descriptor.label}`);
37310
37815
  }
37311
37816
  }
37312
- import_node_process19.default.removeListener("SIGINT", onSigint);
37817
+ import_node_process20.default.removeListener("SIGINT", onSigint);
37313
37818
  if (mode === "ci" && hasPrepare && !hasPublish) {
37314
37819
  cleanupRef.current?.();
37315
37820
  console.log(`
@@ -37329,14 +37834,14 @@ async function run(ctx) {
37329
37834
  }
37330
37835
  await ctx.runtime.pluginRunner.runHook("onSuccess", ctx);
37331
37836
  } catch (e3) {
37332
- import_node_process19.default.removeListener("SIGINT", onSigint);
37837
+ import_node_process20.default.removeListener("SIGINT", onSigint);
37333
37838
  cleanupRef.current?.();
37334
37839
  await ctx.runtime.pluginRunner.runErrorHook(ctx, e3);
37335
37840
  consoleError(e3);
37336
37841
  await ctx.runtime.rollback.execute(ctx, {
37337
37842
  interactive: ctx.runtime.promptEnabled
37338
37843
  });
37339
- import_node_process19.default.exit(1);
37844
+ import_node_process20.default.exit(1);
37340
37845
  }
37341
37846
  }
37342
37847
 
@@ -37352,62 +37857,6 @@ class ChangesetChangelogWriter {
37352
37857
  ];
37353
37858
  }
37354
37859
  }
37355
- // src/conventional-commit/types.ts
37356
- var DEFAULT_TYPE_BUMP_MAP = {
37357
- feat: "minor",
37358
- fix: "patch",
37359
- perf: "patch",
37360
- chore: false,
37361
- docs: false,
37362
- test: false,
37363
- ci: false,
37364
- style: false,
37365
- refactor: false
37366
- };
37367
- var COMMIT_TYPE_CATEGORY_MAP = {
37368
- feat: "Features",
37369
- fix: "Bug Fixes",
37370
- perf: "Performance",
37371
- refactor: "Refactoring",
37372
- docs: "Documentation"
37373
- };
37374
- var DEFAULT_CATEGORY = "Other Changes";
37375
-
37376
- // src/changelog/conventional-commit-writer.ts
37377
- var CATEGORY_ORDER = [
37378
- "Features",
37379
- "Bug Fixes",
37380
- "Performance",
37381
- "Refactoring",
37382
- "Documentation",
37383
- "Other Changes"
37384
- ];
37385
-
37386
- class ConventionalCommitChangelogWriter {
37387
- formatEntries(entries) {
37388
- if (entries.length === 0)
37389
- return [];
37390
- const groups = new Map;
37391
- for (const entry of entries) {
37392
- const category = entry.type && COMMIT_TYPE_CATEGORY_MAP[entry.type] || DEFAULT_CATEGORY;
37393
- const hashSuffix = entry.hash ? ` (${entry.hash})` : "";
37394
- const item = `- ${entry.summary}${hashSuffix}`;
37395
- const existing = groups.get(category);
37396
- if (existing) {
37397
- existing.push(item);
37398
- } else {
37399
- groups.set(category, [item]);
37400
- }
37401
- }
37402
- const sections = [];
37403
- for (const category of CATEGORY_ORDER) {
37404
- const items = groups.get(category);
37405
- if (items)
37406
- sections.push({ category, items });
37407
- }
37408
- return sections;
37409
- }
37410
- }
37411
37860
  // src/changelog/renderer.ts
37412
37861
  var BUMP_HEADINGS = {
37413
37862
  major: "Major Changes",
@@ -37449,13 +37898,13 @@ function maxBump(a3, b2) {
37449
37898
  return BUMP_ORDER2[a3] >= BUMP_ORDER2[b2] ? a3 : b2;
37450
37899
  }
37451
37900
  // src/changeset/migrate.ts
37452
- var import_node_fs17 = require("node:fs");
37453
- var import_node_path28 = __toESM(require("node:path"));
37454
- var import_node_process20 = __toESM(require("node:process"));
37901
+ var import_node_fs18 = require("node:fs");
37902
+ var import_node_path29 = __toESM(require("node:path"));
37903
+ var import_node_process21 = __toESM(require("node:process"));
37455
37904
  var SKIPPED_FILES = new Set(["config.json", "README.md"]);
37456
- function migrateFromChangesets(cwd = import_node_process20.default.cwd()) {
37457
- const changesetDir = import_node_path28.default.join(cwd, ".changeset");
37458
- if (!import_node_fs17.existsSync(changesetDir)) {
37905
+ function migrateFromChangesets(cwd = import_node_process21.default.cwd()) {
37906
+ const changesetDir = import_node_path29.default.join(cwd, ".changeset");
37907
+ if (!import_node_fs18.existsSync(changesetDir)) {
37459
37908
  return {
37460
37909
  success: false,
37461
37910
  error: ".changeset/ directory not found",
@@ -37463,9 +37912,9 @@ function migrateFromChangesets(cwd = import_node_process20.default.cwd()) {
37463
37912
  configMigrated: false
37464
37913
  };
37465
37914
  }
37466
- const pubmDir = import_node_path28.default.join(cwd, ".pubm", "changesets");
37467
- import_node_fs17.mkdirSync(pubmDir, { recursive: true });
37468
- const files = import_node_fs17.readdirSync(changesetDir);
37915
+ const pubmDir = import_node_path29.default.join(cwd, ".pubm", "changesets");
37916
+ import_node_fs18.mkdirSync(pubmDir, { recursive: true });
37917
+ const files = import_node_fs18.readdirSync(changesetDir);
37469
37918
  const migratedFiles = [];
37470
37919
  let configMigrated = false;
37471
37920
  for (const file of files) {
@@ -37477,14 +37926,14 @@ function migrateFromChangesets(cwd = import_node_process20.default.cwd()) {
37477
37926
  continue;
37478
37927
  }
37479
37928
  if (file === "pre.json") {
37480
- import_node_fs17.copyFileSync(import_node_path28.default.join(changesetDir, file), import_node_path28.default.resolve(cwd, ".pubm", "pre.json"));
37929
+ import_node_fs18.copyFileSync(import_node_path29.default.join(changesetDir, file), import_node_path29.default.resolve(cwd, ".pubm", "pre.json"));
37481
37930
  migratedFiles.push(file);
37482
37931
  continue;
37483
37932
  }
37484
37933
  if (file.endsWith(".md")) {
37485
- const src = import_node_path28.default.join(changesetDir, file);
37486
- const dest = import_node_path28.default.join(pubmDir, file);
37487
- import_node_fs17.copyFileSync(src, dest);
37934
+ const src = import_node_path29.default.join(changesetDir, file);
37935
+ const dest = import_node_path29.default.join(pubmDir, file);
37936
+ import_node_fs18.copyFileSync(src, dest);
37488
37937
  migratedFiles.push(file);
37489
37938
  }
37490
37939
  }
@@ -37495,8 +37944,8 @@ function migrateFromChangesets(cwd = import_node_process20.default.cwd()) {
37495
37944
  };
37496
37945
  }
37497
37946
  // src/changeset/status.ts
37498
- var import_node_process21 = __toESM(require("node:process"));
37499
- function getStatus(cwd = import_node_process21.default.cwd(), resolveKey) {
37947
+ var import_node_process22 = __toESM(require("node:process"));
37948
+ function getStatus(cwd = import_node_process22.default.cwd(), resolveKey) {
37500
37949
  const changesets = readChangesets(cwd, resolveKey);
37501
37950
  const packages = new Map;
37502
37951
  for (const changeset of changesets) {
@@ -37522,9 +37971,9 @@ function getStatus(cwd = import_node_process21.default.cwd(), resolveKey) {
37522
37971
  };
37523
37972
  }
37524
37973
  // src/changeset/version.ts
37525
- var import_node_process22 = __toESM(require("node:process"));
37974
+ var import_node_process23 = __toESM(require("node:process"));
37526
37975
  var import_semver5 = __toESM(require_semver2(), 1);
37527
- function calculateVersionBumps(currentVersions, cwd = import_node_process22.default.cwd(), resolveKey) {
37976
+ function calculateVersionBumps(currentVersions, cwd = import_node_process23.default.cwd(), resolveKey) {
37528
37977
  const changesets = readChangesets(cwd, resolveKey);
37529
37978
  const bumpTypes = new Map;
37530
37979
  for (const changeset of changesets) {
@@ -37556,9 +38005,9 @@ function calculateVersionBumps(currentVersions, cwd = import_node_process22.defa
37556
38005
  return result;
37557
38006
  }
37558
38007
  // src/changeset/writer.ts
37559
- var import_node_fs18 = require("node:fs");
37560
- var import_node_path29 = __toESM(require("node:path"));
37561
- var import_node_process23 = __toESM(require("node:process"));
38008
+ var import_node_fs19 = require("node:fs");
38009
+ var import_node_path30 = __toESM(require("node:path"));
38010
+ var import_node_process24 = __toESM(require("node:process"));
37562
38011
  var import_yaml3 = __toESM(require_dist(), 1);
37563
38012
  var adjectives = [
37564
38013
  "brave",
@@ -37653,20 +38102,20 @@ ${summary}
37653
38102
  }
37654
38103
  return content;
37655
38104
  }
37656
- function writeChangeset(releases, summary, cwd = import_node_process23.default.cwd()) {
37657
- const changesetsDir = import_node_path29.default.join(cwd, ".pubm", "changesets");
37658
- import_node_fs18.mkdirSync(changesetsDir, { recursive: true });
38105
+ function writeChangeset(releases, summary, cwd = import_node_process24.default.cwd()) {
38106
+ const changesetsDir = import_node_path30.default.join(cwd, ".pubm", "changesets");
38107
+ import_node_fs19.mkdirSync(changesetsDir, { recursive: true });
37659
38108
  const id = generateChangesetId();
37660
38109
  const fileName = `${id}.md`;
37661
- const filePath = import_node_path29.default.join(changesetsDir, fileName);
38110
+ const filePath = import_node_path30.default.join(changesetsDir, fileName);
37662
38111
  const content = generateChangesetContent(releases, summary);
37663
- import_node_fs18.writeFileSync(filePath, content, "utf-8");
38112
+ import_node_fs19.writeFileSync(filePath, content, "utf-8");
37664
38113
  return filePath;
37665
38114
  }
37666
38115
  // src/config/defaults.ts
37667
38116
  init_catalog2();
37668
38117
  init_i18n();
37669
- var import_node_path30 = __toESM(require("node:path"));
38118
+ var import_node_path31 = __toESM(require("node:path"));
37670
38119
  var import_micromatch4 = __toESM(require_micromatch(), 1);
37671
38120
  init_catalog();
37672
38121
  var defaultValidate = {
@@ -37751,7 +38200,7 @@ async function resolveConfig(config, cwd) {
37751
38200
  if (import_micromatch4.default.scan(normalized).isGlob) {
37752
38201
  return import_micromatch4.default.isMatch(pkgPathForward, normalized);
37753
38202
  }
37754
- return import_node_path30.default.normalize(cp.path) === pkg.path;
38203
+ return import_node_path31.default.normalize(cp.path) === pkg.path;
37755
38204
  });
37756
38205
  return {
37757
38206
  path: pkg.path,
@@ -37800,11 +38249,11 @@ function resolveEcosystemKey(pkg, _entry) {
37800
38249
  throw new Error(t("error.config.cannotInferEcosystem"));
37801
38250
  }
37802
38251
  // src/config/loader.ts
37803
- var import_node_child_process = require("node:child_process");
38252
+ var import_node_child_process2 = require("node:child_process");
37804
38253
  var import_promises8 = require("node:fs/promises");
37805
38254
  var import_node_module2 = require("node:module");
37806
38255
  var import_node_os5 = require("node:os");
37807
- var import_node_path31 = __toESM(require("node:path"));
38256
+ var import_node_path32 = __toESM(require("node:path"));
37808
38257
  var import_node_url = require("node:url");
37809
38258
  var import_node_vm = __toESM(require("node:vm"));
37810
38259
  var CONFIG_FILES = [
@@ -37857,7 +38306,7 @@ var CONFIG_MODULE_SHIMS = {
37857
38306
  };
37858
38307
  async function findConfigFile(cwd) {
37859
38308
  for (const file of CONFIG_FILES) {
37860
- const filePath = import_node_path31.default.join(cwd, file);
38309
+ const filePath = import_node_path32.default.join(cwd, file);
37861
38310
  try {
37862
38311
  if ((await import_promises8.stat(filePath)).isFile()) {
37863
38312
  return filePath;
@@ -37878,15 +38327,15 @@ function isBareSpecifier(specifier) {
37878
38327
  return !specifier.startsWith(".") && !specifier.startsWith("/") && !specifier.startsWith("file:") && !specifier.startsWith("node:");
37879
38328
  }
37880
38329
  async function findClosestPackageManifest(filePath) {
37881
- let current = import_node_path31.default.dirname(filePath);
38330
+ let current = import_node_path32.default.dirname(filePath);
37882
38331
  while (true) {
37883
- const manifestPath = import_node_path31.default.join(current, "package.json");
38332
+ const manifestPath = import_node_path32.default.join(current, "package.json");
37884
38333
  try {
37885
38334
  if ((await import_promises8.stat(manifestPath)).isFile()) {
37886
38335
  return manifestPath;
37887
38336
  }
37888
38337
  } catch {}
37889
- const parent = import_node_path31.default.dirname(current);
38338
+ const parent = import_node_path32.default.dirname(current);
37890
38339
  if (parent === current) {
37891
38340
  return null;
37892
38341
  }
@@ -37988,13 +38437,13 @@ async function collectOptionalDependenciesForInputs(inputPaths) {
37988
38437
  async function findInstalledPackagePath(startDir, dependency) {
37989
38438
  let current = startDir;
37990
38439
  while (true) {
37991
- const packageDir = import_node_path31.default.join(current, "node_modules", dependency);
38440
+ const packageDir = import_node_path32.default.join(current, "node_modules", dependency);
37992
38441
  try {
37993
38442
  if ((await import_promises8.stat(packageDir)).isDirectory()) {
37994
38443
  return packageDir;
37995
38444
  }
37996
38445
  } catch {}
37997
- const parent = import_node_path31.default.dirname(current);
38446
+ const parent = import_node_path32.default.dirname(current);
37998
38447
  if (parent === current) {
37999
38448
  return null;
38000
38449
  }
@@ -38002,19 +38451,19 @@ async function findInstalledPackagePath(startDir, dependency) {
38002
38451
  }
38003
38452
  }
38004
38453
  async function writeOptionalDependencyStubs(moduleDir, resolveFromDir, optionalDependencies) {
38005
- const nodeModulesDir = import_node_path31.default.join(moduleDir, "node_modules");
38454
+ const nodeModulesDir = import_node_path32.default.join(moduleDir, "node_modules");
38006
38455
  for (const dependency of optionalDependencies) {
38007
38456
  if (await findInstalledPackagePath(resolveFromDir, dependency)) {
38008
38457
  continue;
38009
38458
  }
38010
- const packageDir = import_node_path31.default.join(nodeModulesDir, dependency);
38459
+ const packageDir = import_node_path32.default.join(nodeModulesDir, dependency);
38011
38460
  await import_promises8.mkdir(packageDir, { recursive: true });
38012
- await import_promises8.writeFile(import_node_path31.default.join(packageDir, "package.json"), JSON.stringify({
38461
+ await import_promises8.writeFile(import_node_path32.default.join(packageDir, "package.json"), JSON.stringify({
38013
38462
  name: dependency,
38014
38463
  private: true,
38015
38464
  main: "./index.js"
38016
38465
  }, null, 2), "utf8");
38017
- await import_promises8.writeFile(import_node_path31.default.join(packageDir, "index.js"), createOptionalDependencyProxyPackage(dependency), "utf8");
38466
+ await import_promises8.writeFile(import_node_path32.default.join(packageDir, "index.js"), createOptionalDependencyProxyPackage(dependency), "utf8");
38018
38467
  }
38019
38468
  }
38020
38469
  function createOptionalDependencyPlugin(specifiers) {
@@ -38126,10 +38575,10 @@ async function buildConfigWithFormat(entrypoint, format3) {
38126
38575
  }
38127
38576
  async function buildConfigWithChildProcess(entrypoint, format3 = "esm") {
38128
38577
  const extension = format3 === "esm" ? "mjs" : "cjs";
38129
- const tempDir = await import_promises8.mkdtemp(import_node_path31.default.join(import_node_os5.tmpdir(), "pubm-config-"));
38130
- const buildScript = import_node_path31.default.join(tempDir, "build-config.mjs");
38131
- const outfile = import_node_path31.default.join(tempDir, `pubm.config.${extension}`);
38132
- const resultFile = import_node_path31.default.join(tempDir, "build-result.json");
38578
+ const tempDir = await import_promises8.mkdtemp(import_node_path32.default.join(import_node_os5.tmpdir(), "pubm-config-"));
38579
+ const buildScript = import_node_path32.default.join(tempDir, "build-config.mjs");
38580
+ const outfile = import_node_path32.default.join(tempDir, `pubm.config.${extension}`);
38581
+ const resultFile = import_node_path32.default.join(tempDir, "build-result.json");
38133
38582
  try {
38134
38583
  await import_promises8.writeFile(buildScript, [
38135
38584
  'import { readFile, stat, writeFile } from "node:fs/promises";',
@@ -38372,7 +38821,7 @@ async function buildConfigWithChildProcess(entrypoint, format3 = "esm") {
38372
38821
  ].join(`
38373
38822
  `), "utf8");
38374
38823
  await new Promise((resolve2, reject) => {
38375
- import_node_child_process.execFile("bun", [buildScript], (error4, _stdout, stderr) => {
38824
+ import_node_child_process2.execFile("bun", [buildScript], (error4, _stdout, stderr) => {
38376
38825
  if (error4) {
38377
38826
  reject(new Error(stderr || `Failed to build config via bun: ${error4.message}`));
38378
38827
  return;
@@ -38405,11 +38854,11 @@ async function buildConfigWithChildProcess(entrypoint, format3 = "esm") {
38405
38854
  }
38406
38855
  function rewriteImportMeta(source, configPath) {
38407
38856
  const replacements = [
38408
- ["import.meta.dirname", JSON.stringify(import_node_path31.default.dirname(configPath))],
38857
+ ["import.meta.dirname", JSON.stringify(import_node_path32.default.dirname(configPath))],
38409
38858
  ["import.meta.filename", JSON.stringify(configPath)],
38410
38859
  ["import.meta.path", JSON.stringify(configPath)],
38411
38860
  ["import.meta.url", JSON.stringify(import_node_url.pathToFileURL(configPath).href)],
38412
- ["import.meta.dir", JSON.stringify(import_node_path31.default.dirname(configPath))]
38861
+ ["import.meta.dir", JSON.stringify(import_node_path32.default.dirname(configPath))]
38413
38862
  ];
38414
38863
  let rewritten = source;
38415
38864
  for (const [pattern, value] of replacements) {
@@ -38425,10 +38874,10 @@ async function importConfigModule(configPath) {
38425
38874
  return normalizeConfigNamespace(namespace);
38426
38875
  }
38427
38876
  async function importBundledConfig(source, configPath, optionalDependencies) {
38428
- const tempDir = await import_promises8.mkdtemp(import_node_path31.default.join(import_node_path31.default.dirname(configPath), ".pubm-config-module-"));
38429
- const tempFile = import_node_path31.default.join(tempDir, "pubm.config.mjs");
38877
+ const tempDir = await import_promises8.mkdtemp(import_node_path32.default.join(import_node_path32.default.dirname(configPath), ".pubm-config-module-"));
38878
+ const tempFile = import_node_path32.default.join(tempDir, "pubm.config.mjs");
38430
38879
  try {
38431
- await writeOptionalDependencyStubs(tempDir, import_node_path31.default.dirname(configPath), optionalDependencies);
38880
+ await writeOptionalDependencyStubs(tempDir, import_node_path32.default.dirname(configPath), optionalDependencies);
38432
38881
  await import_promises8.writeFile(tempFile, source, "utf8");
38433
38882
  return importConfigModule(tempFile);
38434
38883
  } finally {
@@ -38443,7 +38892,7 @@ async function executeBundledConfigInVm(source, configPath) {
38443
38892
  exports: module2.exports,
38444
38893
  require: require2,
38445
38894
  __filename: configPath,
38446
- __dirname: import_node_path31.default.dirname(configPath),
38895
+ __dirname: import_node_path32.default.dirname(configPath),
38447
38896
  console,
38448
38897
  process,
38449
38898
  Buffer,
@@ -38474,7 +38923,7 @@ function formatStageError(stage, error4) {
38474
38923
  async function loadConfig(cwd = process.cwd(), configPath) {
38475
38924
  let resolvedConfigPath;
38476
38925
  if (configPath) {
38477
- resolvedConfigPath = import_node_path31.default.resolve(cwd, configPath);
38926
+ resolvedConfigPath = import_node_path32.default.resolve(cwd, configPath);
38478
38927
  try {
38479
38928
  if (!(await import_promises8.stat(resolvedConfigPath)).isFile()) {
38480
38929
  throw new Error(`Config path is not a file: ${resolvedConfigPath}`);
@@ -38553,36 +39002,6 @@ function defineConfig(config) {
38553
39002
  // src/index.ts
38554
39003
  init_context();
38555
39004
 
38556
- // src/conventional-commit/scope-resolver.ts
38557
- var import_node_path32 = __toESM(require("node:path"));
38558
- function resolveCommitPackages(commit, packagePaths) {
38559
- const matched = new Set;
38560
- if (commit.scope) {
38561
- for (const pkgPath of packagePaths) {
38562
- const dirName = import_node_path32.default.basename(pkgPath);
38563
- if (dirName === commit.scope) {
38564
- matched.add(pkgPath);
38565
- }
38566
- }
38567
- if (matched.size > 0)
38568
- return [...matched];
38569
- }
38570
- for (const file of commit.files) {
38571
- const normalized = file.replace(/\\/g, "/");
38572
- for (const pkgPath of packagePaths) {
38573
- if (pkgPath === ".") {
38574
- matched.add(pkgPath);
38575
- continue;
38576
- }
38577
- const normalizedPkg = pkgPath.replace(/\\/g, "/");
38578
- if (normalized.startsWith(`${normalizedPkg}/`) || normalized === normalizedPkg) {
38579
- matched.add(pkgPath);
38580
- }
38581
- }
38582
- }
38583
- return [...matched];
38584
- }
38585
-
38586
39005
  // src/conventional-commit/commit-analyzer.ts
38587
39006
  function analyzeCommits(commits, packagePaths, typeOverrides) {
38588
39007
  const typeMap = {
@@ -38623,147 +39042,6 @@ function resolveBumpType(commit, typeMap) {
38623
39042
  return null;
38624
39043
  return mapped;
38625
39044
  }
38626
- // src/conventional-commit/git-log.ts
38627
- var import_node_child_process2 = require("node:child_process");
38628
- var COMMIT_START_MARKER = "COMMIT_START";
38629
- var COMMIT_FILES_MARKER = "COMMIT_FILES";
38630
- function findLastReleaseRef(cwd, packageName) {
38631
- if (packageName) {
38632
- const scopedTags = execGit(cwd, [
38633
- "tag",
38634
- "--list",
38635
- `${packageName}@[0-9]*.[0-9]*.[0-9]*`,
38636
- "--sort=-v:refname"
38637
- ]);
38638
- if (scopedTags.length > 0)
38639
- return scopedTags[0];
38640
- }
38641
- const vTags = execGit(cwd, [
38642
- "tag",
38643
- "--list",
38644
- "v[0-9]*.[0-9]*.[0-9]*",
38645
- "--sort=-v:refname"
38646
- ]);
38647
- if (vTags.length > 0)
38648
- return vTags[0];
38649
- const versionCommit = execGit(cwd, [
38650
- "log",
38651
- "--format=%H",
38652
- "--grep=^Version Packages$",
38653
- "-1"
38654
- ]);
38655
- if (versionCommit.length > 0)
38656
- return versionCommit[0];
38657
- return;
38658
- }
38659
- function getCommitsSinceRef(cwd, ref) {
38660
- const range = ref ? `${ref}..HEAD` : "HEAD";
38661
- const format3 = `${COMMIT_START_MARKER} %h%n%B%n${COMMIT_FILES_MARKER}`;
38662
- const output = execGitRaw(cwd, [
38663
- "log",
38664
- `--format=${format3}`,
38665
- "--name-only",
38666
- range
38667
- ]);
38668
- if (!output.trim())
38669
- return [];
38670
- const commits = [];
38671
- const lines = output.split(`
38672
- `);
38673
- let i2 = 0;
38674
- while (i2 < lines.length) {
38675
- if (!lines[i2].startsWith(COMMIT_START_MARKER)) {
38676
- i2++;
38677
- continue;
38678
- }
38679
- const hash = lines[i2].slice(COMMIT_START_MARKER.length + 1).trim();
38680
- i2++;
38681
- const messageLines = [];
38682
- while (i2 < lines.length && !lines[i2].startsWith(COMMIT_FILES_MARKER)) {
38683
- if (lines[i2].startsWith(COMMIT_START_MARKER))
38684
- break;
38685
- messageLines.push(lines[i2]);
38686
- i2++;
38687
- }
38688
- if (i2 < lines.length && lines[i2].startsWith(COMMIT_FILES_MARKER)) {
38689
- i2++;
38690
- }
38691
- const files = [];
38692
- while (i2 < lines.length && !lines[i2].startsWith(COMMIT_START_MARKER)) {
38693
- const file = lines[i2].trim();
38694
- if (file)
38695
- files.push(file);
38696
- i2++;
38697
- }
38698
- const message = messageLines.join(`
38699
- `).trim();
38700
- if (hash && message) {
38701
- commits.push({ hash, message, files });
38702
- }
38703
- }
38704
- return commits;
38705
- }
38706
- function execGit(cwd, args) {
38707
- return execGitRaw(cwd, args).split(`
38708
- `).map((l3) => l3.trim()).filter(Boolean);
38709
- }
38710
- function execGitRaw(cwd, args) {
38711
- try {
38712
- return import_node_child_process2.execFileSync("git", args, { cwd, encoding: "utf-8" });
38713
- } catch {
38714
- return "";
38715
- }
38716
- }
38717
- // src/conventional-commit/parser.ts
38718
- var HEADER_REGEX = /^(\w+)(?:\(([^)]+)\))?(!)?\s*:\s*(.+)$/;
38719
- var FOOTER_REGEX = /^([\w-]+|BREAKING CHANGE)\s*:\s*(.+)$/;
38720
- function parseConventionalCommit(hash, message, files = []) {
38721
- const lines = message.split(`
38722
- `);
38723
- const firstLine = lines[0];
38724
- const headerMatch = firstLine.match(HEADER_REGEX);
38725
- if (!headerMatch)
38726
- return null;
38727
- const [, type, scope, bang, description] = headerMatch;
38728
- let body;
38729
- const footers = new Map;
38730
- let breaking = bang === "!";
38731
- if (lines.length > 1) {
38732
- const rest = lines.slice(1);
38733
- let footerStartIndex = rest.length;
38734
- for (let i2 = rest.length - 1;i2 >= 0; i2--) {
38735
- if (rest[i2] === "") {
38736
- footerStartIndex = i2 + 1;
38737
- break;
38738
- }
38739
- }
38740
- const bodyStartIndex = rest.findIndex((line) => line !== "");
38741
- if (bodyStartIndex !== -1 && bodyStartIndex < footerStartIndex) {
38742
- const bodyLines = rest.slice(bodyStartIndex, footerStartIndex - 1);
38743
- const bodyText = bodyLines.join(`
38744
- `).trim();
38745
- if (bodyText)
38746
- body = bodyText;
38747
- }
38748
- let currentFooterKey;
38749
- for (let i2 = footerStartIndex;i2 < rest.length; i2++) {
38750
- const footerMatch = rest[i2].match(FOOTER_REGEX);
38751
- if (footerMatch) {
38752
- const [, key, value] = footerMatch;
38753
- footers.set(key, value);
38754
- currentFooterKey = key;
38755
- if (key === "BREAKING CHANGE" || key === "BREAKING-CHANGE") {
38756
- breaking = true;
38757
- }
38758
- } else if (currentFooterKey && rest[i2].startsWith(" ")) {
38759
- const existing = footers.get(currentFooterKey) ?? "";
38760
- footers.set(currentFooterKey, `${existing}
38761
- ${rest[i2].trimStart()}`);
38762
- }
38763
- }
38764
- }
38765
- return { hash, type, scope, breaking, description, body, footers, files };
38766
- }
38767
39045
  // src/index.ts
38768
39046
  init_catalog2();
38769
39047
  init_js_descriptor();
@@ -38813,7 +39091,7 @@ function inspectPackages(config, cwd) {
38813
39091
  // src/manifest/index.ts
38814
39092
  init_manifest_reader();
38815
39093
  // src/migrate/adapters/changesets.ts
38816
- var import_node_fs19 = require("node:fs");
39094
+ var import_node_fs20 = require("node:fs");
38817
39095
  var import_node_path33 = __toESM(require("node:path"));
38818
39096
  var SKIPPED_DIR_ENTRIES = new Set(["config.json", "README.md", ".gitkeep"]);
38819
39097
  var CHANGELOG_PRESET_MAP = {
@@ -38833,13 +39111,13 @@ var changesetsAdapter = {
38833
39111
  configFilePatterns: [".changeset/config.json"],
38834
39112
  async detect(cwd) {
38835
39113
  const configFile = import_node_path33.default.join(cwd, ".changeset", "config.json");
38836
- if (!import_node_fs19.existsSync(configFile)) {
39114
+ if (!import_node_fs20.existsSync(configFile)) {
38837
39115
  return { found: false, configFiles: [], relatedFiles: [] };
38838
39116
  }
38839
39117
  const changesetDir = import_node_path33.default.dirname(configFile);
38840
39118
  const relatedFiles = [];
38841
39119
  try {
38842
- const entries = import_node_fs19.readdirSync(changesetDir, { encoding: "utf-8" });
39120
+ const entries = import_node_fs20.readdirSync(changesetDir, { encoding: "utf-8" });
38843
39121
  for (const entry of entries) {
38844
39122
  if (SKIPPED_DIR_ENTRIES.has(entry))
38845
39123
  continue;
@@ -38859,7 +39137,7 @@ var changesetsAdapter = {
38859
39137
  if (configFile === undefined) {
38860
39138
  return { source: "changesets", unmappable: [] };
38861
39139
  }
38862
- const raw = import_node_fs19.readFileSync(configFile, "utf-8");
39140
+ const raw = import_node_fs20.readFileSync(configFile, "utf-8");
38863
39141
  const config = JSON.parse(raw);
38864
39142
  const result = {
38865
39143
  source: "changesets",
@@ -38891,9 +39169,9 @@ var changesetsAdapter = {
38891
39169
  result.monorepo.updateInternalDeps = config.updateInternalDependencies;
38892
39170
  }
38893
39171
  const preJsonPath = import_node_path33.default.join(cwd, ".changeset", "pre.json");
38894
- if (import_node_fs19.existsSync(preJsonPath)) {
39172
+ if (import_node_fs20.existsSync(preJsonPath)) {
38895
39173
  try {
38896
- const preRaw = import_node_fs19.readFileSync(preJsonPath, "utf-8");
39174
+ const preRaw = import_node_fs20.readFileSync(preJsonPath, "utf-8");
38897
39175
  const preData = JSON.parse(preRaw);
38898
39176
  if (preData.mode === "pre") {
38899
39177
  result.prerelease = { active: true, tag: preData.tag };
@@ -38928,7 +39206,7 @@ var changesetsAdapter = {
38928
39206
  }
38929
39207
  };
38930
39208
  // src/migrate/adapters/np.ts
38931
- var import_node_fs20 = require("node:fs");
39209
+ var import_node_fs21 = require("node:fs");
38932
39210
  var import_node_path34 = __toESM(require("node:path"));
38933
39211
  var import_node_url2 = require("node:url");
38934
39212
  var STANDALONE_CONFIG_FILES = [
@@ -38958,7 +39236,7 @@ async function readNpConfig(filePath, isPackageJson) {
38958
39236
  return {};
38959
39237
  }
38960
39238
  }
38961
- const raw = import_node_fs20.readFileSync(filePath, "utf-8");
39239
+ const raw = import_node_fs21.readFileSync(filePath, "utf-8");
38962
39240
  const parsed = JSON.parse(raw);
38963
39241
  if (isPackageJson) {
38964
39242
  return parsed.np ?? {};
@@ -39035,14 +39313,14 @@ var npAdapter = {
39035
39313
  const configFiles = [];
39036
39314
  for (const filename of STANDALONE_CONFIG_FILES) {
39037
39315
  const filePath = import_node_path34.default.join(cwd, filename);
39038
- if (import_node_fs20.existsSync(filePath)) {
39316
+ if (import_node_fs21.existsSync(filePath)) {
39039
39317
  configFiles.push(filePath);
39040
39318
  }
39041
39319
  }
39042
39320
  const pkgJsonPath = import_node_path34.default.join(cwd, PACKAGE_JSON);
39043
- if (import_node_fs20.existsSync(pkgJsonPath)) {
39321
+ if (import_node_fs21.existsSync(pkgJsonPath)) {
39044
39322
  try {
39045
- const raw = import_node_fs20.readFileSync(pkgJsonPath, "utf-8");
39323
+ const raw = import_node_fs21.readFileSync(pkgJsonPath, "utf-8");
39046
39324
  const parsed = JSON.parse(raw);
39047
39325
  if ("np" in parsed) {
39048
39326
  configFiles.push(pkgJsonPath);
@@ -39080,7 +39358,7 @@ var npAdapter = {
39080
39358
  }
39081
39359
  };
39082
39360
  // src/migrate/adapters/release-it.ts
39083
- var import_node_fs21 = require("node:fs");
39361
+ var import_node_fs22 = require("node:fs");
39084
39362
  var import_node_path35 = __toESM(require("node:path"));
39085
39363
  var import_node_url3 = require("node:url");
39086
39364
  var import_yaml4 = __toESM(require_dist(), 1);
@@ -39103,7 +39381,7 @@ async function loadConfigFile(filePath) {
39103
39381
  return null;
39104
39382
  }
39105
39383
  }
39106
- const raw = import_node_fs21.readFileSync(filePath, "utf-8");
39384
+ const raw = import_node_fs22.readFileSync(filePath, "utf-8");
39107
39385
  if (filePath.endsWith(".yaml") || filePath.endsWith(".yml")) {
39108
39386
  return import_yaml4.default.parse(raw);
39109
39387
  }
@@ -39223,14 +39501,14 @@ var releaseItAdapter = {
39223
39501
  const configFiles = [];
39224
39502
  for (const filename of STANDALONE_CONFIG_FILES2) {
39225
39503
  const filePath = import_node_path35.default.join(cwd, filename);
39226
- if (import_node_fs21.existsSync(filePath)) {
39504
+ if (import_node_fs22.existsSync(filePath)) {
39227
39505
  configFiles.push(filePath);
39228
39506
  }
39229
39507
  }
39230
39508
  const pkgJsonPath = import_node_path35.default.join(cwd, PACKAGE_JSON2);
39231
- if (import_node_fs21.existsSync(pkgJsonPath)) {
39509
+ if (import_node_fs22.existsSync(pkgJsonPath)) {
39232
39510
  try {
39233
- const raw = import_node_fs21.readFileSync(pkgJsonPath, "utf-8");
39511
+ const raw = import_node_fs22.readFileSync(pkgJsonPath, "utf-8");
39234
39512
  const parsed = JSON.parse(raw);
39235
39513
  if ("release-it" in parsed) {
39236
39514
  configFiles.push(pkgJsonPath);
@@ -39279,7 +39557,7 @@ var releaseItAdapter = {
39279
39557
  }
39280
39558
  };
39281
39559
  // src/migrate/adapters/semantic-release.ts
39282
- var import_node_fs22 = require("node:fs");
39560
+ var import_node_fs23 = require("node:fs");
39283
39561
  var import_node_path36 = __toESM(require("node:path"));
39284
39562
  var import_node_url4 = require("node:url");
39285
39563
  var import_yaml5 = __toESM(require_dist(), 1);
@@ -39367,7 +39645,7 @@ async function loadConfigFile2(filePath) {
39367
39645
  return {};
39368
39646
  }
39369
39647
  }
39370
- const raw = import_node_fs22.readFileSync(filePath, "utf-8");
39648
+ const raw = import_node_fs23.readFileSync(filePath, "utf-8");
39371
39649
  if (filePath.endsWith(".yaml") || filePath.endsWith(".yml")) {
39372
39650
  return import_yaml5.default.parse(raw);
39373
39651
  }
@@ -39486,14 +39764,14 @@ var semanticReleaseAdapter = {
39486
39764
  const configFiles = [];
39487
39765
  for (const filename of STANDALONE_CONFIG_FILES3) {
39488
39766
  const filePath = import_node_path36.default.join(cwd, filename);
39489
- if (import_node_fs22.existsSync(filePath)) {
39767
+ if (import_node_fs23.existsSync(filePath)) {
39490
39768
  configFiles.push(filePath);
39491
39769
  }
39492
39770
  }
39493
39771
  const pkgJsonPath = import_node_path36.default.join(cwd, PACKAGE_JSON3);
39494
- if (import_node_fs22.existsSync(pkgJsonPath)) {
39772
+ if (import_node_fs23.existsSync(pkgJsonPath)) {
39495
39773
  try {
39496
- const raw = import_node_fs22.readFileSync(pkgJsonPath, "utf-8");
39774
+ const raw = import_node_fs23.readFileSync(pkgJsonPath, "utf-8");
39497
39775
  const parsed = JSON.parse(raw);
39498
39776
  if ("release" in parsed) {
39499
39777
  configFiles.push(pkgJsonPath);
@@ -39530,7 +39808,7 @@ var semanticReleaseAdapter = {
39530
39808
  }
39531
39809
  };
39532
39810
  // src/migrate/ci-advisor.ts
39533
- var import_node_fs23 = require("node:fs");
39811
+ var import_node_fs24 = require("node:fs");
39534
39812
  var import_node_path37 = require("node:path");
39535
39813
  var CI_PATTERNS = {
39536
39814
  "semantic-release": [
@@ -39552,16 +39830,16 @@ var CI_PATTERNS = {
39552
39830
  };
39553
39831
  function scanCiWorkflows(cwd, source) {
39554
39832
  const workflowsDir = import_node_path37.join(cwd, ".github", "workflows");
39555
- if (!import_node_fs23.existsSync(workflowsDir))
39833
+ if (!import_node_fs24.existsSync(workflowsDir))
39556
39834
  return [];
39557
39835
  const patterns = CI_PATTERNS[source];
39558
39836
  const advice = [];
39559
- const files = import_node_fs23.readdirSync(workflowsDir, { encoding: "utf-8" });
39837
+ const files = import_node_fs24.readdirSync(workflowsDir, { encoding: "utf-8" });
39560
39838
  for (const filename of files) {
39561
39839
  if (!filename.endsWith(".yml") && !filename.endsWith(".yaml"))
39562
39840
  continue;
39563
39841
  const filePath = import_node_path37.join(workflowsDir, filename);
39564
- const content = import_node_fs23.readFileSync(filePath, "utf-8");
39842
+ const content = import_node_fs24.readFileSync(filePath, "utf-8");
39565
39843
  for (const line of content.split(`
39566
39844
  `)) {
39567
39845
  const trimmed = line.trim();
@@ -39583,15 +39861,15 @@ function scanCiWorkflows(cwd, source) {
39583
39861
  return advice;
39584
39862
  }
39585
39863
  // src/migrate/cleanup.ts
39586
- var import_node_fs24 = require("node:fs");
39864
+ var import_node_fs25 = require("node:fs");
39587
39865
  function removeFiles(targets) {
39588
39866
  const removed = [];
39589
39867
  for (const target of targets) {
39590
39868
  try {
39591
- if (import_node_fs24.statSync(target).isDirectory()) {
39592
- import_node_fs24.rmSync(target, { recursive: true });
39869
+ if (import_node_fs25.statSync(target).isDirectory()) {
39870
+ import_node_fs25.rmSync(target, { recursive: true });
39593
39871
  } else {
39594
- import_node_fs24.unlinkSync(target);
39872
+ import_node_fs25.unlinkSync(target);
39595
39873
  }
39596
39874
  removed.push(target);
39597
39875
  } catch (error4) {
@@ -39802,7 +40080,7 @@ async function detectMigrationSources(cwd, adapters, from) {
39802
40080
  return results.filter((r2) => r2 != null && r2.result.found);
39803
40081
  }
39804
40082
  // src/migrate/pipeline.ts
39805
- var import_node_fs25 = require("node:fs");
40083
+ var import_node_fs26 = require("node:fs");
39806
40084
  var import_node_path38 = require("node:path");
39807
40085
  async function executeMigration(options) {
39808
40086
  const { adapter, detected, cwd, dryRun, clean } = options;
@@ -39813,10 +40091,10 @@ async function executeMigration(options) {
39813
40091
  const ciAdvice = scanCiWorkflows(cwd, adapter.name);
39814
40092
  if (!dryRun) {
39815
40093
  const outFile = import_node_path38.join(cwd, "pubm.config.ts");
39816
- if (import_node_fs25.existsSync(outFile)) {
40094
+ if (import_node_fs26.existsSync(outFile)) {
39817
40095
  throw new Error("pubm.config.ts already exists. Remove or rename it before migrating.");
39818
40096
  }
39819
- import_node_fs25.writeFileSync(outFile, configString, "utf-8");
40097
+ import_node_fs26.writeFileSync(outFile, configString, "utf-8");
39820
40098
  }
39821
40099
  if (!dryRun && adapter.name === "changesets") {
39822
40100
  migrateFromChangesets(cwd);
@@ -40635,6 +40913,7 @@ var requiredMissingInformationTasks = (options) => createListr({
40635
40913
  ])
40636
40914
  });
40637
40915
  // src/tasks/snapshot-runner.ts
40916
+ var import_node_process25 = __toESM(require("node:process"));
40638
40917
  init_error4();
40639
40918
  init_git();
40640
40919
  init_i18n();
@@ -40658,7 +40937,8 @@ function generateSnapshotVersion(options) {
40658
40937
  const now2 = new Date;
40659
40938
  const timestamp = formatTimestamp(now2);
40660
40939
  if (options.template) {
40661
- return options.template.replace(/\{base\}/g, base2).replace(/\{tag\}/g, tag).replace(/\{timestamp\}/g, timestamp).replace(/\{commit\}/g, options.commit ?? "");
40940
+ const suffix = options.template.replace(/\{tag\}/g, tag).replace(/\{timestamp\}/g, timestamp).replace(/\{commit\}/g, options.commit ?? "");
40941
+ return `${base2}-${suffix}`;
40662
40942
  }
40663
40943
  return `${base2}-${tag}-${timestamp}`;
40664
40944
  }
@@ -40719,6 +40999,7 @@ function buildSnapshotVersionPlan(packages, versioning, tag, template) {
40719
40999
  }
40720
41000
  async function runSnapshotPipeline(ctx, options) {
40721
41001
  const { tag, filter, dryRun = false } = options;
41002
+ ctx.runtime.promptEnabled = !m && !!import_node_process25.default.stdin.isTTY;
40722
41003
  const targetPackages = applySnapshotFilter(ctx.config.packages, filter);
40723
41004
  const versioning = ctx.config.versioning ?? "fixed";
40724
41005
  const plan = buildSnapshotVersionPlan(targetPackages, versioning, tag, ctx.config.snapshotTemplate);
@@ -40729,88 +41010,90 @@ async function runSnapshotPipeline(ctx, options) {
40729
41010
  const pipelineListrOptions = m ? createCiListrOptions() : undefined;
40730
41011
  const snapshotVersions = plan.mode === "single" ? new Map([[plan.packagePath, plan.version]]) : plan.packages;
40731
41012
  const originalVersions = new Map(targetPackages.map((p2) => [p2.path, p2.version || "0.0.0"]));
40732
- await createListr([
40733
- {
40734
- skip: options.skipTests,
40735
- title: t("task.test.title"),
40736
- task: async (ctx2, task) => {
40737
- const packageManager = await getPackageManager();
40738
- const command = `${packageManager} run ${ctx2.options.testScript}`;
40739
- task.title = t("task.test.titleWithCommand", { command });
40740
- task.output = `Executing \`${command}\``;
40741
- try {
40742
- await exec3(packageManager, ["run", ctx2.options.testScript], {
40743
- throwOnError: true
40744
- });
40745
- } catch (error4) {
40746
- throw new AbstractError(t("error.test.failed", { script: ctx2.options.testScript }), { cause: error4 });
41013
+ try {
41014
+ await createListr([
41015
+ {
41016
+ skip: options.skipTests,
41017
+ title: t("task.test.title"),
41018
+ task: async (ctx2, task) => {
41019
+ const packageManager = await getPackageManager();
41020
+ const command = `${packageManager} run ${ctx2.options.testScript}`;
41021
+ task.title = t("task.test.titleWithCommand", { command });
41022
+ task.output = `Executing \`${command}\``;
41023
+ try {
41024
+ await exec3(packageManager, ["run", ctx2.options.testScript], {
41025
+ throwOnError: true
41026
+ });
41027
+ } catch (error4) {
41028
+ throw new AbstractError(t("error.test.failed", { script: ctx2.options.testScript }), { cause: error4 });
41029
+ }
40747
41030
  }
40748
- }
40749
- },
40750
- {
40751
- skip: options.skipBuild,
40752
- title: t("task.build.title"),
40753
- task: async (ctx2, task) => {
40754
- const packageManager = await getPackageManager();
40755
- const command = `${packageManager} run ${ctx2.options.buildScript}`;
40756
- task.title = t("task.build.titleWithCommand", { command });
40757
- task.output = `Executing \`${command}\``;
40758
- try {
40759
- await exec3(packageManager, ["run", ctx2.options.buildScript], {
40760
- throwOnError: true
40761
- });
40762
- } catch (error4) {
40763
- throw new AbstractError(t("error.build.failed", { script: ctx2.options.buildScript }), { cause: error4 });
41031
+ },
41032
+ {
41033
+ skip: options.skipBuild,
41034
+ title: t("task.build.title"),
41035
+ task: async (ctx2, task) => {
41036
+ const packageManager = await getPackageManager();
41037
+ const command = `${packageManager} run ${ctx2.options.buildScript}`;
41038
+ task.title = t("task.build.titleWithCommand", { command });
41039
+ task.output = `Executing \`${command}\``;
41040
+ try {
41041
+ await exec3(packageManager, ["run", ctx2.options.buildScript], {
41042
+ throwOnError: true
41043
+ });
41044
+ } catch (error4) {
41045
+ throw new AbstractError(t("error.build.failed", { script: ctx2.options.buildScript }), { cause: error4 });
41046
+ }
40764
41047
  }
40765
- }
40766
- },
40767
- {
40768
- title: t("task.snapshot.title"),
40769
- task: async (ctx2, task) => {
40770
- const versionLabel = plan.mode !== "independent" ? plan.version : `${snapshotVersions.size} packages`;
40771
- task.title = t("task.snapshot.titleWithVersion", {
40772
- version: versionLabel
40773
- });
40774
- await writeVersions(ctx2, snapshotVersions);
40775
- try {
41048
+ },
41049
+ {
41050
+ title: t("task.snapshot.title"),
41051
+ task: async (ctx2, task) => {
41052
+ const versionLabel = plan.mode !== "independent" ? plan.version : `${snapshotVersions.size} packages`;
41053
+ task.title = t("task.snapshot.titleWithVersion", {
41054
+ version: versionLabel
41055
+ });
41056
+ await writeVersions(ctx2, snapshotVersions);
41057
+ await resolveWorkspaceProtocols(ctx2);
40776
41058
  task.output = t("task.snapshot.publishing", { tag });
40777
41059
  const publishTasks = await collectPublishTasks(ctx2);
40778
- await createListr(publishTasks, {
41060
+ return task.newListr(publishTasks, {
40779
41061
  concurrent: true
40780
- }).run(ctx2);
40781
- } finally {
40782
- await writeVersions(ctx2, originalVersions);
41062
+ });
40783
41063
  }
40784
- task.output = t("task.snapshot.published", {
40785
- version: versionLabel
40786
- });
40787
- }
40788
- },
40789
- {
40790
- title: t("task.snapshot.createTag"),
40791
- enabled: !dryRun,
40792
- task: async (ctx2, task) => {
40793
- const git = new Git;
40794
- const headCommit = await git.latestCommit();
40795
- if (plan.mode === "independent") {
40796
- for (const [pkgPath, pkgVersion] of plan.packages) {
40797
- const pkgName = ctx2.config.packages.find((p2) => p2.path === pkgPath)?.name ?? pkgPath;
40798
- const tagName = `${pkgName}@${pkgVersion}`;
41064
+ },
41065
+ {
41066
+ title: t("task.snapshot.createTag"),
41067
+ enabled: !dryRun,
41068
+ task: async (ctx2, task) => {
41069
+ const git = new Git;
41070
+ const headCommit = await git.latestCommit();
41071
+ if (plan.mode === "independent") {
41072
+ for (const [pkgPath, pkgVersion] of plan.packages) {
41073
+ const pkgName = ctx2.config.packages.find((p2) => p2.path === pkgPath)?.name ?? pkgPath;
41074
+ const tagName = `${pkgName}@${pkgVersion}`;
41075
+ task.output = t("task.snapshot.creatingTag", { tag: tagName });
41076
+ await git.createTag(tagName, headCommit);
41077
+ }
41078
+ } else {
41079
+ const version = plan.version;
41080
+ const tagName = `v${version}`;
40799
41081
  task.output = t("task.snapshot.creatingTag", { tag: tagName });
40800
41082
  await git.createTag(tagName, headCommit);
40801
41083
  }
40802
- } else {
40803
- const version = plan.version;
40804
- const tagName = `v${version}`;
40805
- task.output = t("task.snapshot.creatingTag", { tag: tagName });
40806
- await git.createTag(tagName, headCommit);
41084
+ task.output = t("task.snapshot.pushingTag", { tag: "tags" });
41085
+ await git.push("--tags");
41086
+ task.output = t("task.snapshot.tagPushed", { tag: "tags" });
40807
41087
  }
40808
- task.output = t("task.snapshot.pushingTag", { tag: "tags" });
40809
- await git.push("--tags");
40810
- task.output = t("task.snapshot.tagPushed", { tag: "tags" });
40811
41088
  }
41089
+ ], pipelineListrOptions).run(ctx);
41090
+ } finally {
41091
+ if (ctx.runtime.workspaceBackups?.size) {
41092
+ restoreManifests(ctx.runtime.workspaceBackups);
41093
+ ctx.runtime.workspaceBackups = undefined;
40812
41094
  }
40813
- ], pipelineListrOptions).run(ctx);
41095
+ await writeVersions(ctx, originalVersions);
41096
+ }
40814
41097
  const registries = collectRegistries(ctx.config);
40815
41098
  const parts = [];
40816
41099
  for (const registryKey of registries) {
@@ -40822,7 +41105,7 @@ async function runSnapshotPipeline(ctx, options) {
40822
41105
  parts.push(`${ui.chalk.bold(name)} on ${descriptor.label}`);
40823
41106
  }
40824
41107
  }
40825
- const versionDisplay = plan.mode !== "independent" ? ui.chalk.blueBright(plan.version) : "";
41108
+ const versionDisplay = ui.chalk.blueBright(formatVersionSummary(ctx));
40826
41109
  console.log(`
40827
41110
 
40828
41111
  \uD83D\uDCF8 ${t("task.snapshot.success", { parts: parts.join(", "), version: versionDisplay })} \uD83D\uDCF8
@@ -42851,11 +43134,11 @@ function isBun2() {
42851
43134
  init_ui();
42852
43135
 
42853
43136
  // src/validate/entry-points.ts
42854
- var import_node_fs26 = require("node:fs");
43137
+ var import_node_fs27 = require("node:fs");
42855
43138
  var import_node_path40 = __toESM(require("node:path"));
42856
43139
  var SIMPLE_FIELDS = ["main", "module", "types", "typings"];
42857
43140
  function checkPath(filePath, cwd) {
42858
- return import_node_fs26.existsSync(import_node_path40.default.resolve(cwd, filePath));
43141
+ return import_node_fs27.existsSync(import_node_path40.default.resolve(cwd, filePath));
42859
43142
  }
42860
43143
  function validateExports(exports2, cwd, prefix = "exports") {
42861
43144
  const errors = [];