change-versions 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -82,7 +82,7 @@ change-versions release patch --dist-tag=next
82
82
  change-versions release patch --yes # 脚本/CI,不提问
83
83
  ```
84
84
 
85
- 输入错误可重试;输入 q、Ctrl-C 或输入结束可取消当前提问。取消停止后续步骤,已经创建的版本提交或已上传的包会保留。版本提交和实际上传分别确认;回车默认不执行。发现上一批未完成时,引导查看状态或恢复发布,不创建新版本。发布失败后可查看状态或重试,始终固定同一提交和标签;从失败菜单退出仍返回失败状态。
85
+ 输入错误可重试;输入 q、Ctrl-C 或输入结束可取消当前提问。取消停止后续步骤,已经创建的版本提交或已上传的包会保留。版本提交和实际上传分别确认;回车默认不执行。发现上一批未完成时,可查看状态、恢复发布,或选择仅对上一批包强制升版并发布。发布失败后可查看状态或重试,始终固定同一提交和标签;从失败菜单退出仍返回失败状态。
86
86
 
87
87
  非交互环境无参数时显示帮助;缺少升版档位或预发布标识时明确报错。`--yes` 跳过提问,需要提供必要参数,不会自动猜测档位。TTY 回归使用可选的 Python 3 标准库 PTY 中继;CLI 运行无需 Python。
88
88
 
@@ -95,3 +95,14 @@ change-versions release patch --yes # 脚本/CI,不提问
95
95
  实际操作使用仓库锁避免并发发布。升版仅暂存本次允许的文件;失败仅恢复仍属于本次写入的内容,外部文件与意外 hook 提交会保留。额外的 hook 生成文件通过 YAML 的 `commitFiles` 声明。配置仍兼容现有 YAML,无需迁移 JS 配置,也不增加 Bun 运行时依赖。完整规则见 [命令文档](docs/commands.md)。
96
96
 
97
97
  使用项目需要在包含这些命令的新版本发布后升级依赖,再将现有流程包装换成 release;1.2.1 不包含这些入口。构建通过既有 beforePublish 和发布上下文接入,增量构建策略继续由项目决定。
98
+
99
+
100
+ 无变更但需要重发上一批包的新版本时,交互会询问是否强制升版;也可显式执行:
101
+
102
+ ```bash
103
+ change-versions release prerelease --preid=alpha --force
104
+ # 仅升版,发布另行执行:
105
+ change-versions version patch --force
106
+ ```
107
+
108
+ `--force` 只使用最近一次可识别的版本提交里的包名单,不扩大到全部工作区包,也不追加其他变更包或依赖方。按指定档位从当前版本继续升版,再发布新版本;单纯重试未完成的发布仍使用 `release --resume`。`--force` 不能与恢复发布组合。`--yes` 本身不会强制升版。
package/dist/cli.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- var Ae=(e,t,n)=>()=>{if(e)try{t=e(e=0)}catch(i){n=[i]}if(n)throw n[0];return t};function Ie(){let e=(process.env.LC_ALL||process.env.LC_MESSAGES||process.env.LANG||"").split(".")[0];return/^zh/i.test(e)?"zh":"en"}function r(e,t,n=Ie()){let i=Lt[e][n];if(t)for(let[o,s]of Object.entries(t))i=i.replaceAll(`{${o}}`,String(s));return i}var Lt;var R=Ae(()=>{Lt={interactiveCancelled:{zh:"已取消,尚未执行的步骤不会继续。",en:"Cancelled. Remaining steps will not run."},confirmAnswer:{zh:"请输入 y 确认、n 返回,或 q 退出。",en:"Enter y to confirm, n to decline, or q to quit."},chooseReleaseKind:{zh:"选择版本类型",en:"Choose a release type"},releaseKindFormal:{zh:"正式版(发布到 latest)",en:"Formal release (default tag: latest)"},releaseKindPre:{zh:"预发布(例如 alpha、beta)",en:"Prerelease (for example alpha or beta)"},choosePreid:{zh:"预发布标识,回车采用默认值,q 退出:",en:"Prerelease identifier; Enter accepts the default, q quits:"},invalidPreid:{zh:"标识不符合 semver,例如可使用 alpha、beta、rc。请重新输入。",en:"Invalid semver prerelease identifier. Try alpha, beta or rc."},chooseDistTag:{zh:"目标 npm 标签,回车采用默认值,q 退出:",en:"Target npm tag; Enter accepts the default, q quits:"},firstBaseline:{zh:"尚未找到版本基线。请指定一条已存在的提交或 Git 标签作为本轮比较起点;q 退出。",en:"No release baseline found. Choose an existing commit or Git tag as the comparison start; q quits."},chooseBaseline:{zh:"首次版本基线(SHA 或 Git 标签):",en:"First release baseline (SHA or Git tag):"},wizardCandidates:{zh:"本次入选包(含依赖方):",en:"Packages to version (including dependents):"},wizardExecutionPlan:{zh:"执行前确认发布设置",en:"Review release settings before execution"},wizardPlanContext:{zh:"目标 npm 标签: {tag};推送分支: {branch}",en:"Target npm tag: {tag}; push branch: {branch}"},wizardNeedsConfig:{zh:"未找到 change-versions.yml,请先初始化配置。",en:"No change-versions.yml found. Initialize the configuration first."},wizardAction:{zh:"选择操作(输入序号,q 退出)",en:"Choose an action (enter a number, q quits)"},actionNewRelease:{zh:"发布新版本",en:"Release new versions"},actionResume:{zh:"恢复上一次发布(不升版)",en:"Resume publication (no version bump)"},actionStatus:{zh:"查看发布状态",en:"View publication status"},actionInit:{zh:"初始化配置",en:"Initialize configuration"},actionExit:{zh:"退出",en:"Exit"},actionRetry:{zh:"重试当前批次(不升版)",en:"Retry this batch (no version bump)"},actionExitFailed:{zh:"退出,保留失败状态",en:"Exit with failure status"},recoveryAction:{zh:"发布未完成,选择下一步",en:"Publication incomplete. Choose the next action"},pendingAction:{zh:"上一批尚未完成,选择下一步",en:"The previous batch is incomplete. Choose the next action"},optDryRunRelease:{zh:"预览升版或恢复发布计划,不执行修改",en:"Preview versioning or resumed publication without changes"},badDistTag:{zh:"dist-tag 必须是有效的 npm 标签,不能是版本范围或含空白等 URL 保留字符,例如 latest、alpha、next。",en:"dist-tag must be a valid npm tag, not a version range or a value containing whitespace or URL-reserved characters. Try latest, alpha or next."},cmdRelease:{zh:"升版并发布,失败后可恢复发布",en:"Version and publish, with publication recovery"},cmdStatus:{zh:"只读查询发布批次的 registry 与 Git 标签状态",en:"Inspect registry and Git tag state without changing anything"},optReleaseCommit:{zh:"指定待发布版本提交(必须在当前历史中)",en:"Use this version commit (must be an ancestor of HEAD)"},optResume:{zh:"恢复上一批发布,不再次升版",en:"Resume publication without another version bump"},badReleaseCommit:{zh:"无效的版本提交 {commit}:需要当前历史中的提交,正文包含唯一且有效的包名 old => new 版本列表。请核对后重试。",en:"Invalid version commit {commit}: it must be in the current history with unique package old => new version lines. Review the commit before retrying."},repositoryLocked:{zh:`另一个发布操作持有仓库锁: {file}
2
+ var Be=(e,t,n)=>()=>{if(e)try{t=e(e=0)}catch(i){n=[i]}if(n)throw n[0];return t};function Ae(){let e=(process.env.LC_ALL||process.env.LC_MESSAGES||process.env.LANG||"").split(".")[0];return/^zh/i.test(e)?"zh":"en"}function r(e,t,n=Ae()){let i=Lt[e][n];if(t)for(let[o,s]of Object.entries(t))i=i.replaceAll(`{${o}}`,String(s));return i}var Lt;var R=Be(()=>{Lt={interactiveCancelled:{zh:"已取消,尚未执行的步骤不会继续。",en:"Cancelled. Remaining steps will not run."},confirmAnswer:{zh:"请输入 y 确认、n 返回,或 q 退出。",en:"Enter y to confirm, n to decline, or q to quit."},chooseReleaseKind:{zh:"选择版本类型",en:"Choose a release type"},releaseKindFormal:{zh:"正式版(发布到 latest)",en:"Formal release (default tag: latest)"},releaseKindPre:{zh:"预发布(例如 alpha、beta)",en:"Prerelease (for example alpha or beta)"},choosePreid:{zh:"预发布标识,回车采用默认值,q 退出:",en:"Prerelease identifier; Enter accepts the default, q quits:"},invalidPreid:{zh:"标识不符合 semver,例如可使用 alpha、beta、rc。请重新输入。",en:"Invalid semver prerelease identifier. Try alpha, beta or rc."},chooseDistTag:{zh:"目标 npm 标签,回车采用默认值,q 退出:",en:"Target npm tag; Enter accepts the default, q quits:"},firstBaseline:{zh:"尚未找到版本基线。请指定一条已存在的提交或 Git 标签作为本轮比较起点;q 退出。",en:"No release baseline found. Choose an existing commit or Git tag as the comparison start; q quits."},chooseBaseline:{zh:"首次版本基线(SHA 或 Git 标签):",en:"First release baseline (SHA or Git tag):"},wizardCandidates:{zh:"本次入选包(含依赖方):",en:"Packages to version (including dependents):"},wizardExecutionPlan:{zh:"执行前确认发布设置",en:"Review release settings before execution"},wizardPlanContext:{zh:"目标 npm 标签: {tag};推送分支: {branch}",en:"Target npm tag: {tag}; push branch: {branch}"},wizardNeedsConfig:{zh:"未找到 change-versions.yml,请先初始化配置。",en:"No change-versions.yml found. Initialize the configuration first."},wizardAction:{zh:"选择操作(输入序号,q 退出)",en:"Choose an action (enter a number, q quits)"},actionNewRelease:{zh:"发布新版本",en:"Release new versions"},actionResume:{zh:"恢复上一次发布(不升版)",en:"Resume publication (no version bump)"},actionStatus:{zh:"查看发布状态",en:"View publication status"},actionInit:{zh:"初始化配置",en:"Initialize configuration"},actionExit:{zh:"退出",en:"Exit"},actionRetry:{zh:"重试当前批次(不升版)",en:"Retry this batch (no version bump)"},actionExitFailed:{zh:"退出,保留失败状态",en:"Exit with failure status"},recoveryAction:{zh:"发布未完成,选择下一步",en:"Publication incomplete. Choose the next action"},pendingAction:{zh:"上一批尚未完成,选择下一步",en:"The previous batch is incomplete. Choose the next action"},optDryRunRelease:{zh:"预览升版或恢复发布计划,不执行修改",en:"Preview versioning or resumed publication without changes"},badDistTag:{zh:"dist-tag 必须是有效的 npm 标签,不能是版本范围或含空白等 URL 保留字符,例如 latest、alpha、next。",en:"dist-tag must be a valid npm tag, not a version range or a value containing whitespace or URL-reserved characters. Try latest, alpha or next."},cmdRelease:{zh:"升版并发布,失败后可恢复发布",en:"Version and publish, with publication recovery"},cmdStatus:{zh:"只读查询发布批次的 registry 与 Git 标签状态",en:"Inspect registry and Git tag state without changing anything"},optReleaseCommit:{zh:"指定待发布版本提交(必须在当前历史中)",en:"Use this version commit (must be an ancestor of HEAD)"},optResume:{zh:"恢复上一批发布,不再次升版",en:"Resume publication without another version bump"},badReleaseCommit:{zh:"无效的版本提交 {commit}:需要当前历史中的提交,正文包含唯一且有效的包名 old => new 版本列表。请核对后重试。",en:"Invalid version commit {commit}: it must be in the current history with unique package old => new version lines. Review the commit before retrying."},repositoryLocked:{zh:`另一个发布操作持有仓库锁: {file}
3
3
  持有者: {owner}
4
4
  下一步:等待该进程结束;若进程已退出,确认没有其他发布操作后再删除该锁并重试。`,en:`Another release operation holds the repository lock: {file}
5
5
  Owner: {owner}
6
- Wait for it to finish. If the owner has exited, verify no release is running before removing the lock and retrying.`},unsafeCommitFile:{zh:"不安全的提交路径: {file}。请使用仓库内的普通文件路径,不能包含通配符或符号链接。",en:"Unsafe commit path: {file}. Use a regular file inside the repository, without globs or symlinks."},versionHeadChanged:{zh:"升版期间 HEAD 被外部操作或 hook 改变;已保留提交与文件。下一步:检查 git log 和 git status,确认需要保留的改动后再继续。",en:"HEAD changed during versioning. Commits and files were preserved. Review git log and git status before continuing."},versionUnexpectedIndex:{zh:"升版期间暂存区被修改,已停止自动提交。下一步:检查 git diff --cached,处理外部暂存后重试。",en:"The index changed during versioning; automatic commit stopped. Review git diff --cached and resolve external staging before retrying."},versionUnexpectedFiles:{zh:"hook 或外部操作修改了未授权文件: {files}。已保留这些改动。下一步:检查 git status;确需随升版提交的文件请加入 commitFiles。",en:"A hook or external process changed unapproved files: {files}. These changes were preserved. Review git status; add intended version outputs to commitFiles."},versionRecovery:{zh:"升版已中断;仅尝试恢复本次写入且未再次改变的文件。下一步:检查 git status 后重试。",en:"Versioning interrupted; only unchanged files written by this operation were restored. Review git status before retrying."},statusNoBatch:{zh:"尚无可识别的版本批次。下一步:运行 release 创建批次;已有升版提交可用 status --commit=<提交> 指定。",en:"No version batch found. Run release to create one, or use status --commit=<revision> for an existing version commit."},statusHeading:{zh:"【发布状态】只读查询,不执行 hook、上传、提交或标签操作",en:"[Release status] Read-only; no hooks, uploads, commits or tag changes"},statusUpload:{zh:"待上传",en:"Upload pending"},statusRetag:{zh:"待更新 npm 标签",en:"npm tag update pending"},statusReady:{zh:"就绪",en:"ready"},statusMissing:{zh:"未就绪或无法确认",en:"pending or unknown"},statusNotConfigured:{zh:"未配置推送",en:"push not configured"},statusGitTag:{zh:"Git 标签 {tag}:本地 {local};远端 {remote}",en:"Git tag {tag}: local {local}; remote {remote}"},statusRemoteUnknown:{zh:"无法确认远端 Git 标签,请检查 origin 与网络后重试: {detail}",en:"Remote Git tag state is unknown. Check origin and the network, then retry: {detail}"},statusExternalReady:{zh:"registry 与要求的 Git 标签已就绪。",en:"Registry and required Git tags are ready."},statusPending:{zh:"仍有待处理或无法确认的状态,检查以上提示后恢复发布。",en:"Some state is pending or unknown. Review the messages above before resuming publication."},statusHooksUnknown:{zh:"status 无法证明历史 hook 是否成功执行。需要重跑完整发布阶段时使用下方命令;hook 应支持重试。",en:"Status cannot prove that past hooks succeeded. Use the command below to rerun the publication stage; hooks should support retries."},releaseResumeOptions:{zh:"恢复发布不能同时指定升版档位、baseline、branch 或 commit-message。请移除这些升版参数后重试。",en:"Resume cannot be combined with a bump, baseline, branch or commit-message. Remove versioning options and retry."},releasePending:{zh:`上一批版本或所需 Git 标签尚未就绪,已停止新一轮升版。下一步:先恢复发布,无需再次升版:
6
+ Wait for it to finish. If the owner has exited, verify no release is running before removing the lock and retrying.`},unsafeCommitFile:{zh:"不安全的提交路径: {file}。请使用仓库内的普通文件路径,不能包含通配符或符号链接。",en:"Unsafe commit path: {file}. Use a regular file inside the repository, without globs or symlinks."},versionHeadChanged:{zh:"升版期间 HEAD 被外部操作或 hook 改变;已保留提交与文件。下一步:检查 git log 和 git status,确认需要保留的改动后再继续。",en:"HEAD changed during versioning. Commits and files were preserved. Review git log and git status before continuing."},versionUnexpectedIndex:{zh:"升版期间暂存区被修改,已停止自动提交。下一步:检查 git diff --cached,处理外部暂存后重试。",en:"The index changed during versioning; automatic commit stopped. Review git diff --cached and resolve external staging before retrying."},versionUnexpectedFiles:{zh:"hook 或外部操作修改了未授权文件: {files}。已保留这些改动。下一步:检查 git status;确需随升版提交的文件请加入 commitFiles。",en:"A hook or external process changed unapproved files: {files}. These changes were preserved. Review git status; add intended version outputs to commitFiles."},versionRecovery:{zh:"升版已中断;仅尝试恢复本次写入且未再次改变的文件。下一步:检查 git status 后重试。",en:"Versioning interrupted; only unchanged files written by this operation were restored. Review git status before retrying."},statusNoBatch:{zh:"尚无可识别的版本批次。下一步:运行 release 创建批次;已有升版提交可用 status --commit=<提交> 指定。",en:"No version batch found. Run release to create one, or use status --commit=<revision> for an existing version commit."},statusHeading:{zh:"【发布状态】只读查询,不执行 hook、上传、提交或标签操作",en:"[Release status] Read-only; no hooks, uploads, commits or tag changes"},statusUpload:{zh:"待上传",en:"Upload pending"},statusRetag:{zh:"待更新 npm 标签",en:"npm tag update pending"},statusReady:{zh:"就绪",en:"ready"},statusMissing:{zh:"未就绪或无法确认",en:"pending or unknown"},statusNotConfigured:{zh:"未配置推送",en:"push not configured"},statusGitTag:{zh:"Git 标签 {tag}:本地 {local};远端 {remote}",en:"Git tag {tag}: local {local}; remote {remote}"},statusRemoteUnknown:{zh:"无法确认远端 Git 标签,请检查 origin 与网络后重试: {detail}",en:"Remote Git tag state is unknown. Check origin and the network, then retry: {detail}"},statusExternalReady:{zh:"registry 与要求的 Git 标签已就绪。",en:"Registry and required Git tags are ready."},statusPending:{zh:"仍有待处理或无法确认的状态,检查以上提示后恢复发布。",en:"Some state is pending or unknown. Review the messages above before resuming publication."},statusHooksUnknown:{zh:"status 无法证明历史 hook 是否成功执行。需要重跑完整发布阶段时使用下方命令;hook 应支持重试。",en:"Status cannot prove that past hooks succeeded. Use the command below to rerun the publication stage; hooks should support retries."},releaseResumeOptions:{zh:"恢复发布不能同时指定--force、升版档位、baseline、branch 或 commit-message。请移除这些升版参数后重试。",en:"Resume cannot be combined with --force, a bump, baseline, branch or commit-message. Remove versioning options and retry."},releasePending:{zh:`上一批版本或所需 Git 标签尚未就绪,已停止新一轮升版。下一步:先恢复发布,无需再次升版:
7
7
  {command}`,en:`The previous batch is not ready on the registry or required Git tags; a new version bump was stopped. Resume publication first:
8
- {command}`},releaseVersionStage:{zh:"【发布流程 1/2】选择变更并提交版本",en:"[Release 1/2] Select changes and commit versions"},releasePublishStage:{zh:"【发布流程 2/2】发布刚创建的版本提交",en:"[Release 2/2] Publish the version commit just created"},releasePreviewComplete:{zh:"发布流程预览结束:未创建版本提交,未执行发布 hook、上传或标签操作。实际发布计划将在升版成功后查询 registry 生成。确认后去掉 --dry-run 重跑 release。",en:"Release preview complete: no version commit, publish hooks, uploads or tag changes. The actual publication plan will query the registry after versioning succeeds. Remove --dry-run and rerun release after review."},publishPreview:{zh:"【发布预览】仅查询 registry 并展示计划,以下操作尚未执行",en:"[Publish preview] Querying the registry and showing a plan; the operations below have not been executed"},publishPreparing:{zh:"【发布检查】正在确认版本、登录状态和 registry;尚未执行发布操作",en:"[Publish checks] Checking versions, authentication and the registry; publication has not started"},publishPlanSummary:{zh:"计划上传: {uploads},更新 npm 标签: {retags},校验/创建 Git 标签: {tags}",en:"Upload: {uploads}, npm tag updates: {retags}, Git tags to check/create: {tags}"},plannedStep:{zh:"[计划] {step}",en:"[Planned] {step}"},executingStep:{zh:"[执行] {step}",en:"[Running] {step}"},publishPreviewComplete:{zh:"预览结束:未执行 hook、上传、npm 标签修改或 Git 标签/推送操作。",en:"Preview complete. No hooks, uploads, npm tag changes or Git tag/push operations were executed."},publishPreviewNext:{zh:"下一步:确认计划后,去掉 --dry-run,沿用原来的 CLI 运行方式执行下方命令;包装脚本请关闭对应预览选项并使用恢复发布入口。",en:"Next: review the plan, then remove --dry-run and run the command below with your usual CLI runner. For wrapper scripts, disable preview and use their resume-publication entry."},publishResumeInfo:{zh:"将重新查询 registry,跳过已上传的版本,仅补必要的 npm 标签;配置的 hook 和正式版 Git 标签阶段仍会执行。",en:"This will query the registry again, skip uploaded versions and update npm tags only as needed. Configured hooks and the formal-release Git tag stage still run."},publishRetry:{zh:"下一步:修复上述错误后,无需再次升版,重试发布。沿用原来的 CLI 运行方式执行下方命令;包装脚本请使用恢复发布入口,不要重新执行 version。",en:"Next: fix the error, then retry publication without bumping versions. Run the command below with your usual CLI runner; wrapper scripts should resume publication instead of running version again."},publishRetryTitle:{zh:"无需再次升版,重试发布",en:"Retry publication without bumping versions"},publishTagRecovery:{zh:"包已在 registry 就绪,Git 标签阶段未完成;本地或远端标签可能已部分完成,请修复 Git 错误后重试。",en:"Packages are ready on the registry, but the Git tag stage is incomplete. Local or remote tags may be partially complete; fix the Git error before retrying."},publishReady:{zh:"目标 npm 版本与标签已就绪;本批次无需再次升版或上传。",en:"Target npm versions and tags are ready; no further version bump or upload is needed for this batch."},gitTagsLocal:{zh:"Git 标签已在本地就绪;未配置推送分支,因此未推送标签。",en:"Git tags are ready locally. No push branch is configured, so tags were not pushed."},gitTagsPushed:{zh:"Git 标签已创建/校验并推送到 origin。",en:"Git tags were created/checked and pushed to origin."},versionPreview:{zh:"【升版预览】以下为计划版本,尚未修改文件或提交",en:"[Version preview] Planned versions only; no files or commits have been changed"},versionPreviewComplete:{zh:"预览结束:未修改文件、提交或推送。确认后去掉 --dry-run,保留相同档位和参数重跑 version。",en:"Preview complete. No files, commits or pushes were made. Remove --dry-run and rerun version with the same bump and options after reviewing the plan."},versionCommitted:{zh:"版本已提交,包尚未发布。版本提交: {commit}",en:"Versions committed; packages have not been published. Version commit: {commit}"},versionTrailerHint:{zh:"合并或重写 version 提交时,请保留正文中的 Co-authored-by: change-versions <publish@change-versions.com>,供 publish 识别。",en:"When squashing or rewriting a version commit, preserve its Co-authored-by: change-versions <publish@change-versions.com> trailer so publish can find it."},versionPublishNext:{zh:"下一步:沿用原来的 CLI 运行方式执行下方 publish 命令;也可以先加 --dry-run 预览发布计划。",en:"Next: run the publish command below with your usual CLI runner, or add --dry-run to preview the publication plan first."},noVersionChangesNext:{zh:"如果上一轮已经升版但尚未发布,请恢复 publish,不要为了重试再次升版。",en:"If the previous version bump still needs publishing, resume publish instead of bumping again."},publishComplete:{zh:"发布完成,汇总:",en:"Publish complete. Summary:"},publishIncomplete:{zh:"发布未完成,汇总:",en:"Publish incomplete. Summary:"},publishSummaryContext:{zh:"版本提交: {commit},dist-tag: {tag}",en:"Version commit: {commit}, dist-tag: {tag}"},publishFailedStage:{zh:"失败或中断阶段: {stage}",en:"Failed or interrupted stage: {stage}"},summaryPublished:{zh:"已发布",en:"Published"},summaryRetagged:{zh:"标签已更新",en:"Tag updated"},summarySkipped:{zh:"已跳过(版本与标签已就绪)",en:"Skipped (version and tag ready)"},summaryPrivate:{zh:"已跳过(私有包)",en:"Skipped (private)"},summaryFailed:{zh:"失败(registry 状态需重跑确认)",en:"Failed (rerun to check registry state)"},summaryPending:{zh:"未执行",en:"Not executed"},alreadyTagged:{zh:"跳过 {name}@{version}:{tag} 已指向该版本,registry: {registry}",en:"Skipping {name}@{version}: {tag} already points to this version, registry: {registry}"},unexpectedRegistryTags:{zh:"registry {registry} 未返回有效标签信息,无法确认 {name} 的 {tag} 标签",en:"Registry {registry} did not return valid tag metadata for {name} ({tag})"},checkingRegistry:{zh:"检查 {name}@{version},registry: {registry}",en:"Checking {name}@{version}, registry: {registry}"},publishHeadChanged:{zh:"发布 hook 改变了 HEAD。下一步: 检查该提交,让 hook 只更新忽略的构建产物后重跑 publish",en:"A publish hook changed HEAD. Review that commit and keep hooks limited to ignored build output before retrying publish"},wrongBranch:{zh:"当前分支不是 {branch}。下一步: 切换到该分支后重跑 version",en:"Current branch is not {branch}. Next: switch to that branch and rerun version"},releaseVersionMismatch:{zh:"{name} 当前版本 {actual} 与 version 提交中的 {expected} 不一致。识别到版本提交: {commit}。下一步: 检查最新升版提交与 package.json,并确认合并/重写后仍保留 change-versions 的 Co-authored-by 标记,再恢复 publish;不要盲目重新升版",en:"{name} is at {actual}, but the version commit records {expected}. Version commit: {commit}. Check the latest version commit and package.json, including the change-versions Co-authored-by trailer after a squash/rewrite, before resuming publish; do not blindly bump again"},releaseContentsChanged:{zh:"待发布包在 version 提交后又有改动。下一步: 先完成新一轮 version,再发布对应提交",en:"Release packages changed after the version commit. Next: create a new version commit before publishing"},unexpectedRegistryVersion:{zh:"registry {registry} 未返回预期版本 {name}@{version},无法确认是否已发布",en:"The registry did not return the expected version {name}@{version} ({registry})"},dirtyTree:{zh:"工作区不干净。下一步: 提交或还原后,重跑刚才那条命令",en:"Working tree is dirty. Next: commit or restore your changes, then rerun the same command"},gitFailed:{zh:`git 失败。下一步: 在 git 仓库里重跑
8
+ {command}`},releaseVersionStage:{zh:"【发布流程 1/2】选择变更并提交版本",en:"[Release 1/2] Select changes and commit versions"},releasePublishStage:{zh:"【发布流程 2/2】发布刚创建的版本提交",en:"[Release 2/2] Publish the version commit just created"},releasePreviewComplete:{zh:"发布流程预览结束:未创建版本提交,未执行发布 hook、上传或标签操作。实际发布计划将在升版成功后查询 registry 生成。确认后去掉 --dry-run 重跑 release。",en:"Release preview complete: no version commit, publish hooks, uploads or tag changes. The actual publication plan will query the registry after versioning succeeds. Remove --dry-run and rerun release after review."},publishPreview:{zh:"【发布预览】仅查询 registry 并展示计划,以下操作尚未执行",en:"[Publish preview] Querying the registry and showing a plan; the operations below have not been executed"},publishPreparing:{zh:"【发布检查】正在确认版本、登录状态和 registry;尚未执行发布操作",en:"[Publish checks] Checking versions, authentication and the registry; publication has not started"},publishPlanSummary:{zh:"计划上传: {uploads},更新 npm 标签: {retags},校验/创建 Git 标签: {tags}",en:"Upload: {uploads}, npm tag updates: {retags}, Git tags to check/create: {tags}"},plannedStep:{zh:"[计划] {step}",en:"[Planned] {step}"},executingStep:{zh:"[执行] {step}",en:"[Running] {step}"},publishPreviewComplete:{zh:"预览结束:未执行 hook、上传、npm 标签修改或 Git 标签/推送操作。",en:"Preview complete. No hooks, uploads, npm tag changes or Git tag/push operations were executed."},publishPreviewNext:{zh:"下一步:确认计划后,去掉 --dry-run,沿用原来的 CLI 运行方式执行下方命令;包装脚本请关闭对应预览选项并使用恢复发布入口。",en:"Next: review the plan, then remove --dry-run and run the command below with your usual CLI runner. For wrapper scripts, disable preview and use their resume-publication entry."},publishResumeInfo:{zh:"将重新查询 registry,跳过已上传的版本,仅补必要的 npm 标签;配置的 hook 和正式版 Git 标签阶段仍会执行。",en:"This will query the registry again, skip uploaded versions and update npm tags only as needed. Configured hooks and the formal-release Git tag stage still run."},publishRetry:{zh:"下一步:修复上述错误后,无需再次升版,重试发布。沿用原来的 CLI 运行方式执行下方命令;包装脚本请使用恢复发布入口,不要重新执行 version。",en:"Next: fix the error, then retry publication without bumping versions. Run the command below with your usual CLI runner; wrapper scripts should resume publication instead of running version again."},publishRetryTitle:{zh:"无需再次升版,重试发布",en:"Retry publication without bumping versions"},publishTagRecovery:{zh:"包已在 registry 就绪,Git 标签阶段未完成;本地或远端标签可能已部分完成,请修复 Git 错误后重试。",en:"Packages are ready on the registry, but the Git tag stage is incomplete. Local or remote tags may be partially complete; fix the Git error before retrying."},publishReady:{zh:"目标 npm 版本与标签已就绪;本批次无需再次升版或上传。",en:"Target npm versions and tags are ready; no further version bump or upload is needed for this batch."},gitTagsLocal:{zh:"Git 标签已在本地就绪;未配置推送分支,因此未推送标签。",en:"Git tags are ready locally. No push branch is configured, so tags were not pushed."},gitTagsPushed:{zh:"Git 标签已创建/校验并推送到 origin。",en:"Git tags were created/checked and pushed to origin."},versionPreview:{zh:"【升版预览】以下为计划版本,尚未修改文件或提交",en:"[Version preview] Planned versions only; no files or commits have been changed"},versionPreviewComplete:{zh:"预览结束:未修改文件、提交或推送。确认后去掉 --dry-run,保留相同档位和参数重跑 version。",en:"Preview complete. No files, commits or pushes were made. Remove --dry-run and rerun version with the same bump and options after reviewing the plan."},versionCommitted:{zh:"版本已提交,包尚未发布。版本提交: {commit}",en:"Versions committed; packages have not been published. Version commit: {commit}"},versionTrailerHint:{zh:"合并或重写 version 提交时,请保留正文中的 Co-authored-by: change-versions <publish@change-versions.com>,供 publish 识别。",en:"When squashing or rewriting a version commit, preserve its Co-authored-by: change-versions <publish@change-versions.com> trailer so publish can find it."},versionPublishNext:{zh:"下一步:沿用原来的 CLI 运行方式执行下方 publish 命令;也可以先加 --dry-run 预览发布计划。",en:"Next: run the publish command below with your usual CLI runner, or add --dry-run to preview the publication plan first."},noVersionChangesNext:{zh:"如果上一轮已经升版但尚未发布,可恢复 publish;如需重发上一批包的新版本,可选择强制升版或使用 --force。",en:"Resume publish if the previous batch still needs publishing. To release new versions of the previous batch, choose a forced bump or use --force."},optForceVersion:{zh:"仅对上一次版本提交中的包强制升版,不扩展为全量发布",en:"Force new versions of only the packages in the previous version commit"},confirmForceVersion:{zh:"是否仅对上一批包强制升版?",en:"Force new versions of only the previous batch?"},actionForceVersion:{zh:"仅对上一批包强制升版并发布",en:"Force new versions and publish only the previous batch"},forcePreviousBatch:{zh:"强制升版范围:仅版本提交 {commit} 中的包",en:"Forced version scope: only packages from version commit {commit}"},publishComplete:{zh:"发布完成,汇总:",en:"Publish complete. Summary:"},publishIncomplete:{zh:"发布未完成,汇总:",en:"Publish incomplete. Summary:"},publishSummaryContext:{zh:"版本提交: {commit},dist-tag: {tag}",en:"Version commit: {commit}, dist-tag: {tag}"},publishFailedStage:{zh:"失败或中断阶段: {stage}",en:"Failed or interrupted stage: {stage}"},summaryPublished:{zh:"已发布",en:"Published"},summaryRetagged:{zh:"标签已更新",en:"Tag updated"},summarySkipped:{zh:"已跳过(版本与标签已就绪)",en:"Skipped (version and tag ready)"},summaryPrivate:{zh:"已跳过(私有包)",en:"Skipped (private)"},summaryFailed:{zh:"失败(registry 状态需重跑确认)",en:"Failed (rerun to check registry state)"},summaryPending:{zh:"未执行",en:"Not executed"},alreadyTagged:{zh:"跳过 {name}@{version}:{tag} 已指向该版本,registry: {registry}",en:"Skipping {name}@{version}: {tag} already points to this version, registry: {registry}"},unexpectedRegistryTags:{zh:"registry {registry} 未返回有效标签信息,无法确认 {name} 的 {tag} 标签",en:"Registry {registry} did not return valid tag metadata for {name} ({tag})"},checkingRegistry:{zh:"检查 {name}@{version},registry: {registry}",en:"Checking {name}@{version}, registry: {registry}"},publishHeadChanged:{zh:"发布 hook 改变了 HEAD。下一步: 检查该提交,让 hook 只更新忽略的构建产物后重跑 publish",en:"A publish hook changed HEAD. Review that commit and keep hooks limited to ignored build output before retrying publish"},wrongBranch:{zh:"当前分支不是 {branch}。下一步: 切换到该分支后重跑 version",en:"Current branch is not {branch}. Next: switch to that branch and rerun version"},releaseVersionMismatch:{zh:"{name} 当前版本 {actual} 与 version 提交中的 {expected} 不一致。识别到版本提交: {commit}。下一步: 检查最新升版提交与 package.json,并确认合并/重写后仍保留 change-versions 的 Co-authored-by 标记,再恢复 publish;不要盲目重新升版",en:"{name} is at {actual}, but the version commit records {expected}. Version commit: {commit}. Check the latest version commit and package.json, including the change-versions Co-authored-by trailer after a squash/rewrite, before resuming publish; do not blindly bump again"},releaseContentsChanged:{zh:"待发布包在 version 提交后又有改动。下一步: 先完成新一轮 version,再发布对应提交",en:"Release packages changed after the version commit. Next: create a new version commit before publishing"},unexpectedRegistryVersion:{zh:"registry {registry} 未返回预期版本 {name}@{version},无法确认是否已发布",en:"The registry did not return the expected version {name}@{version} ({registry})"},dirtyTree:{zh:"工作区不干净。下一步: 提交或还原后,重跑刚才那条命令",en:"Working tree is dirty. Next: commit or restore your changes, then rerun the same command"},gitFailed:{zh:`git 失败。下一步: 在 git 仓库里重跑
9
9
  {detail}`,en:`git failed. Next: rerun this inside a git repository
10
10
  {detail}`},noPackagesSince:{zh:"自 {rev} 以来没有需要升版的包",en:"No packages to version since {rev}"},changedHeader:{zh:"变更:",en:"Changed:"},dependentsHeader:{zh:"依赖方:",en:"Dependents:"},confirmVersions:{zh:"以上版本是否确认?",en:"Apply these versions?"},cancelledVersion:{zh:"已取消。还没改文件。想继续就再跑同一条命令",en:"Cancelled. No files were changed. Rerun the same command to continue"},branchPushFailed:{zh:`分支推送失败。commit 已在本地。下一步: git push origin {branch};成功后恢复 publish,不要重跑 version
11
11
  {detail}`,en:`Branch push failed. The commit is local. Next: git push origin {branch}, then resume publish. Do not rerun version
@@ -19,14 +19,14 @@ Wait for it to finish. If the owner has exited, verify no release is running bef
19
19
  {detail}`,en:`Cannot read the npm registry:
20
20
  {detail}`},npmFailed:{zh:"npm 失败",en:"npm failed"},npmViewFailed:{zh:"npm view 失败",en:"npm view failed"},hookFailed:{zh:`{name} 失败。下一步: 修好 hook 后重跑 publish。已上传的包保留在 registry,尚未执行 git tag 阶段
21
21
  {detail}`,en:`{name} failed. Next: fix the hook, then rerun publish. Uploaded packages remain on the registry; the git tag stage was not reached
22
- {detail}`},beforePublishDirty:{zh:"beforePublish 改了被跟踪的文件。下一步: hook 只能改 git 忽略的构建产物,弄干净后重跑 publish",en:"beforePublish changed tracked files. Next: the hook may only change gitignored build output. Clean the tree, then rerun publish"},afterPublishDirty:{zh:"afterPublish 改了被跟踪的文件,还没打 git tag。下一步: 让 hook 不改被跟踪的文件,弄干净后重跑 publish",en:"afterPublish changed tracked files, so no git tag was created. Next: keep the hook off tracked files, clean the tree, then rerun publish"},configUnreadable:{zh:"配置读不了: {file}。下一步: 补上 include,删掉不认识的字段",en:"Cannot read config: {file}. Next: add include and remove unknown fields"},packagesDirMissing:{zh:"找不到目录 {dir}",en:"Directory not found: {dir}"},packageJsonIncomplete:{zh:"{folder} 的 package.json 缺少 name 或 version",en:"{folder} package.json is missing name or version"},publicDependsOnPrivate:{zh:"public 包 {name} 不能依赖 private 包 {dep}。下一步: 改依赖后重跑 version",en:"Public package {name} cannot depend on private package {dep}. Next: change the dependency, then rerun version"},missingVersionField:{zh:"{folder} 缺少 version",en:"{folder} is missing version"},badBump:{zh:"档位非法: {bump}。可用 {list}",en:"Invalid bump: {bump}. Use {list}"},preidRequired:{zh:"{kind} 必须带 --preid。预发布用 prepatch 这类档位",en:"{kind} requires --preid. Use a pre* bump for prereleases"},preidForbidden:{zh:"正式版不能带 --preid。预发布用 prepatch 这类档位",en:"A stable bump cannot take --preid. Use a pre* bump for prereleases"},badLine:{zh:"第 {line} 行无法解析",en:"Cannot parse line {line}"},unknownField:{zh:"不认识的字段 {name}",en:"Unknown field {name}"},missingValue:{zh:"{name} 缺少值",en:"{name} is missing a value"},includeRequired:{zh:"include 不能为空。下一步: 补上 include,删掉不认识的字段",en:"include must not be empty. Next: add include and remove unknown fields"},commitMessageNeedsToken:{zh:"commitMessage 需要 %s",en:"commitMessage must contain %s"},patternBang:{zh:"模式不能包含 !: {pattern}",en:"Patterns cannot contain !: {pattern}"},patternClass:{zh:"不支持字符组: {pattern}",en:"Character classes are not supported: {pattern}"},badHook:{zh:"hooks 无法解析: {line}",en:"Cannot parse hooks: {line}"},unknownHook:{zh:"不认识的 hook {name}",en:"Unknown hook {name}"},hookMissingCommand:{zh:"{name} 缺少命令",en:"{name} is missing a command"},badPatternLine:{zh:"路径列表无法解析: {line}",en:"Cannot parse path list: {line}"},badSemver:{zh:"无法解析版本 {version}",en:"Cannot parse version {version}"},dependencyCycle:{zh:"依赖成环: {name}",en:"Dependency cycle: {name}"},bumpRequired:{zh:"非交互环境或 --yes 模式必须指定档位,例如 release patch --yes;交互式发布请运行 release。",en:"A bump is required when not interactive or using --yes. Use release patch --yes, or run release interactively."},chooseIndex:{zh:"请输入序号(q 退出): ",en:"Enter a number (q to quit): "},invalidChoice:{zh:"无效选择: {answer}",en:"Invalid choice: {answer}"},emptyAnswer:{zh:"(空)",en:"(empty)"},yesRequired:{zh:"非交互环境需要 --yes",en:"Pass --yes when not interactive"},commandFailed:{zh:"{command} 失败: {detail}",en:"{command} failed: {detail}"},commandFailedShort:{zh:"{command} 失败",en:"{command} failed"},commandExit:{zh:"{command} 退出 {code}",en:"{command} exited {code}"},cliDescription:{zh:"只给需要发的包升版本,再按那次提交发布",en:"Version only the packages that need a release, then publish that commit"},optRoot:{zh:"仓库根目录",en:"Repository root"},optVersionsFile:{zh:"配置文件",en:"Config file"},optPackages:{zh:"覆盖 packagesDir",en:"Override packagesDir"},cmdChanged:{zh:"列出会升版的包",en:"List packages that would be versioned"},optBaseline:{zh:"这一次的比较起点,SHA 或 tag",en:"Comparison start for this run, SHA or tag"},cmdVersion:{zh:"升版本并提交",en:"Bump versions and commit"},argBump:{zh:"patch、minor、major、prerelease、prepatch、preminor、premajor",en:"patch, minor, major, prerelease, prepatch, preminor, or premajor"},optPreid:{zh:"预发布标识,pre* 必填",en:"Prerelease identifier, required for pre*"},optYes:{zh:"自动执行,不补问缺失参数",en:"Run without prompts; supply required options"},optDryRunVersion:{zh:"只打印旧版本到新版本",en:"Print old and new versions only"},optBranch:{zh:"覆盖配置里的 branch",en:"Override branch from the config"},optCommitMessage:{zh:"覆盖 commitMessage",en:"Override commitMessage"},cmdPublish:{zh:"发布最近一次 version 提交里的包",en:"Publish packages listed in the latest version commit"},optDistTag:{zh:"npm dist-tag",en:"npm dist-tag"},optDryRunPublish:{zh:"查询 registry 并预览计划;不执行 hook、上传、标签修改或推送",en:"Query the registry and preview the plan without hooks, uploads, tag changes or pushes"},cmdInit:{zh:"写入带注释的配置",en:"Write a commented config file"},optYesInit:{zh:"不提问,按探测到的目录写默认配置",en:"Write defaults from the detected directory, without prompts"},configExists:{zh:"已有 {file}。下一步: 直接改这个文件,或删掉后重跑 init",en:"Config already exists: {file}. Next: edit that file, or delete it and rerun init"},initIntro:{zh:"写入 {file}",en:"Write {file}"},initFoundDirs:{zh:"发现包目录: {dirs}",en:"Package directories: {dirs}"},initPackagesDir:{zh:"包目录",en:"Package directory"},initInclude:{zh:"源码路径,逗号分隔",en:"Source paths, comma-separated"},initExclude:{zh:"排除路径,逗号分隔",en:"Excluded paths, comma-separated"},initBranch:{zh:"推送分支,回车跳过",en:"Branch to push, Enter to skip"},initBeforeCommit:{zh:"beforeCommit,回车跳过",en:"beforeCommit, Enter to skip"},initBeforePublish:{zh:"beforePublish,回车跳过",en:"beforePublish, Enter to skip"},initWrote:{zh:"已写入 {file}",en:"Wrote {file}"},initNotePackagesDir:{zh:"包所在目录。这次可用 --packages 覆盖",en:"Directory of packages. Override once with --packages"},initNoteCommitMessage:{zh:"%s 换成档位。有 --preid 时再空一格接上,例如 bump: prerelease alpha。查找看正文末尾的 Co-authored-by: change-versions <publish@change-versions.com>,不改提交作者",en:"%s becomes the bump. With --preid, a space and the id follow, for example bump: prerelease alpha. Lookup uses the Co-authored-by: change-versions <publish@change-versions.com> trailer. The commit author stays unchanged"},initNoteBranch:{zh:"不写就不推送。version 只推这个分支,不推 tag",en:"Omit to skip pushing. version pushes this branch only, not tags"},initNoteBeforeCommit:{zh:"版本和 CHANGELOG 写完之后、git commit 之前。失败仅恢复本次拥有的文件",en:"After versions and CHANGELOG are written, before git commit. Failure restores only files owned by this operation"},initNoteBeforePublish:{zh:"确认之后、npm publish 之前。只能改 git 忽略的构建产物",en:"After confirm, before npm publish. May only change gitignored build output"},initNoteAfterPublish:{zh:"要发的包都已在 registry 上之后。不能把工作区弄脏",en:"After every selected package is on the registry. Must leave the tree clean"},initNoteInclude:{zh:"相对仓库根。* 和 ? 不跨过 /,** 可以。命中目录时,目录里的文件也算",en:"Relative to the repo root. * and ? do not cross /, ** may. A matching directory includes files under it"},initNoteExclude:{zh:"命中这里的文件不触发升版。package.json 另比,去掉 devDependencies 后有差异才算",en:"Files that match here do not trigger a bump. package.json is compared separately, after dropping devDependencies"}}});import Qe from"picomatch";import pe from"semver";import{YAMLParseError as Vt,parse as qt}from"yaml";function Me(e){return tt.has(e)}function we(e,t){if(!Xe.includes(e))throw new l(r("badBump",{bump:e,list:Xe.join(", ")}));let n=e;if(Ut.has(n)&&!t)throw new l(r("preidRequired",{kind:n}));if(tt.has(n)&&t)throw new l(r("preidForbidden"));return n}function be(e){let t=_t(e);for(let d of Object.keys(t))if(!Wt.has(d))throw new l(r("unknownField",{name:d}));let n=t.packagesDir===void 0?"packages":Be(t.packagesDir,"packagesDir"),i=t.commitMessage===void 0?"bump: %s":Be(t.commitMessage,"commitMessage"),o=t.branch===void 0?void 0:Be(t.branch,"branch"),s=t.hooks==null?{}:Kt(t.hooks),a=t.include==null?[]:je(t.include,"include"),c=t.exclude==null?[]:je(t.exclude,"exclude");if(!a.length)throw new l(r("includeRequired"));if(!i.includes("%s"))throw new l(r("commitMessageNeedsToken"));for(let d of[...a,...c]){if(d.includes("!"))throw new l(r("patternBang",{pattern:d}));if(/\[[^\]]+\]/.test(d))throw new l(r("patternClass",{pattern:d}))}let g=t.commitFiles==null?void 0:je(t.commitFiles,"commitFiles");return{packagesDir:n,commitMessage:i,branch:o,hooks:s,include:a,exclude:c,...g?{commitFiles:g}:{}}}function _t(e){try{let t=qt(e);if(t==null)return{};if(!nt(t))throw new l(r("badLine",{line:1}));return t}catch(t){if(t instanceof l)throw t;if(t instanceof Vt)throw new l(r("badLine",{line:t.linePos?.[0]?.line??1}));throw t}}function Kt(e){if(!nt(e))throw new l(r("badHook",{line:"hooks"}));let t={};for(let[n,i]of Object.entries(e)){if(!Jt.has(n))throw new l(r("unknownHook",{name:n}));if(typeof i!=="string"||!i)throw new l(r("hookMissingCommand",{name:n}));t[n]=i}return t}function je(e,t){if(!Array.isArray(e))throw new l(r("badPatternLine",{line:t}));return e.map((n)=>{if(typeof n!=="string"||!n)throw new l(r("badPatternLine",{line:t}));return n})}function Be(e,t){if(typeof e!=="string"||!e)throw new l(r("missingValue",{name:t}));return e}function nt(e){return Boolean(e)&&typeof e==="object"&&!Array.isArray(e)}function Ze(e,t){let n={dot:!0};if(Qe(t,n)(e))return!0;if(t.endsWith("/**"))return!1;return Qe(`${t}/**`,n)(e)}function He(e,t,n){return t.some((i)=>Ze(e,i))&&!n.some((i)=>Ze(e,i))}function it(e,t,n){let i=new Set(n),o=`${t}/`,s=new Map;for(let a of e.split(`
23
- `)){if(!a.startsWith(o))continue;let c=a.slice(o.length),g=c.split("/")[0];if(!g||!c.includes("/")||!i.has(g))continue;let d=s.get(g)??[];d.push(a),s.set(g,d)}return s}function rt(e,t,n,i,o,s){let a=[],c=[];for(let g of e){let d=t.get(g);if(!d?.length){c.push(g);continue}let h=`${s}/${g}/package.json`;if(d.some((f)=>f!==h&&He(f,n,i))||d.includes(h)&&!o(g))a.push(g);else c.push(g)}return{changed:a,ignored:c}}function st(e,t){return JSON.stringify(fe(et(e)))===JSON.stringify(fe(et(t)))}function et(e){if(!e||typeof e!=="object"||Array.isArray(e))return e;let t={...e};return delete t.devDependencies,t}function fe(e){if(Array.isArray(e))return e.map(fe);if(e&&typeof e==="object"){let t=e;return Object.fromEntries(Object.keys(t).sort().map((n)=>[n,fe(t[n])]))}return e}function ot(e,t,n){let i=n?pe.inc(e,t,n):pe.inc(e,t);if(!i)throw new l(r("badSemver",{version:e}));return i}function at(e,t,n){let i=new Set(t),o=new Map(e.map((a)=>[a,[]]));for(let a of e)for(let c of n(a))o.get(c)?.push(a);let s=[...t];while(s.length){let a=s.pop();if(!a)break;for(let c of o.get(a)??[]){if(i.has(c))continue;i.add(c),s.push(c)}}return e.filter((a)=>i.has(a))}function ct(e,t,n){let i=e.replace("%s",t);return n?`${i} ${n}`:i}function ve(e){return e.length>0&&e.every((t)=>Boolean(pe.valid(t.to))&&pe.prerelease(t.to)==null)}function lt(e){return/^v\d/.test(e)}function gt(e){return/^v\d+\.\d+\.\d+$/.test(e)}function ke(e){let t=[];for(let n of e.split(`
24
- `)){let i=/^(\S+) (\S+) => (\S+)$/.exec(n.trim());if(i)t.push({name:i[1],from:i[2],to:i[3]})}return t}function mt(e){let t=new Map(e.map((s)=>[s.folder,s])),n=new Set,i=[],o=(s,a)=>{if(n.has(s.folder))return;if(a.has(s.folder))throw new l(r("dependencyCycle",{name:s.name}));a.add(s.folder);for(let c of s.deps){let g=t.get(c);if(g)o(g,a)}a.delete(s.folder),n.add(s.folder),i.push(s)};for(let s of e)o(s,new Set);return i}function ae(e){return/ENEEDAUTH|E401|E403|need auth|not logged in|401 Unauthorized|403 Forbidden/i.test(e)}function Oe(e){try{return JSON.parse(e)?.error?.code==="E404"}catch{return!1}}var l,Xe,tt,Ut,Wt,Jt,Yt="publish@change-versions.com",Qt,ye;var D=Ae(()=>{R();l=class l extends Error{auth;constructor(e,t=!1){super(e);this.name="Fail",this.auth=t}};Xe=["patch","minor","major","prerelease","prepatch","preminor","premajor"],tt=new Set(["patch","minor","major"]),Ut=new Set(["prerelease","prepatch","preminor","premajor"]);Wt=new Set(["packagesDir","commitMessage","branch","hooks","include","exclude","commitFiles"]),Jt=new Set(["beforeCommit","beforePublish","afterPublish"]);Qt=`change-versions <${Yt}>`,ye=`Co-authored-by: ${Qt}`});import{CommitParser as Pn}from"conventional-commits-parser";import{writeChangelogString as Sn}from"conventional-changelog-writer";function It(e){return e.find((t)=>ve(ke(t.body)))?.hash}function jt(e,t,n,i,o,s){let a=`${n}/${t}/package.json`,c=`${n}/${t}/`,g=[];for(let d of e)if(d.files.some((y)=>y!==a&&y.startsWith(c)&&He(y,i,o))||d.files.includes(a)&&s.has(d.hash))g.push({hash:d.hash,body:d.body});return g}async function Bt(e){let t=new Date().toISOString().slice(0,10),n=[`## ${e.version} (${t})`];if(e.previousTag){let s=`../../compare/${encodeURIComponent(e.previousTag)}...${encodeURIComponent(e.currentTag)}`;n.push(`[${e.previousTag}...${e.currentTag}](${s})`)}let i=new Pn({noteKeywords:["BREAKING CHANGE","BREAKING-CHANGE"]}),o=[];for(let s of e.messages){let a;try{a=i.parse(s.body)}catch{continue}o.push({...a,hash:s.hash.slice(0,7),notes:a.notes??[],subject:a.subject})}if(o.length){let a=(await Sn(o,{version:e.version,date:t},{groupBy:"type",mainTemplate:zn,transform(c){let d=(c.notes??[]).some((y)=>/breaking/i.test(y.title)),h=c.type??"";if(Cn.has(h)&&!d)return null;if(!Et[h]&&!d)return null;return{type:Et[h]??null}}})).trim();if(a)n.push("",a);else if(e.dependencies.length)n.push("",At(e.dependencies))}else if(e.dependencies.length)n.push("",At(e.dependencies).trimEnd());return`${n.join(`
22
+ {detail}`},beforePublishDirty:{zh:"beforePublish 改了被跟踪的文件。下一步: hook 只能改 git 忽略的构建产物,弄干净后重跑 publish",en:"beforePublish changed tracked files. Next: the hook may only change gitignored build output. Clean the tree, then rerun publish"},afterPublishDirty:{zh:"afterPublish 改了被跟踪的文件,还没打 git tag。下一步: 让 hook 不改被跟踪的文件,弄干净后重跑 publish",en:"afterPublish changed tracked files, so no git tag was created. Next: keep the hook off tracked files, clean the tree, then rerun publish"},configUnreadable:{zh:"配置读不了: {file}。下一步: 补上 include,删掉不认识的字段",en:"Cannot read config: {file}. Next: add include and remove unknown fields"},packagesDirMissing:{zh:"找不到目录 {dir}",en:"Directory not found: {dir}"},packageJsonIncomplete:{zh:"{folder} 的 package.json 缺少 name 或 version",en:"{folder} package.json is missing name or version"},publicDependsOnPrivate:{zh:"public 包 {name} 不能依赖 private 包 {dep}。下一步: 改依赖后重跑 version",en:"Public package {name} cannot depend on private package {dep}. Next: change the dependency, then rerun version"},missingVersionField:{zh:"{folder} 缺少 version",en:"{folder} is missing version"},badBump:{zh:"档位非法: {bump}。可用 {list}",en:"Invalid bump: {bump}. Use {list}"},preidRequired:{zh:"{kind} 必须带 --preid。预发布用 prepatch 这类档位",en:"{kind} requires --preid. Use a pre* bump for prereleases"},preidForbidden:{zh:"正式版不能带 --preid。预发布用 prepatch 这类档位",en:"A stable bump cannot take --preid. Use a pre* bump for prereleases"},badLine:{zh:"第 {line} 行无法解析",en:"Cannot parse line {line}"},unknownField:{zh:"不认识的字段 {name}",en:"Unknown field {name}"},missingValue:{zh:"{name} 缺少值",en:"{name} is missing a value"},includeRequired:{zh:"include 不能为空。下一步: 补上 include,删掉不认识的字段",en:"include must not be empty. Next: add include and remove unknown fields"},commitMessageNeedsToken:{zh:"commitMessage 需要 %s",en:"commitMessage must contain %s"},patternBang:{zh:"模式不能包含 !: {pattern}",en:"Patterns cannot contain !: {pattern}"},patternClass:{zh:"不支持字符组: {pattern}",en:"Character classes are not supported: {pattern}"},badHook:{zh:"hooks 无法解析: {line}",en:"Cannot parse hooks: {line}"},unknownHook:{zh:"不认识的 hook {name}",en:"Unknown hook {name}"},hookMissingCommand:{zh:"{name} 缺少命令",en:"{name} is missing a command"},badPatternLine:{zh:"路径列表无法解析: {line}",en:"Cannot parse path list: {line}"},badSemver:{zh:"无法解析版本 {version}",en:"Cannot parse version {version}"},dependencyCycle:{zh:"依赖成环: {name}",en:"Dependency cycle: {name}"},bumpRequired:{zh:"非交互环境或 --yes 模式必须指定档位,例如 release patch --yes;交互式发布请运行 release。",en:"A bump is required when not interactive or using --yes. Use release patch --yes, or run release interactively."},chooseIndex:{zh:"请输入序号(q 退出): ",en:"Enter a number (q to quit): "},invalidChoice:{zh:"无效选择: {answer}",en:"Invalid choice: {answer}"},emptyAnswer:{zh:"(空)",en:"(empty)"},yesRequired:{zh:"非交互环境需要 --yes",en:"Pass --yes when not interactive"},commandFailed:{zh:"{command} 失败: {detail}",en:"{command} failed: {detail}"},commandFailedShort:{zh:"{command} 失败",en:"{command} failed"},commandExit:{zh:"{command} 退出 {code}",en:"{command} exited {code}"},cliDescription:{zh:"只给需要发的包升版本,再按那次提交发布",en:"Version only the packages that need a release, then publish that commit"},optRoot:{zh:"仓库根目录",en:"Repository root"},optVersionsFile:{zh:"配置文件",en:"Config file"},optPackages:{zh:"覆盖 packagesDir",en:"Override packagesDir"},cmdChanged:{zh:"列出会升版的包",en:"List packages that would be versioned"},optBaseline:{zh:"这一次的比较起点,SHA 或 tag",en:"Comparison start for this run, SHA or tag"},cmdVersion:{zh:"升版本并提交",en:"Bump versions and commit"},argBump:{zh:"patch、minor、major、prerelease、prepatch、preminor、premajor",en:"patch, minor, major, prerelease, prepatch, preminor, or premajor"},optPreid:{zh:"预发布标识,pre* 必填",en:"Prerelease identifier, required for pre*"},optYes:{zh:"自动执行,不补问缺失参数",en:"Run without prompts; supply required options"},optDryRunVersion:{zh:"只打印旧版本到新版本",en:"Print old and new versions only"},optBranch:{zh:"覆盖配置里的 branch",en:"Override branch from the config"},optCommitMessage:{zh:"覆盖 commitMessage",en:"Override commitMessage"},cmdPublish:{zh:"发布最近一次 version 提交里的包",en:"Publish packages listed in the latest version commit"},optDistTag:{zh:"npm dist-tag",en:"npm dist-tag"},optDryRunPublish:{zh:"查询 registry 并预览计划;不执行 hook、上传、标签修改或推送",en:"Query the registry and preview the plan without hooks, uploads, tag changes or pushes"},cmdInit:{zh:"写入带注释的配置",en:"Write a commented config file"},optYesInit:{zh:"不提问,按探测到的目录写默认配置",en:"Write defaults from the detected directory, without prompts"},configExists:{zh:"已有 {file}。下一步: 直接改这个文件,或删掉后重跑 init",en:"Config already exists: {file}. Next: edit that file, or delete it and rerun init"},initIntro:{zh:"写入 {file}",en:"Write {file}"},initFoundDirs:{zh:"发现包目录: {dirs}",en:"Package directories: {dirs}"},initPackagesDir:{zh:"包目录",en:"Package directory"},initInclude:{zh:"源码路径,逗号分隔",en:"Source paths, comma-separated"},initExclude:{zh:"排除路径,逗号分隔",en:"Excluded paths, comma-separated"},initBranch:{zh:"推送分支,回车跳过",en:"Branch to push, Enter to skip"},initBeforeCommit:{zh:"beforeCommit,回车跳过",en:"beforeCommit, Enter to skip"},initBeforePublish:{zh:"beforePublish,回车跳过",en:"beforePublish, Enter to skip"},initWrote:{zh:"已写入 {file}",en:"Wrote {file}"},initNotePackagesDir:{zh:"包所在目录。这次可用 --packages 覆盖",en:"Directory of packages. Override once with --packages"},initNoteCommitMessage:{zh:"%s 换成档位。有 --preid 时再空一格接上,例如 bump: prerelease alpha。查找看正文末尾的 Co-authored-by: change-versions <publish@change-versions.com>,不改提交作者",en:"%s becomes the bump. With --preid, a space and the id follow, for example bump: prerelease alpha. Lookup uses the Co-authored-by: change-versions <publish@change-versions.com> trailer. The commit author stays unchanged"},initNoteBranch:{zh:"不写就不推送。version 只推这个分支,不推 tag",en:"Omit to skip pushing. version pushes this branch only, not tags"},initNoteBeforeCommit:{zh:"版本和 CHANGELOG 写完之后、git commit 之前。失败仅恢复本次拥有的文件",en:"After versions and CHANGELOG are written, before git commit. Failure restores only files owned by this operation"},initNoteBeforePublish:{zh:"确认之后、npm publish 之前。只能改 git 忽略的构建产物",en:"After confirm, before npm publish. May only change gitignored build output"},initNoteAfterPublish:{zh:"要发的包都已在 registry 上之后。不能把工作区弄脏",en:"After every selected package is on the registry. Must leave the tree clean"},initNoteInclude:{zh:"相对仓库根。* 和 ? 不跨过 /,** 可以。命中目录时,目录里的文件也算",en:"Relative to the repo root. * and ? do not cross /, ** may. A matching directory includes files under it"},initNoteExclude:{zh:"命中这里的文件不触发升版。package.json 另比,去掉 devDependencies 后有差异才算",en:"Files that match here do not trigger a bump. package.json is compared separately, after dropping devDependencies"}}});import Qe from"picomatch";import fe from"semver";import{YAMLParseError as qt,parse as Ut}from"yaml";function Me(e){return tt.has(e)}function be(e,t){if(!Xe.includes(e))throw new l(r("badBump",{bump:e,list:Xe.join(", ")}));let n=e;if(Wt.has(n)&&!t)throw new l(r("preidRequired",{kind:n}));if(tt.has(n)&&t)throw new l(r("preidForbidden"));return n}function ye(e){let t=Kt(e);for(let d of Object.keys(t))if(!Jt.has(d))throw new l(r("unknownField",{name:d}));let n=t.packagesDir===void 0?"packages":je(t.packagesDir,"packagesDir"),i=t.commitMessage===void 0?"bump: %s":je(t.commitMessage,"commitMessage"),o=t.branch===void 0?void 0:je(t.branch,"branch"),s=t.hooks==null?{}:Yt(t.hooks),a=t.include==null?[]:Ie(t.include,"include"),c=t.exclude==null?[]:Ie(t.exclude,"exclude");if(!a.length)throw new l(r("includeRequired"));if(!i.includes("%s"))throw new l(r("commitMessageNeedsToken"));for(let d of[...a,...c]){if(d.includes("!"))throw new l(r("patternBang",{pattern:d}));if(/\[[^\]]+\]/.test(d))throw new l(r("patternClass",{pattern:d}))}let g=t.commitFiles==null?void 0:Ie(t.commitFiles,"commitFiles");return{packagesDir:n,commitMessage:i,branch:o,hooks:s,include:a,exclude:c,...g?{commitFiles:g}:{}}}function Kt(e){try{let t=Ut(e);if(t==null)return{};if(!nt(t))throw new l(r("badLine",{line:1}));return t}catch(t){if(t instanceof l)throw t;if(t instanceof qt)throw new l(r("badLine",{line:t.linePos?.[0]?.line??1}));throw t}}function Yt(e){if(!nt(e))throw new l(r("badHook",{line:"hooks"}));let t={};for(let[n,i]of Object.entries(e)){if(!_t.has(n))throw new l(r("unknownHook",{name:n}));if(typeof i!=="string"||!i)throw new l(r("hookMissingCommand",{name:n}));t[n]=i}return t}function Ie(e,t){if(!Array.isArray(e))throw new l(r("badPatternLine",{line:t}));return e.map((n)=>{if(typeof n!=="string"||!n)throw new l(r("badPatternLine",{line:t}));return n})}function je(e,t){if(typeof e!=="string"||!e)throw new l(r("missingValue",{name:t}));return e}function nt(e){return Boolean(e)&&typeof e==="object"&&!Array.isArray(e)}function Ze(e,t){let n={dot:!0};if(Qe(t,n)(e))return!0;if(t.endsWith("/**"))return!1;return Qe(`${t}/**`,n)(e)}function He(e,t,n){return t.some((i)=>Ze(e,i))&&!n.some((i)=>Ze(e,i))}function it(e,t,n){let i=new Set(n),o=`${t}/`,s=new Map;for(let a of e.split(`
23
+ `)){if(!a.startsWith(o))continue;let c=a.slice(o.length),g=c.split("/")[0];if(!g||!c.includes("/")||!i.has(g))continue;let d=s.get(g)??[];d.push(a),s.set(g,d)}return s}function rt(e,t,n,i,o,s){let a=[],c=[];for(let g of e){let d=t.get(g);if(!d?.length){c.push(g);continue}let h=`${s}/${g}/package.json`;if(d.some((f)=>f!==h&&He(f,n,i))||d.includes(h)&&!o(g))a.push(g);else c.push(g)}return{changed:a,ignored:c}}function st(e,t){return JSON.stringify(we(et(e)))===JSON.stringify(we(et(t)))}function et(e){if(!e||typeof e!=="object"||Array.isArray(e))return e;let t={...e};return delete t.devDependencies,t}function we(e){if(Array.isArray(e))return e.map(we);if(e&&typeof e==="object"){let t=e;return Object.fromEntries(Object.keys(t).sort().map((n)=>[n,we(t[n])]))}return e}function ot(e,t,n){let i=n?fe.inc(e,t,n):fe.inc(e,t);if(!i)throw new l(r("badSemver",{version:e}));return i}function at(e,t,n){let i=new Set(t),o=new Map(e.map((a)=>[a,[]]));for(let a of e)for(let c of n(a))o.get(c)?.push(a);let s=[...t];while(s.length){let a=s.pop();if(!a)break;for(let c of o.get(a)??[]){if(i.has(c))continue;i.add(c),s.push(c)}}return e.filter((a)=>i.has(a))}function ct(e,t,n){let i=e.replace("%s",t);return n?`${i} ${n}`:i}function ke(e){return e.length>0&&e.every((t)=>Boolean(fe.valid(t.to))&&fe.prerelease(t.to)==null)}function lt(e){return/^v\d/.test(e)}function gt(e){return/^v\d+\.\d+\.\d+$/.test(e)}function xe(e){let t=[];for(let n of e.split(`
24
+ `)){let i=/^(\S+) (\S+) => (\S+)$/.exec(n.trim());if(i)t.push({name:i[1],from:i[2],to:i[3]})}return t}function mt(e){let t=new Map(e.map((s)=>[s.folder,s])),n=new Set,i=[],o=(s,a)=>{if(n.has(s.folder))return;if(a.has(s.folder))throw new l(r("dependencyCycle",{name:s.name}));a.add(s.folder);for(let c of s.deps){let g=t.get(c);if(g)o(g,a)}a.delete(s.folder),n.add(s.folder),i.push(s)};for(let s of e)o(s,new Set);return i}function ae(e){return/ENEEDAUTH|E401|E403|need auth|not logged in|401 Unauthorized|403 Forbidden/i.test(e)}function Oe(e){try{return JSON.parse(e)?.error?.code==="E404"}catch{return!1}}var l,Xe,tt,Wt,Jt,_t,Qt="publish@change-versions.com",Xt,ve;var F=Be(()=>{R();l=class l extends Error{auth;constructor(e,t=!1){super(e);this.name="Fail",this.auth=t}};Xe=["patch","minor","major","prerelease","prepatch","preminor","premajor"],tt=new Set(["patch","minor","major"]),Wt=new Set(["prerelease","prepatch","preminor","premajor"]);Jt=new Set(["packagesDir","commitMessage","branch","hooks","include","exclude","commitFiles"]),_t=new Set(["beforeCommit","beforePublish","afterPublish"]);Xt=`change-versions <${Qt}>`,ve=`Co-authored-by: ${Xt}`});import{CommitParser as Cn}from"conventional-commits-parser";import{writeChangelogString as Sn}from"conventional-changelog-writer";function At(e){return e.find((t)=>ke(xe(t.body)))?.hash}function It(e,t,n,i,o,s){let a=`${n}/${t}/package.json`,c=`${n}/${t}/`,g=[];for(let d of e)if(d.files.some((y)=>y!==a&&y.startsWith(c)&&He(y,i,o))||d.files.includes(a)&&s.has(d.hash))g.push({hash:d.hash,body:d.body});return g}async function jt(e){let t=new Date().toISOString().slice(0,10),n=[`## ${e.version} (${t})`];if(e.previousTag){let s=`../../compare/${encodeURIComponent(e.previousTag)}...${encodeURIComponent(e.currentTag)}`;n.push(`[${e.previousTag}...${e.currentTag}](${s})`)}let i=new Cn({noteKeywords:["BREAKING CHANGE","BREAKING-CHANGE"]}),o=[];for(let s of e.messages){let a;try{a=i.parse(s.body)}catch{continue}o.push({...a,hash:s.hash.slice(0,7),notes:a.notes??[],subject:a.subject})}if(o.length){let a=(await Sn(o,{version:e.version,date:t},{groupBy:"type",mainTemplate:Rn,transform(c){let d=(c.notes??[]).some((y)=>/breaking/i.test(y.title)),h=c.type??"";if(zn.has(h)&&!d)return null;if(!Et[h]&&!d)return null;return{type:Et[h]??null}}})).trim();if(a)n.push("",a);else if(e.dependencies.length)n.push("",Bt(e.dependencies))}else if(e.dependencies.length)n.push("",Bt(e.dependencies).trimEnd());return`${n.join(`
25
25
  `).trim()}
26
- `}function At(e){return`### Dependencies
26
+ `}function Bt(e){return`### Dependencies
27
27
 
28
28
  * update dependencies ${e.map((t)=>`${t.name}@${t.version}`).join(", ")}
29
- `}var Cn,Et,zn=`{{#each commitGroups}}
29
+ `}var zn,Et,Rn=`{{#each commitGroups}}
30
30
  {{#if title}}
31
31
  ### {{title}}
32
32
 
@@ -44,21 +44,21 @@ Wait for it to finish. If the owner has exited, verify no release is running bef
44
44
  {{/each}}
45
45
 
46
46
  {{/each}}
47
- `;var Mt=Ae(()=>{D();Cn=new Set(["docs","style","chore","refactor","test","build","ci"]),Et={feat:"Features",feature:"Features",fix:"Bug Fixes",perf:"Performance Improvements",revert:"Reverts"}});import{Command as Bn}from"commander";import{readFileSync as Mn}from"node:fs";import en from"node:path";import{styleText as Gt}from"node:util";function H(e,t,n){return Gt(e,t,{stream:n})}function S(e){return H(["bold","cyan"],e,process.stdout)}function O(e){return H("bold",e,process.stdout)}function Q(e){return H("green",e,process.stdout)}function P(e){return H("dim",e,process.stdout)}function A(e){return H("cyan",e,process.stdout)}function Ye(e,t,n){return`${O(e)} ${P(t)} ${P("=>")} ${Q(n)}`}function j(e){let[t,...n]=e.split(`
48
- `),i=H("red",t,process.stderr);if(!n.length)return i;return[i,...n.map((o)=>H("yellow",o,process.stderr))].join(`
49
- `)}function W(e){return H("green",e,process.stdout)}function k(e){return H("yellow",e,process.stdout)}function he(e){return H("red",e,process.stdout)}R();R();D();import{spawn as dt}from"node:child_process";function x(e,t,n){return new Promise((i)=>{let o=dt(e,t,{cwd:n,stdio:["ignore","pipe","pipe"]}),s="",a="";o.stdout.on("data",(c)=>{s+=c}),o.stderr.on("data",(c)=>{a+=c}),o.on("error",(c)=>i({code:1,stdout:s,stderr:`${a}${c.message}`})),o.on("close",(c)=>i({code:c??1,stdout:s,stderr:a}))})}async function w(e,t,n){let i=await x(e,t,n);if(i.code!==0){let o=(i.stderr||i.stdout).trim();throw new l(o?r("commandFailed",{command:e,detail:o}):r("commandFailedShort",{command:e}))}return i.stdout}function xe(e,t,n,i){return new Promise((o,s)=>{let a=dt(e,t,{cwd:n,stdio:"inherit",env:{...process.env,...i}});a.on("error",s),a.on("exit",(c)=>{if(c===0)o();else s(new l(r("commandExit",{command:e,code:c??1})))})})}R();D();import ne from"node:fs";import Pe from"node:path";R();D();function ut(e){let t=e.packages.map((g)=>g.folder),n=new Map(e.packages.map((g)=>[g.folder,g])),i=new Map(e.packages.map((g)=>[g.name,g])),o=new Map(e.packages.map((g)=>[g.name,g.folder])),{changed:s}=rt(t,e.filesByFolder,e.include,e.exclude,(g)=>e.devOnly.has(g),e.packagesDir),a=at(t,s,(g)=>Xt(n.get(g),o));for(let g of a){let d=n.get(g);if(!d||d.private)continue;for(let h of Object.keys(d.dependencies??{}))if(i.get(h)?.private)throw new l(r("publicDependsOnPrivate",{name:d.name,dep:h}))}let c=new Set(s);return{changed:s,dependents:a.filter((g)=>!c.has(g))}}function Xt(e,t){if(!e)return[];return[...Object.keys(e.dependencies??{}),...Object.keys(e.devDependencies??{})].flatMap((i)=>{let o=t.get(i);return o?[o]:[]})}function ie(e,t){let n=Pe.resolve(e,t);if(!ne.existsSync(n))throw new l(r("configUnreadable",{file:t}));return be(ne.readFileSync(n,"utf8"))}function X(e,t){let n=Pe.join(e,t);if(!ne.existsSync(n))throw new l(r("packagesDirMissing",{dir:t}));return ne.readdirSync(n).filter((i)=>!i.startsWith(".")&&ne.existsSync(Pe.join(n,i,"package.json")))}function F(e,t,n){let i=JSON.parse(ne.readFileSync(Pe.join(e,t,n,"package.json"),"utf8"));if(!i.name||!i.version)throw new l(r("packageJsonIncomplete",{folder:n}));return i}function Se(e,t){let n=[];for(let i of["dependencies","devDependencies"])for(let o of Object.keys(e[i]??{})){let s=t.get(o);if(s)n.push(s)}return n}async function L(e){let t=await x("git",["status","--porcelain"],e);if(t.code!==0)throw new l(r("gitFailed",{detail:t.stderr.trim()}));if(t.stdout.trim())throw new l(r("dirtyTree"))}async function Ge(e,t){let n=await x("git",["status","--porcelain"],e);if(n.code!==0)throw new l(r("gitFailed",{detail:n.stderr.trim()}));if(n.stdout.trim())throw new l(t)}async function Le(e){return(await w("git",["log","--format=%H%x1f%s"],e)).split(`
50
- `).filter(Boolean).map((n)=>{let[i,o]=n.split("\x1F");return{hash:i,subject:o??""}})}async function ce(e){let t=await w("git",["log","-F",`--grep=${ye}`,"--format=%H%x1f%s%x1f%b%x1e"],e),n=[];for(let i of t.split("\x1E")){let o=i.replace(/^\n/,"").trim();if(!o)continue;let[s,a,c]=o.split("\x1F");if(!s)continue;n.push({hash:s,subject:a??"",body:c??""})}return n}async function J(e,t){if(t){let s=await x("git",["rev-parse","--verify",`${t}^{commit}`],e);if(s.code!==0)throw new l(r("badBaseline",{rev:t}));return s.stdout.trim()}if((await x("git",["rev-parse","--verify","HEAD"],e)).code!==0)throw new l(r("noBaseline"));let i=await ce(e),o=(await Le(e)).find((s)=>lt(s.subject));if(i[0]){if(o&&o.hash!==i[0].hash&&(await x("git",["merge-base","--is-ancestor",i[0].hash,o.hash],e)).code===0)return o.hash;return i[0].hash}return o?.hash??Zt()}async function Ce(e,t,n){let i=await J(e,n),o=X(e,t.packagesDir),s=await w("git",["diff","--name-only",i,"HEAD"],e),a=it(s,t.packagesDir,o),c=new Set;for(let[h,y]of a){let f=`${t.packagesDir}/${h}/package.json`;if(y.includes(f)&&await Ve(e,i,"HEAD",f))c.add(h)}let{changed:g,dependents:d}=ut({packages:o.map((h)=>({...F(e,t.packagesDir,h),folder:h})),filesByFolder:a,devOnly:c,include:t.include,exclude:t.exclude,packagesDir:t.packagesDir});return{baseline:i,changed:g,dependents:d}}async function Ve(e,t,n,i){let o=await ht(e,`${t}:${i}`),s=await ht(e,`${n}:${i}`);if(o===null||s===null)return!1;try{return st(JSON.parse(o),JSON.parse(s))}catch{return!1}}async function ht(e,t){let n=await x("git",["show",t],e);return n.code===0?n.stdout:null}function Zt(){throw new l(r("noBaseline"))}async function pt(e){let t=en.resolve(e.root),n=ie(t,e.versionsFile);if(e.packages)n.packagesDir=e.packages;await L(t);let{baseline:i,changed:o,dependents:s}=await Ce(t,n,e.baseline);if(!o.length&&!s.length){let a=(await w("git",["rev-parse","--short",i],t)).trim();console.log(P(r("noPackagesSince",{rev:a})));return}console.log(S(r("changedHeader")));for(let a of o)console.log(` ${O(F(t,n.packagesDir,a).name)}`);if(s.length){console.log(S(r("dependentsHeader")));for(let a of s)console.log(` ${Q(F(t,n.packagesDir,a).name)}`)}}import M from"node:fs";import Z from"node:path";R();D();import tn from"node:readline/promises";import{stdin as ft,stdout as wt}from"node:process";R();D();class G extends l{constructor(){super(r("interactiveCancelled"))}}async function qe(e){let t=tn.createInterface({input:ft,output:wt}),n=new AbortController,i=()=>n.abort();t.once("SIGINT",i),t.once("close",i);try{return await t.question(e,{signal:n.signal})}catch(o){if(n.signal.aborted)throw new G;throw o}finally{t.off("SIGINT",i),t.off("close",i),t.close()}}function z(){return Boolean(ft.isTTY&&wt.isTTY)}async function Ue(e,t){if(!z())throw new l(r("bumpRequired"));console.log(S(e)),t.forEach((n,i)=>console.log(` ${O(String(i+1))}) ${n}`));while(!0){let n=(await qe(r("chooseIndex"))).trim();if(n.toLowerCase()==="q")throw new G;let i=/^\d+$/.test(n)?Number(n)-1:-1;if(Number.isInteger(i)&&i>=0&&i<t.length)return t[i];console.log(k(r("invalidChoice",{answer:n||r("emptyAnswer")})))}}async function _(e,t){let n=await Ue(e,t.map((i)=>i.label));return t.find((i)=>i.label===n).value}async function B(e,t=""){if(!z())throw new l(r("yesRequired"));let n=t?` [${t}]`:"",i=(await qe(`${e}${n} `)).trim();if(i.toLowerCase()==="q")throw new G;return i||t}async function ze(e){if(!z())throw new l(r("yesRequired"));console.log(S(e));while(!0){let t=(await qe("[y/N/q] ")).trim().toLowerCase();if(t==="q")throw new G;if(t==="y"||t==="yes")return!0;if(!t||t==="n"||t==="no")return!1;console.log(k(r("confirmAnswer")))}}function nn(e){let t=new Set,n=[];for(let i of[...an(e),...cn(e)]){if(t.has(i))continue;t.add(i),n.push(i)}return n}function rn(e,t=Ie()){let n=(s,a="")=>r(s,void 0,t).split(`
47
+ `;var Mt=Be(()=>{F();zn=new Set(["docs","style","chore","refactor","test","build","ci"]),Et={feat:"Features",feature:"Features",fix:"Bug Fixes",perf:"Performance Improvements",revert:"Reverts"}});import{Command as Mn}from"commander";import{readFileSync as Hn}from"node:fs";import tn from"node:path";import{styleText as Vt}from"node:util";function O(e,t,n){return Vt(e,t,{stream:n})}function C(e){return O(["bold","cyan"],e,process.stdout)}function G(e){return O("bold",e,process.stdout)}function X(e){return O("green",e,process.stdout)}function P(e){return O("dim",e,process.stdout)}function B(e){return O("cyan",e,process.stdout)}function Ye(e,t,n){return`${G(e)} ${P(t)} ${P("=>")} ${X(n)}`}function I(e){let[t,...n]=e.split(`
48
+ `),i=O("red",t,process.stderr);if(!n.length)return i;return[i,...n.map((o)=>O("yellow",o,process.stderr))].join(`
49
+ `)}function W(e){return O("green",e,process.stdout)}function k(e){return O("yellow",e,process.stdout)}function pe(e){return O("red",e,process.stdout)}R();R();F();import{spawn as dt}from"node:child_process";function x(e,t,n){return new Promise((i)=>{let o=dt(e,t,{cwd:n,stdio:["ignore","pipe","pipe"]}),s="",a="";o.stdout.on("data",(c)=>{s+=c}),o.stderr.on("data",(c)=>{a+=c}),o.on("error",(c)=>i({code:1,stdout:s,stderr:`${a}${c.message}`})),o.on("close",(c)=>i({code:c??1,stdout:s,stderr:a}))})}async function w(e,t,n){let i=await x(e,t,n);if(i.code!==0){let o=(i.stderr||i.stdout).trim();throw new l(o?r("commandFailed",{command:e,detail:o}):r("commandFailedShort",{command:e}))}return i.stdout}function Pe(e,t,n,i){return new Promise((o,s)=>{let a=dt(e,t,{cwd:n,stdio:"inherit",env:{...process.env,...i}});a.on("error",s),a.on("exit",(c)=>{if(c===0)o();else s(new l(r("commandExit",{command:e,code:c??1})))})})}R();F();import ne from"node:fs";import Ce from"node:path";R();F();function ut(e){let t=e.packages.map((g)=>g.folder),n=new Map(e.packages.map((g)=>[g.folder,g])),i=new Map(e.packages.map((g)=>[g.name,g])),o=new Map(e.packages.map((g)=>[g.name,g.folder])),{changed:s}=rt(t,e.filesByFolder,e.include,e.exclude,(g)=>e.devOnly.has(g),e.packagesDir),a=at(t,s,(g)=>Zt(n.get(g),o));for(let g of a){let d=n.get(g);if(!d||d.private)continue;for(let h of Object.keys(d.dependencies??{}))if(i.get(h)?.private)throw new l(r("publicDependsOnPrivate",{name:d.name,dep:h}))}let c=new Set(s);return{changed:s,dependents:a.filter((g)=>!c.has(g))}}function Zt(e,t){if(!e)return[];return[...Object.keys(e.dependencies??{}),...Object.keys(e.devDependencies??{})].flatMap((i)=>{let o=t.get(i);return o?[o]:[]})}function ie(e,t){let n=Ce.resolve(e,t);if(!ne.existsSync(n))throw new l(r("configUnreadable",{file:t}));return ye(ne.readFileSync(n,"utf8"))}function J(e,t){let n=Ce.join(e,t);if(!ne.existsSync(n))throw new l(r("packagesDirMissing",{dir:t}));return ne.readdirSync(n).filter((i)=>!i.startsWith(".")&&ne.existsSync(Ce.join(n,i,"package.json")))}function D(e,t,n){let i=JSON.parse(ne.readFileSync(Ce.join(e,t,n,"package.json"),"utf8"));if(!i.name||!i.version)throw new l(r("packageJsonIncomplete",{folder:n}));return i}function Se(e,t){let n=[];for(let i of["dependencies","devDependencies"])for(let o of Object.keys(e[i]??{})){let s=t.get(o);if(s)n.push(s)}return n}async function L(e){let t=await x("git",["status","--porcelain"],e);if(t.code!==0)throw new l(r("gitFailed",{detail:t.stderr.trim()}));if(t.stdout.trim())throw new l(r("dirtyTree"))}async function Ge(e,t){let n=await x("git",["status","--porcelain"],e);if(n.code!==0)throw new l(r("gitFailed",{detail:n.stderr.trim()}));if(n.stdout.trim())throw new l(t)}async function Ve(e){return(await w("git",["log","--format=%H%x1f%s"],e)).split(`
50
+ `).filter(Boolean).map((n)=>{let[i,o]=n.split("\x1F");return{hash:i,subject:o??""}})}async function ce(e){let t=await w("git",["log","-F",`--grep=${ve}`,"--format=%H%x1f%s%x1f%b%x1e"],e),n=[];for(let i of t.split("\x1E")){let o=i.replace(/^\n/,"").trim();if(!o)continue;let[s,a,c]=o.split("\x1F");if(!s)continue;n.push({hash:s,subject:a??"",body:c??""})}return n}async function _(e,t){if(t){let s=await x("git",["rev-parse","--verify",`${t}^{commit}`],e);if(s.code!==0)throw new l(r("badBaseline",{rev:t}));return s.stdout.trim()}if((await x("git",["rev-parse","--verify","HEAD"],e)).code!==0)throw new l(r("noBaseline"));let i=await ce(e),o=(await Ve(e)).find((s)=>lt(s.subject));if(i[0]){if(o&&o.hash!==i[0].hash&&(await x("git",["merge-base","--is-ancestor",i[0].hash,o.hash],e)).code===0)return o.hash;return i[0].hash}return o?.hash??en()}async function ze(e,t,n){let i=await _(e,n),o=J(e,t.packagesDir),s=await w("git",["diff","--name-only",i,"HEAD"],e),a=it(s,t.packagesDir,o),c=new Set;for(let[h,y]of a){let f=`${t.packagesDir}/${h}/package.json`;if(y.includes(f)&&await Le(e,i,"HEAD",f))c.add(h)}let{changed:g,dependents:d}=ut({packages:o.map((h)=>({...D(e,t.packagesDir,h),folder:h})),filesByFolder:a,devOnly:c,include:t.include,exclude:t.exclude,packagesDir:t.packagesDir});return{baseline:i,changed:g,dependents:d}}async function Le(e,t,n,i){let o=await ht(e,`${t}:${i}`),s=await ht(e,`${n}:${i}`);if(o===null||s===null)return!1;try{return st(JSON.parse(o),JSON.parse(s))}catch{return!1}}async function ht(e,t){let n=await x("git",["show",t],e);return n.code===0?n.stdout:null}function en(){throw new l(r("noBaseline"))}async function pt(e){let t=tn.resolve(e.root),n=ie(t,e.versionsFile);if(e.packages)n.packagesDir=e.packages;await L(t);let{baseline:i,changed:o,dependents:s}=await ze(t,n,e.baseline);if(!o.length&&!s.length){let a=(await w("git",["rev-parse","--short",i],t)).trim();console.log(P(r("noPackagesSince",{rev:a})));return}console.log(C(r("changedHeader")));for(let a of o)console.log(` ${G(D(t,n.packagesDir,a).name)}`);if(s.length){console.log(C(r("dependentsHeader")));for(let a of s)console.log(` ${X(D(t,n.packagesDir,a).name)}`)}}import H from"node:fs";import Z from"node:path";R();F();import nn from"node:readline/promises";import{stdin as ft,stdout as wt}from"node:process";R();F();class V extends l{constructor(){super(r("interactiveCancelled"))}}async function qe(e){let t=nn.createInterface({input:ft,output:wt}),n=new AbortController,i=()=>n.abort();t.once("SIGINT",i),t.once("close",i);try{return await t.question(e,{signal:n.signal})}catch(o){if(n.signal.aborted)throw new V;throw o}finally{t.off("SIGINT",i),t.off("close",i),t.close()}}function z(){return Boolean(ft.isTTY&&wt.isTTY)}async function Ue(e,t){if(!z())throw new l(r("bumpRequired"));console.log(C(e)),t.forEach((n,i)=>console.log(` ${G(String(i+1))}) ${n}`));while(!0){let n=(await qe(r("chooseIndex"))).trim();if(n.toLowerCase()==="q")throw new V;let i=/^\d+$/.test(n)?Number(n)-1:-1;if(Number.isInteger(i)&&i>=0&&i<t.length)return t[i];console.log(k(r("invalidChoice",{answer:n||r("emptyAnswer")})))}}async function K(e,t){let n=await Ue(e,t.map((i)=>i.label));return t.find((i)=>i.label===n).value}async function M(e,t=""){if(!z())throw new l(r("yesRequired"));let n=t?` [${t}]`:"",i=(await qe(`${e}${n} `)).trim();if(i.toLowerCase()==="q")throw new V;return i||t}async function le(e){if(!z())throw new l(r("yesRequired"));console.log(C(e));while(!0){let t=(await qe("[y/N/q] ")).trim().toLowerCase();if(t==="q")throw new V;if(t==="y"||t==="yes")return!0;if(!t||t==="n"||t==="no")return!1;console.log(k(r("confirmAnswer")))}}function rn(e){let t=new Set,n=[];for(let i of[...cn(e),...ln(e)]){if(t.has(i))continue;t.add(i),n.push(i)}return n}function sn(e,t=Ae()){let n=(s,a="")=>r(s,void 0,t).split(`
51
51
  `).map((c)=>`${a}# ${c}`).join(`
52
- `),i=(s,a,c,g)=>[n(g," "),a?` ${s}: ${le(a)}`:` # ${s}: ${c}`].join(`
53
- `),o=[n("initNotePackagesDir"),`packagesDir: ${le(e.packagesDir)}`,"",n("initNoteCommitMessage"),'commitMessage: "bump: %s"',"",n("initNoteBranch"),e.branch?`branch: ${le(e.branch)}`:"# branch: main","","hooks:",i("beforeCommit",e.beforeCommit,"bun install","initNoteBeforeCommit"),i("beforePublish",e.beforePublish,"bun run build","initNoteBeforePublish"),i("afterPublish",void 0,"echo published","initNoteAfterPublish"),"",n("initNoteInclude"),"include:",...e.include.map((s)=>` - ${le(s)}`),` # - ${e.packagesDir}/*/bin`,"",n("initNoteExclude")];if(e.exclude.length)o.push("exclude:",...e.exclude.map((s)=>` - ${le(s)}`));else o.push("# exclude:",`# - ${e.packagesDir}/*/src/**/__tests__/**`);return`${o.join(`
52
+ `),i=(s,a,c,g)=>[n(g," "),a?` ${s}: ${ge(a)}`:` # ${s}: ${c}`].join(`
53
+ `),o=[n("initNotePackagesDir"),`packagesDir: ${ge(e.packagesDir)}`,"",n("initNoteCommitMessage"),'commitMessage: "bump: %s"',"",n("initNoteBranch"),e.branch?`branch: ${ge(e.branch)}`:"# branch: main","","hooks:",i("beforeCommit",e.beforeCommit,"bun install","initNoteBeforeCommit"),i("beforePublish",e.beforePublish,"bun run build","initNoteBeforePublish"),i("afterPublish",void 0,"echo published","initNoteAfterPublish"),"",n("initNoteInclude"),"include:",...e.include.map((s)=>` - ${ge(s)}`),` # - ${e.packagesDir}/*/bin`,"",n("initNoteExclude")];if(e.exclude.length)o.push("exclude:",...e.exclude.map((s)=>` - ${ge(s)}`));else o.push("# exclude:",`# - ${e.packagesDir}/*/src/**/__tests__/**`);return`${o.join(`
54
54
  `)}
55
- `}async function Re(e){let t=Z.resolve(e.root),n=Z.resolve(t,e.versionsFile);if(M.existsSync(n))throw new l(r("configExists",{file:e.versionsFile}));let i=nn(t),o=i[0]??"packages",s=e.yes?sn(o):await on(e.versionsFile,i,o);if(!s.include.length)throw new l(r("includeRequired"));let a=rn(s);be(a),M.mkdirSync(Z.dirname(n),{recursive:!0}),M.writeFileSync(n,a),console.log(Q(r("initWrote",{file:e.versionsFile})))}function sn(e){return{packagesDir:e,include:[`${e}/*/src`],exclude:[`${e}/*/src/**/__tests__/**`]}}async function on(e,t,n){if(!z())throw new l(r("yesRequired"));if(console.log(S(r("initIntro",{file:e}))),t.length)console.log(P(r("initFoundDirs",{dirs:t.join(", ")})));let i=await B(r("initPackagesDir"),n),o=bt(await B(r("initInclude"),`${i}/*/src`)),s=bt(await B(r("initExclude"),`${i}/*/src/**/__tests__/**`)),a=await B(r("initBranch")),c=await B(r("initBeforeCommit")),g=await B(r("initBeforePublish"));return{packagesDir:i,branch:a||void 0,beforeCommit:c||void 0,beforePublish:g||void 0,include:o,exclude:s}}function bt(e){return e.split(",").map((t)=>t.trim()).filter(Boolean)}function le(e){return/^[A-Za-z0-9_./@*+-]+$/.test(e)?e:JSON.stringify(e)}function an(e){return gn(e).flatMap((t)=>{let n=t.replace(/\/\*\*?$/,"");if(!n||n===t||n.includes("*"))return[];return M.existsSync(Z.join(e,n))?[n]:[]})}function cn(e){if(!M.existsSync(e))return[];let t=[];for(let n of M.readdirSync(e)){if(n.startsWith(".")||n==="node_modules")continue;let i=Z.join(e,n);if(!M.statSync(i).isDirectory())continue;if(ln(i))t.push(n)}return t}function ln(e){return M.readdirSync(e).some((t)=>M.existsSync(Z.join(e,t,"package.json")))}function gn(e){let t=Z.join(e,"package.json");if(!M.existsSync(t))return[];try{let n=JSON.parse(M.readFileSync(t,"utf8")),i=Array.isArray(n.workspaces)?n.workspaces:n.workspaces?.packages;return Array.isArray(i)?i.filter((o)=>typeof o==="string"):[]}catch{return[]}}import Te from"node:path";import vt from"semver";import re from"node:fs";import We from"node:path";import mn from"node:os";import{randomUUID as dn}from"node:crypto";import{AsyncLocalStorage as un}from"node:async_hooks";D();R();var Je=new un;async function se(e,t,n){if(t)return n();e=We.resolve(e);let i=We.resolve(e,(await w("git",["rev-parse","--git-common-dir"],e)).trim()),o=We.join(i,"change-versions.lock");if(Je.getStore()?.has(o))return n();let s={pid:process.pid,host:mn.hostname(),token:dn()},a;try{a=re.openSync(o,"wx",384)}catch(d){if(d.code!=="EEXIST")throw d;let h="";try{h=re.readFileSync(o,"utf8")}catch{}throw new l(r("repositoryLocked",{file:o,owner:h.trim()}))}let c=()=>{try{if(JSON.parse(re.readFileSync(o,"utf8")).token===s.token)re.unlinkSync(o)}catch{}};try{re.writeFileSync(a,JSON.stringify(s))}finally{re.closeSync(a)}let g=()=>{if(process.listenerCount("SIGINT")<=1&&process.listenerCount("SIGTERM")<=1)process.exit(1)};process.on("exit",c),process.on("SIGINT",g),process.on("SIGTERM",g);try{return await Je.run(new Set([...Je.getStore()??[],o]),n)}finally{process.off("SIGINT",g),process.off("SIGTERM",g),process.off("exit",c),c()}}R();function hn(e){if(/^[a-zA-Z0-9_./:@=+-]+$/.test(e))return e;return"'"+e.replaceAll("'","'\\''")+"'"}function V(e){let t=["change-versions","publish",`--dist-tag=${e.distTag}`,`--root=${e.root}`,`--versions-file=${e.versionsFile}`];if(e.commit)t.push(`--commit=${e.commit}`);if(e.packages)t.push(`--packages=${e.packages}`);return t.map(hn).join(" ")}D();D();function yt(e){let t=[];if(e.beforePublish)t.push({kind:"hook",name:"beforePublish",command:e.beforePublish});for(let n of mt(e.packages.filter((i)=>!i.private))){if(n.published&&n.distTagVersion===n.version)continue;let i=n.registry??"";t.push(n.published?{kind:"dist-tag",name:n.name,version:n.version,folder:n.folder,registry:i,tag:e.distTag}:{kind:"publish",name:n.name,version:n.version,folder:n.folder,registry:i,tag:e.distTag})}if(e.afterPublish)t.push({kind:"hook",name:"afterPublish",command:e.afterPublish});if(e.formal)for(let n of e.packages)t.push({kind:"tag",name:n.name,version:n.version,commit:e.commit});return t}async function zt(e){return se(e.root,Boolean(e.dryRun),()=>pn(e))}async function pn(e){console.log(e.dryRun?k(r("publishPreview")):S(r("publishPreparing")));let{root:t,startHead:n,config:i,release:o,entries:s,formal:a,registryOf:c,published:g,distTagVersions:d,steps:h}=await ge(e),y=V({...e,root:t,commit:o.hash}),f={CHANGE_VERSIONS_PUBLISH_CONTEXT:JSON.stringify({schemaVersion:1,root:t,packagesDir:i.packagesDir,commit:o.hash,distTag:e.distTag,packages:h.flatMap((m)=>m.kind==="publish"?[{name:m.name,version:m.version,path:Te.join(i.packagesDir,m.folder)}]:[])})};for(let m of s)if(g.has(m.folder)&&d.get(m.folder)===m.to)console.log(P(r("alreadyTagged",{name:m.name,version:m.to,tag:e.distTag,registry:c.get(m.folder)||""})));if(console.log(r("publishPlanSummary",{uploads:h.filter((m)=>m.kind==="publish").length,retags:h.filter((m)=>m.kind==="dist-tag").length,tags:h.filter((m)=>m.kind==="tag").length})),e.dryRun){for(let m of h)console.log(`${k(r("plannedStep",{step:""}))}${kt(m)}`);if(a&&i.branch)console.log(k(r("plannedStep",{step:`git push origin ${s.map((m)=>`refs/tags/${m.name}@${m.to}`).join(" ")}`})));if(!a)console.log(P(r("noGitTag")));console.log(k(r("publishPreviewComplete"))),console.log(S(r("publishPreviewNext"))),console.log(A(y));return}console.log(P(r("publishResumeInfo"))),console.log(S(r("willPublish")));for(let m of s){if(g.has(m.folder)&&d.get(m.folder)===m.to)continue;let E=m.pkg.private?` ${P(r("privateMark"))}`:g.has(m.folder)?` ${P(r("distTagOnlyMark"))}`:"";console.log(` ${O(m.name)} ${Q(m.to)}${E}`)}if(!e.yes&&!await ze(r("confirmPublish")))throw new l(r("cancelledPublish"));let u=new Map(s.map((m)=>[m.folder,m.pkg.private?"summaryPrivate":g.has(m.folder)&&d.get(m.folder)===m.to?"summarySkipped":"summaryPending"])),v="beforePublish",b,I=!1,p=(m)=>m==="summaryPublished"||m==="summaryRetagged"?W:m==="summaryFailed"?he:m==="summaryPending"?k:P,C=()=>{console.log((I?W:he)(r(I?"publishComplete":"publishIncomplete"))),console.log(r("publishSummaryContext",{commit:o.hash,tag:e.distTag}));let m=new Map;for(let E of s){let T=u.get(E.folder);m.set(T,(m.get(T)??0)+1);let Ke=c.get(E.folder);console.log(` ${p(T)(r(T))}: ${O(E.name)}@${O(E.to)}${Ke?` — ${P(Ke)}`:""}`)}if(console.log([...m].map(([E,T])=>`${p(E)(r(E))}: ${O(String(T))}`).join(", ")),I)console.log(W(r("publishReady"))),console.log(P(r(a?i.branch?"gitTagsPushed":"gitTagsLocal":"noGitTag")));else{if(console.log(he(r("publishFailedStage",{stage:v}))),v==="git tag / git push")console.log(k(r("publishTagRecovery")));console.log(k(r("publishRetryTitle"))),console.log(S(r("publishRetry"))),console.log(P(r("publishResumeInfo"))),console.log(A(y))}},N=()=>{if(b)u.set(b,"summaryFailed");C(),console.error(j(r("publishInterrupted"))),process.exit(1)};process.on("SIGINT",N),process.on("SIGTERM",N);try{await Ct(t,i.hooks.beforePublish,"beforePublish",f),await Ge(t,r("beforePublishDirty")),await xt(t,n);for(let m of h){if(m.kind!=="publish"&&m.kind!=="dist-tag")continue;console.log(S(r("executingStep",{step:kt(m)})));let E=Te.join(t,i.packagesDir,m.folder);v=`${m.kind==="publish"?"npm publish":"npm dist-tag add"} ${m.name}@${m.version}`,b=m.folder,await Tt(async()=>{if(m.kind==="dist-tag")await Pt(t,["dist-tag","add",`${m.name}@${m.version}`,m.tag,`--registry=${m.registry}`],m.registry);else await Pt(E,["publish",`--tag=${m.tag}`,`--registry=${m.registry}`],m.registry)}),u.set(m.folder,m.kind==="publish"?"summaryPublished":"summaryRetagged"),b=void 0}if(v="afterPublish",await Ct(t,i.hooks.afterPublish,"afterPublish",f),await Ge(t,r("afterPublishDirty")),await xt(t,n),v="git tag / git push",a)console.log(S(r("executingStep",{step:v}))),await fn(t,i.branch,s,o.hash);I=!0}catch(m){if(b)u.set(b,"summaryFailed");throw m}finally{process.off("SIGINT",N),process.off("SIGTERM",N),C()}}async function ge(e,t=!1,n=!1){let i=Te.resolve(e.root);if(!t)await L(i);let o=(await w("git",["rev-parse","HEAD"],i)).trim(),s=ie(i,e.versionsFile);if(e.packages)s.packagesDir=e.packages;let a=await q(i,e.commit);if(!a?.lines.length)throw new l(r("noVersionCommit"));let c=X(i,s.packagesDir),g=new Map(c.map((p)=>[F(i,s.packagesDir,p).name,p])),d=a.lines.map((p)=>{let C=g.get(p.name);if(!C)throw new l(r("packageNotInDir",{dir:s.packagesDir,name:p.name}));let N=F(i,s.packagesDir,C);if(N.version!==p.to)throw new l(r("releaseVersionMismatch",{name:p.name,expected:p.to,actual:N.version,commit:a.hash}));return{...p,folder:C,pkg:N,deps:Se(N,g)}}),h=await x("git",["diff","--quiet",a.hash,"HEAD","--",...d.map((p)=>`${s.packagesDir}/${p.folder}`)],i);if(h.code===1&&!n)throw new l(r("releaseContentsChanged"));if(h.code!==0&&h.code!==1)throw new l(r("gitFailed",{detail:h.stderr.trim()}));if(!t)console.log(r("publishSummaryContext",{commit:a.hash,tag:e.distTag}));let y=ve(a.lines);if(y)await Rt(i,d,a.hash);let f=new Map;for(let p of d){if(p.pkg.private)continue;let C=await vn(i,p.pkg);if(f.set(p.folder,C),!t)console.log(r("checkingRegistry",{name:p.name,version:p.to,registry:C}))}let u=new Set;for(let p of d){let C=f.get(p.folder);if(!C||u.has(C))continue;if(u.add(C),!t)await yn(i,C)}let v=new Set,b=new Map;for(let p of d){if(p.pkg.private)continue;let C=f.get(p.folder);if(!C)continue;await Tt(async()=>{if(await wn(i,p.name,p.to,C)){v.add(p.folder);let N=await bn(i,p.name,e.distTag,C);b.set(p.folder,N)}})}let I=yt({packages:d.map((p)=>({name:p.name,version:p.to,folder:p.folder,private:p.pkg.private,deps:p.deps,registry:f.get(p.folder),published:v.has(p.folder),distTagVersion:b.get(p.folder)})),distTag:e.distTag,formal:y,commit:a.hash,beforePublish:s.hooks.beforePublish,afterPublish:s.hooks.afterPublish});return{root:i,startHead:o,config:s,release:a,entries:d,formal:y,registryOf:f,published:v,distTagVersions:b,steps:I}}function kt(e){if(e.kind==="hook")return`${P(`${e.name}:`)} ${A(e.command)}`;if(e.kind==="tag")return A(`git tag ${e.name}@${e.version} ${e.commit}`);if(e.kind==="dist-tag")return A(`npm dist-tag add ${e.name}@${e.version} ${e.tag} --registry=${e.registry}`);return A(`npm publish --tag=${e.tag} --registry=${e.registry} ${e.name}@${e.version}`)}async function q(e,t){if((await x("git",["rev-parse","--verify","HEAD"],e)).code!==0)return null;let i;if(t){let a=await x("git",["rev-parse","--verify","--end-of-options",`${t}^{commit}`],e);if(a.code!==0)throw new l(r("badReleaseCommit",{commit:t}));let c=a.stdout.trim();if((await x("git",["merge-base","--is-ancestor",c,"HEAD"],e)).code!==0)throw new l(r("badReleaseCommit",{commit:t}));i={hash:c,subject:(await w("git",["show","-s","--format=%s",c],e)).trim(),body:await w("git",["show","-s","--format=%b",c],e)}}else i=(await ce(e))[0];if(!i)return null;let o=ke(i.body);if(!o.length){if(t)throw new l(r("badReleaseCommit",{commit:t}));return null}if(new Set(o.map((a)=>a.name)).size!==o.length||o.some((a)=>!vt.valid(a.from)||!vt.valid(a.to)))throw new l(r("badReleaseCommit",{commit:i.hash}));let s=/^Change-Versions-Dist-Tag: (\S+)$/m.exec(i.body)?.[1];return{hash:i.hash,subject:i.subject,lines:o,distTag:s}}async function fn(e,t,n,i){await Rt(e,n,i);let o=n.map((a)=>`${a.name}@${a.to}`);for(let a of o){if((await x("git",["rev-parse","--verify",`refs/tags/${a}^{commit}`],e)).code===0)continue;await w("git",["tag",a,i],e)}if(!t)return;let s=await x("git",["push","origin",...o.map((a)=>`refs/tags/${a}`)],e);if(s.code!==0)throw new l(r("tagPushFailed",{detail:s.stderr.trim()}))}async function Rt(e,t,n){for(let i of t){let o=`${i.name}@${i.to}`,s=await x("git",["rev-parse","--verify",`refs/tags/${o}^{commit}`],e);if(s.code===0&&s.stdout.trim()!==n)throw new l(r("tagPointsElsewhere",{tag:o}))}}async function xt(e,t){if((await w("git",["rev-parse","HEAD"],e)).trim()!==t)throw new l(r("publishHeadChanged"))}async function Tt(e){let t="";for(let n=0;n<3;n++)try{await e();return}catch(i){if(i instanceof l&&i.auth)throw i;t=i instanceof Error?i.message:String(i)}throw new l(r("networkFailed",{detail:t}))}async function Pt(e,t,n){let i=await x("npm",t,e);if(i.code===0)return;let o=`${i.stderr}${i.stdout}`;if(process.stderr.write(i.stderr),ae(o))throw new l(r("notLoggedIn",{registry:n}),!0);throw Error(o.trim()||r("npmFailed"))}async function wn(e,t,n,i){let o=await x("npm",["view",`${t}@${n}`,"version","--json",`--registry=${i}`],e);if(o.code===0){let a;try{a=JSON.parse(o.stdout)}catch{}if(a===n||Array.isArray(a)&&a.length===1&&a[0]===n)return!0;throw Error(r("unexpectedRegistryVersion",{name:t,version:n,registry:i}))}let s=`${o.stderr}${o.stdout}`;if(ae(s))throw new l(r("notLoggedIn",{registry:i}),!0);if(Oe(o.stdout)||Oe(o.stderr))return!1;throw Error(s.trim()||r("npmViewFailed"))}async function bn(e,t,n,i){let o=await x("npm",["view",t,"dist-tags","--json",`--registry=${i}`],e);if(o.code!==0){let c=`${o.stderr}${o.stdout}`.trim();if(ae(c))throw new l(r("notLoggedIn",{registry:i}),!0);throw Error(c||r("npmViewFailed"))}let s;try{s=JSON.parse(o.stdout)}catch{}if(Array.isArray(s)&&s.length===1)s=s[0];if(!s||typeof s!=="object"||Array.isArray(s))throw Error(r("unexpectedRegistryTags",{name:t,tag:n,registry:i}));let a=Object.prototype.hasOwnProperty.call(s,n)?s[n]:void 0;if(a!==void 0&&typeof a!=="string")throw Error(r("unexpectedRegistryTags",{name:t,tag:n,registry:i}));return a}async function yn(e,t){let n=await x("npm",["whoami",`--registry=${t}`],e);if(n.code===0)return;let i=`${n.stderr}${n.stdout}`;if(ae(i))throw new l(r("notLoggedIn",{registry:t}),!0);throw new l(r("registryUnreachable",{registry:t,detail:i.trim()}))}async function vn(e,t){if(t.publishConfig?.registry)return t.publishConfig.registry.replace(/\/$/,"");if(t.name.startsWith("@")&&t.name.includes("/")){let i=t.name.slice(0,t.name.indexOf("/")),o=await St(e,`${i}:registry`);if(o&&o!=="undefined"&&o!=="null")return o.replace(/\/$/,"")}let n=await St(e,"registry");if(!n||n==="undefined"||n==="null")throw new l(r("noNpmRegistry",{detail:"npm config get registry: empty value"}));return n.replace(/\/$/,"")}async function St(e,t){let n=await x("npm",["config","get",t],e);if(n.code!==0){let i=n.stderr.trim()||n.stdout.trim()||`npm config get ${t}: exit ${n.code}`;throw new l(r("noNpmRegistry",{detail:i}))}return n.stdout.trim()}async function Ct(e,t,n,i){if(!t)return;console.log(S(r("executingStep",{step:`${n}: ${t}`})));try{await xe("sh",["-c",t],e,i)}catch(o){let s=o instanceof Error?o.message:String(o);throw new l(r("hookFailed",{name:n,detail:s}))}}async function me(e,t,n){return t??(await q(Te.resolve(e),n))?.distTag??"latest"}import An from"node:path";import Ht from"semver";import te from"node:fs";import De from"node:path";import ee from"node:fs";import K from"node:path";import{spawnSync as kn}from"node:child_process";D();R();function _e(e){try{let t=ee.lstatSync(e);if(!t.isFile())throw new l(r("unsafeCommitFile",{file:e}));return{bytes:ee.readFileSync(e),mode:t.mode&511}}catch(t){if(t.code==="ENOENT")return;throw t}}function xn(e,t){return e===t||Boolean(e&&t&&e.mode===t.mode&&e.bytes.equals(t.bytes))}async function $t(e,t,n){let i=(await w("git",["rev-parse","HEAD"],e)).trim();if(n&&i!==n)throw new l(r("versionHeadChanged"));let o=new Map;for(let f of new Set(t)){let u=K.resolve(e,f),v=K.relative(e,u);if(!v||v.startsWith("..")||K.isAbsolute(v)||/[*?\[\]\\]/.test(f)||v.split(K.sep).includes(".git"))throw new l(r("unsafeCommitFile",{file:f}));for(let b=K.dirname(u);b!==e;b=K.dirname(b))if(ee.existsSync(b)&&ee.lstatSync(b).isSymbolicLink())throw new l(r("unsafeCommitFile",{file:f}));o.set(v,_e(u))}let s=new Map(o),a,c=!0,g=()=>{s=new Map([...o.keys()].map((f)=>[f,_e(K.join(e,f))]))},d=(...f)=>kn("git",f,{cwd:e,encoding:"utf8"}),h=()=>{if(!c)return;c=!1,process.off("SIGINT",y),process.off("SIGTERM",y);let f=d("rev-parse","HEAD");if(f.status!==0||f.stdout.trim()!==i){console.error(j(r("versionHeadChanged")));return}if(a!==void 0&&d("write-tree").stdout.trim()===a)d("restore","--staged","--",...o.keys());for(let[u,v]of o){let b=K.join(e,u);try{if(!xn(_e(b),s.get(u)))continue;if(v)ee.writeFileSync(b,v.bytes),ee.chmodSync(b,v.mode);else ee.rmSync(b,{force:!0})}catch{}}},y=()=>{h(),console.error(j(r("versionRecovery"))),process.exit(1)};return process.on("SIGINT",y),process.on("SIGTERM",y),{checkpoint:g,async stage(){if((await w("git",["rev-parse","HEAD"],e)).trim()!==i)throw new l(r("versionHeadChanged"));if(await w("git",["diff","--cached","--name-only","-z"],e))throw new l(r("versionUnexpectedIndex"));let u=(await w("git",["diff","--name-only","-z"],e)).split("\x00").filter(Boolean),v=(await w("git",["ls-files","--others","--exclude-standard","-z"],e)).split("\x00").filter(Boolean),b=[...u,...v].filter((C)=>!o.has(C));if(b.length)throw new l(r("versionUnexpectedFiles",{files:b.join(", ")}));g();let I=[...new Set([...u,...v])];if(!I.length)throw new l(r("versionUnexpectedIndex"));if(await w("git",["add","--",...I],e),a=(await w("git",["write-tree"],e)).trim(),(await w("git",["diff","--cached","--name-only","-z"],e)).split("\x00").filter(Boolean).some((C)=>!o.has(C)))throw new l(r("versionUnexpectedIndex"))},async verifyCommit(){let f=(await w("git",["rev-parse","HEAD^"],e)).trim(),u=(await w("git",["rev-parse","HEAD^{tree}"],e)).trim();if(f!==i||u!==a)throw new l(r("versionHeadChanged"))},disarm(){c=!1,process.off("SIGINT",y),process.off("SIGTERM",y)},fail(f){throw h(),f}}}R();D();import Dt from"semver";R();D();async function Ft(e){let{bump:t,preid:n}=e;if(!t){if(e.yes||!z())throw new l(r("bumpRequired"));let i=n?"pre":await _(r("chooseReleaseKind"),[{value:"formal",label:r("releaseKindFormal")},{value:"pre",label:r("releaseKindPre")}]);t=await Ue(r("chooseBump"),i==="pre"?["prerelease","prepatch","preminor","premajor"]:["patch","minor","major"])}if(!t.startsWith("pre")||n||!["prerelease","prepatch","preminor","premajor"].includes(t))return{bump:we(t,n),preid:n};if(e.yes||!z())return{bump:we(t,n),preid:n};while(!n){let i=await B(r("choosePreid"),"alpha");if(Dt.valid(`0.0.0-${i}.0`))n=i;else console.log(k(r("invalidPreid")))}return{bump:we(t,n),preid:n}}function $e(e){return Boolean(e)&&encodeURIComponent(e)===e&&!Dt.validRange(e)}async function de(e,t,n){if(e!==void 0||n||!z()){let i=e??t;if(!$e(i))throw new l(r("badDistTag"));return i}while(!0){let i=await B(r("chooseDistTag"),t);if($e(i))return i;console.log(k(r("badDistTag")))}}async function Nt(e,t,n){try{return await J(e,t)}catch(i){if(t||n||!z()||!(i instanceof l)||i.message!==r("noBaseline"))throw i}console.log(k(r("firstBaseline")));while(!0){let i=await B(r("chooseBaseline"));if(!i)continue;try{return await J(e,i)}catch(o){if(!(o instanceof l))throw o;console.log(k(o.message))}}}async function Fe(e){return se(e.root,Boolean(e.dryRun),()=>Rn(e))}async function Rn(e){let t=De.resolve(e.root),n=ie(t,e.versionsFile);if(e.packages)n.packagesDir=e.packages;if(e.messageFromCli&&e.commitMessage)n.commitMessage=e.commitMessage;if(e.branchFromCli)n.branch=e.branch||void 0;if(await L(t),n.branch){let u=await x("git",["symbolic-ref","--quiet","--short","HEAD"],t);if(u.code!==0||u.stdout.trim()!==n.branch)throw new l(r("wrongBranch",{branch:n.branch}))}let i=await Nt(t,e.baseline,e.yes),o=(await w("git",["rev-parse","HEAD"],t)).trim(),s=await Ce(t,n,i);if(!s.changed.length&&!s.dependents.length){let u=(await w("git",["rev-parse","--short",s.baseline],t)).trim();console.log(P(r("noPackagesSince",{rev:u}))),console.log(P(r("noVersionChangesNext")));return}if(z()&&!e.yes){console.log(S(r("wizardCandidates")));for(let u of[...s.changed,...s.dependents])console.log(` ${F(t,n.packagesDir,u).name}`)}let{bump:a,preid:c}=await Ft(e),g=[...s.changed,...s.dependents].map((u)=>{let v=F(t,n.packagesDir,u);return{folder:u,name:v.name,from:v.version,to:ot(v.version,a,c)}});if(e.dryRun)console.log(k(r("versionPreview")));for(let u of g)console.log(Ye(u.name,u.from,u.to));let d=e.preparePublish?await e.preparePublish({preid:c,config:n}):e.publishTag;if(e.dryRun){console.log(S(r("versionPreviewComplete")));return}if(!e.yes&&!await ze(r("confirmVersions")))throw new l(r("cancelledVersion"));if(await L(t),(await w("git",["rev-parse","HEAD"],t)).trim()!==o)throw new l(r("versionHeadChanged"));let h=X(t,n.packagesDir).map((u)=>`${n.packagesDir}/${u}/package.json`);if(Me(a))h.push(...g.map((u)=>`${n.packagesDir}/${u.folder}/CHANGELOG.md`));h.push("bun.lock","bun.lockb","package-lock.json","npm-shrinkwrap.json","yarn.lock","pnpm-lock.yaml",...n.commitFiles??[]);let y=await $t(t,h,o);try{try{for(let b of g)Fn(t,n.packagesDir,b.folder,b.to);if(Nn(t,n.packagesDir),Me(a))await Tn(t,n,g,i)}finally{y.checkpoint()}if(n.hooks.beforeCommit)await xe("sh",["-c",n.hooks.beforeCommit],t);let u=ct(n.commitMessage,a,c),v=g.map((b)=>`${b.name} ${b.from} => ${b.to}`).join(`
55
+ `}async function Re(e){let t=Z.resolve(e.root),n=Z.resolve(t,e.versionsFile);if(H.existsSync(n))throw new l(r("configExists",{file:e.versionsFile}));let i=rn(t),o=i[0]??"packages",s=e.yes?on(o):await an(e.versionsFile,i,o);if(!s.include.length)throw new l(r("includeRequired"));let a=sn(s);ye(a),H.mkdirSync(Z.dirname(n),{recursive:!0}),H.writeFileSync(n,a),console.log(X(r("initWrote",{file:e.versionsFile})))}function on(e){return{packagesDir:e,include:[`${e}/*/src`],exclude:[`${e}/*/src/**/__tests__/**`]}}async function an(e,t,n){if(!z())throw new l(r("yesRequired"));if(console.log(C(r("initIntro",{file:e}))),t.length)console.log(P(r("initFoundDirs",{dirs:t.join(", ")})));let i=await M(r("initPackagesDir"),n),o=bt(await M(r("initInclude"),`${i}/*/src`)),s=bt(await M(r("initExclude"),`${i}/*/src/**/__tests__/**`)),a=await M(r("initBranch")),c=await M(r("initBeforeCommit")),g=await M(r("initBeforePublish"));return{packagesDir:i,branch:a||void 0,beforeCommit:c||void 0,beforePublish:g||void 0,include:o,exclude:s}}function bt(e){return e.split(",").map((t)=>t.trim()).filter(Boolean)}function ge(e){return/^[A-Za-z0-9_./@*+-]+$/.test(e)?e:JSON.stringify(e)}function cn(e){return mn(e).flatMap((t)=>{let n=t.replace(/\/\*\*?$/,"");if(!n||n===t||n.includes("*"))return[];return H.existsSync(Z.join(e,n))?[n]:[]})}function ln(e){if(!H.existsSync(e))return[];let t=[];for(let n of H.readdirSync(e)){if(n.startsWith(".")||n==="node_modules")continue;let i=Z.join(e,n);if(!H.statSync(i).isDirectory())continue;if(gn(i))t.push(n)}return t}function gn(e){return H.readdirSync(e).some((t)=>H.existsSync(Z.join(e,t,"package.json")))}function mn(e){let t=Z.join(e,"package.json");if(!H.existsSync(t))return[];try{let n=JSON.parse(H.readFileSync(t,"utf8")),i=Array.isArray(n.workspaces)?n.workspaces:n.workspaces?.packages;return Array.isArray(i)?i.filter((o)=>typeof o==="string"):[]}catch{return[]}}import Te from"node:path";import vt from"semver";import re from"node:fs";import We from"node:path";import dn from"node:os";import{randomUUID as un}from"node:crypto";import{AsyncLocalStorage as hn}from"node:async_hooks";F();R();var Je=new hn;async function se(e,t,n){if(t)return n();e=We.resolve(e);let i=We.resolve(e,(await w("git",["rev-parse","--git-common-dir"],e)).trim()),o=We.join(i,"change-versions.lock");if(Je.getStore()?.has(o))return n();let s={pid:process.pid,host:dn.hostname(),token:un()},a;try{a=re.openSync(o,"wx",384)}catch(d){if(d.code!=="EEXIST")throw d;let h="";try{h=re.readFileSync(o,"utf8")}catch{}throw new l(r("repositoryLocked",{file:o,owner:h.trim()}))}let c=()=>{try{if(JSON.parse(re.readFileSync(o,"utf8")).token===s.token)re.unlinkSync(o)}catch{}};try{re.writeFileSync(a,JSON.stringify(s))}finally{re.closeSync(a)}let g=()=>{if(process.listenerCount("SIGINT")<=1&&process.listenerCount("SIGTERM")<=1)process.exit(1)};process.on("exit",c),process.on("SIGINT",g),process.on("SIGTERM",g);try{return await Je.run(new Set([...Je.getStore()??[],o]),n)}finally{process.off("SIGINT",g),process.off("SIGTERM",g),process.off("exit",c),c()}}R();function pn(e){if(/^[a-zA-Z0-9_./:@=+-]+$/.test(e))return e;return"'"+e.replaceAll("'","'\\''")+"'"}function q(e){let t=["change-versions","publish",`--dist-tag=${e.distTag}`,`--root=${e.root}`,`--versions-file=${e.versionsFile}`];if(e.commit)t.push(`--commit=${e.commit}`);if(e.packages)t.push(`--packages=${e.packages}`);return t.map(pn).join(" ")}F();F();function yt(e){let t=[];if(e.beforePublish)t.push({kind:"hook",name:"beforePublish",command:e.beforePublish});for(let n of mt(e.packages.filter((i)=>!i.private))){if(n.published&&n.distTagVersion===n.version)continue;let i=n.registry??"";t.push(n.published?{kind:"dist-tag",name:n.name,version:n.version,folder:n.folder,registry:i,tag:e.distTag}:{kind:"publish",name:n.name,version:n.version,folder:n.folder,registry:i,tag:e.distTag})}if(e.afterPublish)t.push({kind:"hook",name:"afterPublish",command:e.afterPublish});if(e.formal)for(let n of e.packages)t.push({kind:"tag",name:n.name,version:n.version,commit:e.commit});return t}async function zt(e){return se(e.root,Boolean(e.dryRun),()=>fn(e))}async function fn(e){console.log(e.dryRun?k(r("publishPreview")):C(r("publishPreparing")));let{root:t,startHead:n,config:i,release:o,entries:s,formal:a,registryOf:c,published:g,distTagVersions:d,steps:h}=await me(e),y=q({...e,root:t,commit:o.hash}),f={CHANGE_VERSIONS_PUBLISH_CONTEXT:JSON.stringify({schemaVersion:1,root:t,packagesDir:i.packagesDir,commit:o.hash,distTag:e.distTag,packages:h.flatMap((m)=>m.kind==="publish"?[{name:m.name,version:m.version,path:Te.join(i.packagesDir,m.folder)}]:[])})};for(let m of s)if(g.has(m.folder)&&d.get(m.folder)===m.to)console.log(P(r("alreadyTagged",{name:m.name,version:m.to,tag:e.distTag,registry:c.get(m.folder)||""})));if(console.log(r("publishPlanSummary",{uploads:h.filter((m)=>m.kind==="publish").length,retags:h.filter((m)=>m.kind==="dist-tag").length,tags:h.filter((m)=>m.kind==="tag").length})),e.dryRun){for(let m of h)console.log(`${k(r("plannedStep",{step:""}))}${kt(m)}`);if(a&&i.branch)console.log(k(r("plannedStep",{step:`git push origin ${s.map((m)=>`refs/tags/${m.name}@${m.to}`).join(" ")}`})));if(!a)console.log(P(r("noGitTag")));console.log(k(r("publishPreviewComplete"))),console.log(C(r("publishPreviewNext"))),console.log(B(y));return}console.log(P(r("publishResumeInfo"))),console.log(C(r("willPublish")));for(let m of s){if(g.has(m.folder)&&d.get(m.folder)===m.to)continue;let E=m.pkg.private?` ${P(r("privateMark"))}`:g.has(m.folder)?` ${P(r("distTagOnlyMark"))}`:"";console.log(` ${G(m.name)} ${X(m.to)}${E}`)}if(!e.yes&&!await le(r("confirmPublish")))throw new l(r("cancelledPublish"));let u=new Map(s.map((m)=>[m.folder,m.pkg.private?"summaryPrivate":g.has(m.folder)&&d.get(m.folder)===m.to?"summarySkipped":"summaryPending"])),v="beforePublish",b,A=!1,p=(m)=>m==="summaryPublished"||m==="summaryRetagged"?W:m==="summaryFailed"?pe:m==="summaryPending"?k:P,S=()=>{console.log((A?W:pe)(r(A?"publishComplete":"publishIncomplete"))),console.log(r("publishSummaryContext",{commit:o.hash,tag:e.distTag}));let m=new Map;for(let E of s){let T=u.get(E.folder);m.set(T,(m.get(T)??0)+1);let Ke=c.get(E.folder);console.log(` ${p(T)(r(T))}: ${G(E.name)}@${G(E.to)}${Ke?` — ${P(Ke)}`:""}`)}if(console.log([...m].map(([E,T])=>`${p(E)(r(E))}: ${G(String(T))}`).join(", ")),A)console.log(W(r("publishReady"))),console.log(P(r(a?i.branch?"gitTagsPushed":"gitTagsLocal":"noGitTag")));else{if(console.log(pe(r("publishFailedStage",{stage:v}))),v==="git tag / git push")console.log(k(r("publishTagRecovery")));console.log(k(r("publishRetryTitle"))),console.log(C(r("publishRetry"))),console.log(P(r("publishResumeInfo"))),console.log(B(y))}},N=()=>{if(b)u.set(b,"summaryFailed");S(),console.error(I(r("publishInterrupted"))),process.exit(1)};process.on("SIGINT",N),process.on("SIGTERM",N);try{await St(t,i.hooks.beforePublish,"beforePublish",f),await Ge(t,r("beforePublishDirty")),await xt(t,n);for(let m of h){if(m.kind!=="publish"&&m.kind!=="dist-tag")continue;console.log(C(r("executingStep",{step:kt(m)})));let E=Te.join(t,i.packagesDir,m.folder);v=`${m.kind==="publish"?"npm publish":"npm dist-tag add"} ${m.name}@${m.version}`,b=m.folder,await Tt(async()=>{if(m.kind==="dist-tag")await Pt(t,["dist-tag","add",`${m.name}@${m.version}`,m.tag,`--registry=${m.registry}`],m.registry);else await Pt(E,["publish",`--tag=${m.tag}`,`--registry=${m.registry}`],m.registry)}),u.set(m.folder,m.kind==="publish"?"summaryPublished":"summaryRetagged"),b=void 0}if(v="afterPublish",await St(t,i.hooks.afterPublish,"afterPublish",f),await Ge(t,r("afterPublishDirty")),await xt(t,n),v="git tag / git push",a)console.log(C(r("executingStep",{step:v}))),await wn(t,i.branch,s,o.hash);A=!0}catch(m){if(b)u.set(b,"summaryFailed");throw m}finally{process.off("SIGINT",N),process.off("SIGTERM",N),S()}}async function me(e,t=!1,n=!1){let i=Te.resolve(e.root);if(!t)await L(i);let o=(await w("git",["rev-parse","HEAD"],i)).trim(),s=ie(i,e.versionsFile);if(e.packages)s.packagesDir=e.packages;let a=await j(i,e.commit);if(!a?.lines.length)throw new l(r("noVersionCommit"));let c=J(i,s.packagesDir),g=new Map(c.map((p)=>[D(i,s.packagesDir,p).name,p])),d=a.lines.map((p)=>{let S=g.get(p.name);if(!S)throw new l(r("packageNotInDir",{dir:s.packagesDir,name:p.name}));let N=D(i,s.packagesDir,S);if(N.version!==p.to)throw new l(r("releaseVersionMismatch",{name:p.name,expected:p.to,actual:N.version,commit:a.hash}));return{...p,folder:S,pkg:N,deps:Se(N,g)}}),h=await x("git",["diff","--quiet",a.hash,"HEAD","--",...d.map((p)=>`${s.packagesDir}/${p.folder}`)],i);if(h.code===1&&!n)throw new l(r("releaseContentsChanged"));if(h.code!==0&&h.code!==1)throw new l(r("gitFailed",{detail:h.stderr.trim()}));if(!t)console.log(r("publishSummaryContext",{commit:a.hash,tag:e.distTag}));let y=ke(a.lines);if(y)await Rt(i,d,a.hash);let f=new Map;for(let p of d){if(p.pkg.private)continue;let S=await kn(i,p.pkg);if(f.set(p.folder,S),!t)console.log(r("checkingRegistry",{name:p.name,version:p.to,registry:S}))}let u=new Set;for(let p of d){let S=f.get(p.folder);if(!S||u.has(S))continue;if(u.add(S),!t)await vn(i,S)}let v=new Set,b=new Map;for(let p of d){if(p.pkg.private)continue;let S=f.get(p.folder);if(!S)continue;await Tt(async()=>{if(await bn(i,p.name,p.to,S)){v.add(p.folder);let N=await yn(i,p.name,e.distTag,S);b.set(p.folder,N)}})}let A=yt({packages:d.map((p)=>({name:p.name,version:p.to,folder:p.folder,private:p.pkg.private,deps:p.deps,registry:f.get(p.folder),published:v.has(p.folder),distTagVersion:b.get(p.folder)})),distTag:e.distTag,formal:y,commit:a.hash,beforePublish:s.hooks.beforePublish,afterPublish:s.hooks.afterPublish});return{root:i,startHead:o,config:s,release:a,entries:d,formal:y,registryOf:f,published:v,distTagVersions:b,steps:A}}function kt(e){if(e.kind==="hook")return`${P(`${e.name}:`)} ${B(e.command)}`;if(e.kind==="tag")return B(`git tag ${e.name}@${e.version} ${e.commit}`);if(e.kind==="dist-tag")return B(`npm dist-tag add ${e.name}@${e.version} ${e.tag} --registry=${e.registry}`);return B(`npm publish --tag=${e.tag} --registry=${e.registry} ${e.name}@${e.version}`)}async function j(e,t){if((await x("git",["rev-parse","--verify","HEAD"],e)).code!==0)return null;let i;if(t){let a=await x("git",["rev-parse","--verify","--end-of-options",`${t}^{commit}`],e);if(a.code!==0)throw new l(r("badReleaseCommit",{commit:t}));let c=a.stdout.trim();if((await x("git",["merge-base","--is-ancestor",c,"HEAD"],e)).code!==0)throw new l(r("badReleaseCommit",{commit:t}));i={hash:c,subject:(await w("git",["show","-s","--format=%s",c],e)).trim(),body:await w("git",["show","-s","--format=%b",c],e)}}else i=(await ce(e))[0];if(!i)return null;let o=xe(i.body);if(!o.length){if(t)throw new l(r("badReleaseCommit",{commit:t}));return null}if(new Set(o.map((a)=>a.name)).size!==o.length||o.some((a)=>!vt.valid(a.from)||!vt.valid(a.to)))throw new l(r("badReleaseCommit",{commit:i.hash}));let s=/^Change-Versions-Dist-Tag: (\S+)$/m.exec(i.body)?.[1];return{hash:i.hash,subject:i.subject,lines:o,distTag:s}}async function wn(e,t,n,i){await Rt(e,n,i);let o=n.map((a)=>`${a.name}@${a.to}`);for(let a of o){if((await x("git",["rev-parse","--verify",`refs/tags/${a}^{commit}`],e)).code===0)continue;await w("git",["tag",a,i],e)}if(!t)return;let s=await x("git",["push","origin",...o.map((a)=>`refs/tags/${a}`)],e);if(s.code!==0)throw new l(r("tagPushFailed",{detail:s.stderr.trim()}))}async function Rt(e,t,n){for(let i of t){let o=`${i.name}@${i.to}`,s=await x("git",["rev-parse","--verify",`refs/tags/${o}^{commit}`],e);if(s.code===0&&s.stdout.trim()!==n)throw new l(r("tagPointsElsewhere",{tag:o}))}}async function xt(e,t){if((await w("git",["rev-parse","HEAD"],e)).trim()!==t)throw new l(r("publishHeadChanged"))}async function Tt(e){let t="";for(let n=0;n<3;n++)try{await e();return}catch(i){if(i instanceof l&&i.auth)throw i;t=i instanceof Error?i.message:String(i)}throw new l(r("networkFailed",{detail:t}))}async function Pt(e,t,n){let i=await x("npm",t,e);if(i.code===0)return;let o=`${i.stderr}${i.stdout}`;if(process.stderr.write(i.stderr),ae(o))throw new l(r("notLoggedIn",{registry:n}),!0);throw Error(o.trim()||r("npmFailed"))}async function bn(e,t,n,i){let o=await x("npm",["view",`${t}@${n}`,"version","--json",`--registry=${i}`],e);if(o.code===0){let a;try{a=JSON.parse(o.stdout)}catch{}if(a===n||Array.isArray(a)&&a.length===1&&a[0]===n)return!0;throw Error(r("unexpectedRegistryVersion",{name:t,version:n,registry:i}))}let s=`${o.stderr}${o.stdout}`;if(ae(s))throw new l(r("notLoggedIn",{registry:i}),!0);if(Oe(o.stdout)||Oe(o.stderr))return!1;throw Error(s.trim()||r("npmViewFailed"))}async function yn(e,t,n,i){let o=await x("npm",["view",t,"dist-tags","--json",`--registry=${i}`],e);if(o.code!==0){let c=`${o.stderr}${o.stdout}`.trim();if(ae(c))throw new l(r("notLoggedIn",{registry:i}),!0);throw Error(c||r("npmViewFailed"))}let s;try{s=JSON.parse(o.stdout)}catch{}if(Array.isArray(s)&&s.length===1)s=s[0];if(!s||typeof s!=="object"||Array.isArray(s))throw Error(r("unexpectedRegistryTags",{name:t,tag:n,registry:i}));let a=Object.prototype.hasOwnProperty.call(s,n)?s[n]:void 0;if(a!==void 0&&typeof a!=="string")throw Error(r("unexpectedRegistryTags",{name:t,tag:n,registry:i}));return a}async function vn(e,t){let n=await x("npm",["whoami",`--registry=${t}`],e);if(n.code===0)return;let i=`${n.stderr}${n.stdout}`;if(ae(i))throw new l(r("notLoggedIn",{registry:t}),!0);throw new l(r("registryUnreachable",{registry:t,detail:i.trim()}))}async function kn(e,t){if(t.publishConfig?.registry)return t.publishConfig.registry.replace(/\/$/,"");if(t.name.startsWith("@")&&t.name.includes("/")){let i=t.name.slice(0,t.name.indexOf("/")),o=await Ct(e,`${i}:registry`);if(o&&o!=="undefined"&&o!=="null")return o.replace(/\/$/,"")}let n=await Ct(e,"registry");if(!n||n==="undefined"||n==="null")throw new l(r("noNpmRegistry",{detail:"npm config get registry: empty value"}));return n.replace(/\/$/,"")}async function Ct(e,t){let n=await x("npm",["config","get",t],e);if(n.code!==0){let i=n.stderr.trim()||n.stdout.trim()||`npm config get ${t}: exit ${n.code}`;throw new l(r("noNpmRegistry",{detail:i}))}return n.stdout.trim()}async function St(e,t,n,i){if(!t)return;console.log(C(r("executingStep",{step:`${n}: ${t}`})));try{await Pe("sh",["-c",t],e,i)}catch(o){let s=o instanceof Error?o.message:String(o);throw new l(r("hookFailed",{name:n,detail:s}))}}async function de(e,t,n){return t??(await j(Te.resolve(e),n))?.distTag??"latest"}import An from"node:path";import Ot from"semver";import te from"node:fs";import Fe from"node:path";import ee from"node:fs";import Y from"node:path";import{spawnSync as xn}from"node:child_process";F();R();function _e(e){try{let t=ee.lstatSync(e);if(!t.isFile())throw new l(r("unsafeCommitFile",{file:e}));return{bytes:ee.readFileSync(e),mode:t.mode&511}}catch(t){if(t.code==="ENOENT")return;throw t}}function Pn(e,t){return e===t||Boolean(e&&t&&e.mode===t.mode&&e.bytes.equals(t.bytes))}async function $t(e,t,n){let i=(await w("git",["rev-parse","HEAD"],e)).trim();if(n&&i!==n)throw new l(r("versionHeadChanged"));let o=new Map;for(let f of new Set(t)){let u=Y.resolve(e,f),v=Y.relative(e,u);if(!v||v.startsWith("..")||Y.isAbsolute(v)||/[*?\[\]\\]/.test(f)||v.split(Y.sep).includes(".git"))throw new l(r("unsafeCommitFile",{file:f}));for(let b=Y.dirname(u);b!==e;b=Y.dirname(b))if(ee.existsSync(b)&&ee.lstatSync(b).isSymbolicLink())throw new l(r("unsafeCommitFile",{file:f}));o.set(v,_e(u))}let s=new Map(o),a,c=!0,g=()=>{s=new Map([...o.keys()].map((f)=>[f,_e(Y.join(e,f))]))},d=(...f)=>xn("git",f,{cwd:e,encoding:"utf8"}),h=()=>{if(!c)return;c=!1,process.off("SIGINT",y),process.off("SIGTERM",y);let f=d("rev-parse","HEAD");if(f.status!==0||f.stdout.trim()!==i){console.error(I(r("versionHeadChanged")));return}if(a!==void 0&&d("write-tree").stdout.trim()===a)d("restore","--staged","--",...o.keys());for(let[u,v]of o){let b=Y.join(e,u);try{if(!Pn(_e(b),s.get(u)))continue;if(v)ee.writeFileSync(b,v.bytes),ee.chmodSync(b,v.mode);else ee.rmSync(b,{force:!0})}catch{}}},y=()=>{h(),console.error(I(r("versionRecovery"))),process.exit(1)};return process.on("SIGINT",y),process.on("SIGTERM",y),{checkpoint:g,async stage(){if((await w("git",["rev-parse","HEAD"],e)).trim()!==i)throw new l(r("versionHeadChanged"));if(await w("git",["diff","--cached","--name-only","-z"],e))throw new l(r("versionUnexpectedIndex"));let u=(await w("git",["diff","--name-only","-z"],e)).split("\x00").filter(Boolean),v=(await w("git",["ls-files","--others","--exclude-standard","-z"],e)).split("\x00").filter(Boolean),b=[...u,...v].filter((S)=>!o.has(S));if(b.length)throw new l(r("versionUnexpectedFiles",{files:b.join(", ")}));g();let A=[...new Set([...u,...v])];if(!A.length)throw new l(r("versionUnexpectedIndex"));if(await w("git",["add","--",...A],e),a=(await w("git",["write-tree"],e)).trim(),(await w("git",["diff","--cached","--name-only","-z"],e)).split("\x00").filter(Boolean).some((S)=>!o.has(S)))throw new l(r("versionUnexpectedIndex"))},async verifyCommit(){let f=(await w("git",["rev-parse","HEAD^"],e)).trim(),u=(await w("git",["rev-parse","HEAD^{tree}"],e)).trim();if(f!==i||u!==a)throw new l(r("versionHeadChanged"))},disarm(){c=!1,process.off("SIGINT",y),process.off("SIGTERM",y)},fail(f){throw h(),f}}}R();F();import Ft from"semver";R();F();async function Dt(e){let{bump:t,preid:n}=e;if(!t){if(e.yes||!z())throw new l(r("bumpRequired"));let i=n?"pre":await K(r("chooseReleaseKind"),[{value:"formal",label:r("releaseKindFormal")},{value:"pre",label:r("releaseKindPre")}]);t=await Ue(r("chooseBump"),i==="pre"?["prerelease","prepatch","preminor","premajor"]:["patch","minor","major"])}if(!t.startsWith("pre")||n||!["prerelease","prepatch","preminor","premajor"].includes(t))return{bump:be(t,n),preid:n};if(e.yes||!z())return{bump:be(t,n),preid:n};while(!n){let i=await M(r("choosePreid"),"alpha");if(Ft.valid(`0.0.0-${i}.0`))n=i;else console.log(k(r("invalidPreid")))}return{bump:be(t,n),preid:n}}function $e(e){return Boolean(e)&&encodeURIComponent(e)===e&&!Ft.validRange(e)}async function ue(e,t,n){if(e!==void 0||n||!z()){let i=e??t;if(!$e(i))throw new l(r("badDistTag"));return i}while(!0){let i=await M(r("chooseDistTag"),t);if($e(i))return i;console.log(k(r("badDistTag")))}}async function Nt(e,t,n){try{return await _(e,t)}catch(i){if(t||n||!z()||!(i instanceof l)||i.message!==r("noBaseline"))throw i}console.log(k(r("firstBaseline")));while(!0){let i=await M(r("chooseBaseline"));if(!i)continue;try{return await _(e,i)}catch(o){if(!(o instanceof l))throw o;console.log(k(o.message))}}}async function De(e){return se(e.root,Boolean(e.dryRun),()=>Tn(e))}async function Tn(e){let t=Fe.resolve(e.root),n=ie(t,e.versionsFile);if(e.packages)n.packagesDir=e.packages;if(e.messageFromCli&&e.commitMessage)n.commitMessage=e.commitMessage;if(e.branchFromCli)n.branch=e.branch||void 0;if(await L(t),n.branch){let u=await x("git",["symbolic-ref","--quiet","--short","HEAD"],t);if(u.code!==0||u.stdout.trim()!==n.branch)throw new l(r("wrongBranch",{branch:n.branch}))}let i=await Nt(t,e.baseline,e.yes),o=(await w("git",["rev-parse","HEAD"],t)).trim(),s=e.force?{baseline:i,changed:await Ht(t,n),dependents:[]}:await ze(t,n,i);if(!s.changed.length&&!s.dependents.length){let u=(await w("git",["rev-parse","--short",s.baseline],t)).trim();if(console.log(P(r("noPackagesSince",{rev:u}))),console.log(P(r("noVersionChangesNext"))),e.yes||!z()||!await j(t)||!await le(r("confirmForceVersion")))return;s.changed=await Ht(t,n)}if(z()&&!e.yes){console.log(C(r("wizardCandidates")));for(let u of[...s.changed,...s.dependents])console.log(` ${D(t,n.packagesDir,u).name}`)}let{bump:a,preid:c}=await Dt(e),g=[...s.changed,...s.dependents].map((u)=>{let v=D(t,n.packagesDir,u);return{folder:u,name:v.name,from:v.version,to:ot(v.version,a,c)}});if(e.dryRun)console.log(k(r("versionPreview")));for(let u of g)console.log(Ye(u.name,u.from,u.to));let d=e.preparePublish?await e.preparePublish({preid:c,config:n}):e.publishTag;if(e.dryRun){console.log(C(r("versionPreviewComplete")));return}if(!e.yes&&!await le(r("confirmVersions")))throw new l(r("cancelledVersion"));if(await L(t),(await w("git",["rev-parse","HEAD"],t)).trim()!==o)throw new l(r("versionHeadChanged"));let h=J(t,n.packagesDir).map((u)=>`${n.packagesDir}/${u}/package.json`);if(Me(a))h.push(...g.map((u)=>`${n.packagesDir}/${u.folder}/CHANGELOG.md`));h.push("bun.lock","bun.lockb","package-lock.json","npm-shrinkwrap.json","yarn.lock","pnpm-lock.yaml",...n.commitFiles??[]);let y=await $t(t,h,o);try{try{for(let b of g)Nn(t,n.packagesDir,b.folder,b.to);if(En(t,n.packagesDir),Me(a))await $n(t,n,g,i)}finally{y.checkpoint()}if(n.hooks.beforeCommit)await Pe("sh",["-c",n.hooks.beforeCommit],t);let u=ct(n.commitMessage,a,c),v=g.map((b)=>`${b.name} ${b.from} => ${b.to}`).join(`
56
56
  `)+(d?`
57
57
 
58
- Change-Versions-Dist-Tag: ${d}`:"");await y.stage(),await w("git",["commit","-m",u,"-m",v,"-m",ye],t),await y.verifyCommit(),y.disarm()}catch(u){await y.fail(u)}let f=(await w("git",["rev-parse","HEAD"],t)).trim();if(console.log(W(r("versionCommitted",{commit:f}))),console.log(k(r("versionTrailerHint"))),n.branch){let u=await x("git",["push","origin",n.branch],t);if(u.code!==0)throw new l(r("branchPushFailed",{branch:n.branch,detail:u.stderr.trim()}))}return console.log(S(r("versionPublishNext"))),console.log(A(V({...e,root:t,commit:f,distTag:d??c??"latest"}))),f}async function Tn(e,t,n,i){await Promise.resolve().then(() => Mt());let c=await ce(e),g=(await Le(e)).find((u)=>gt(u.subject))?.hash,d=It(c)??g??(i?await J(e,i):void 0),h=await $n(e,d),y=new Set(n.map((u)=>u.folder)),f=new Map(X(e,t.packagesDir).map((u)=>[F(e,t.packagesDir,u).name,u]));for(let u of n){let v=`${t.packagesDir}/${u.folder}/package.json`,b=new Set;for(let T of h)if(T.files.includes(v)&&await Dn(e,T.hash,v))b.add(T.hash);let I=jt(h,u.folder,t.packagesDir,t.include,t.exclude,b),p=F(e,t.packagesDir,u.folder),C=I.length?[]:Se(p,f).filter((T)=>y.has(T)).map((T)=>F(e,t.packagesDir,T)).map((T)=>({name:T.name,version:T.version})),N=await Bt({messages:I,version:u.to,previousTag:`${u.name}@${u.from}`,currentTag:`${u.name}@${u.to}`,dependencies:C}),m=De.join(e,t.packagesDir,u.folder,"CHANGELOG.md"),E=te.existsSync(m)?te.readFileSync(m,"utf8"):"";te.writeFileSync(m,E?`${N}
59
- ${E}`:N)}}async function $n(e,t){let n=t?["rev-list","--reverse",`${t}..HEAD`]:["rev-list","--reverse","HEAD"],i=(await w("git",n,e)).split(`
58
+ Change-Versions-Dist-Tag: ${d}`:"");await y.stage(),await w("git",["commit","-m",u,"-m",v,"-m",ve],t),await y.verifyCommit(),y.disarm()}catch(u){await y.fail(u)}let f=(await w("git",["rev-parse","HEAD"],t)).trim();if(console.log(W(r("versionCommitted",{commit:f}))),console.log(k(r("versionTrailerHint"))),n.branch){let u=await x("git",["push","origin",n.branch],t);if(u.code!==0)throw new l(r("branchPushFailed",{branch:n.branch,detail:u.stderr.trim()}))}return console.log(C(r("versionPublishNext"))),console.log(B(q({...e,root:t,commit:f,distTag:d??c??"latest"}))),f}async function Ht(e,t){let n=await j(e);if(!n)throw new l(r("noVersionCommit"));let i=J(e,t.packagesDir).map((s)=>({folder:s,...D(e,t.packagesDir,s)})),o=new Map(i.map((s)=>[s.name,s]));return console.log(k(r("forcePreviousBatch",{commit:n.hash}))),n.lines.map((s)=>{let a=o.get(s.name);if(!a)throw new l(r("packageNotInDir",{dir:t.packagesDir,name:s.name}));if(a.version!==s.to)throw new l(r("releaseVersionMismatch",{name:s.name,expected:s.to,actual:a.version,commit:n.hash}));if(!a.private){for(let c of Object.keys(a.dependencies??{}))if(o.get(c)?.private)throw new l(r("publicDependsOnPrivate",{name:a.name,dep:c}))}return a.folder})}async function $n(e,t,n,i){await Promise.resolve().then(() => Mt());let c=await ce(e),g=(await Ve(e)).find((u)=>gt(u.subject))?.hash,d=At(c)??g??(i?await _(e,i):void 0),h=await Fn(e,d),y=new Set(n.map((u)=>u.folder)),f=new Map(J(e,t.packagesDir).map((u)=>[D(e,t.packagesDir,u).name,u]));for(let u of n){let v=`${t.packagesDir}/${u.folder}/package.json`,b=new Set;for(let T of h)if(T.files.includes(v)&&await Dn(e,T.hash,v))b.add(T.hash);let A=It(h,u.folder,t.packagesDir,t.include,t.exclude,b),p=D(e,t.packagesDir,u.folder),S=A.length?[]:Se(p,f).filter((T)=>y.has(T)).map((T)=>D(e,t.packagesDir,T)).map((T)=>({name:T.name,version:T.version})),N=await jt({messages:A,version:u.to,previousTag:`${u.name}@${u.from}`,currentTag:`${u.name}@${u.to}`,dependencies:S}),m=Fe.join(e,t.packagesDir,u.folder,"CHANGELOG.md"),E=te.existsSync(m)?te.readFileSync(m,"utf8"):"";te.writeFileSync(m,E?`${N}
59
+ ${E}`:N)}}async function Fn(e,t){let n=t?["rev-list","--reverse",`${t}..HEAD`]:["rev-list","--reverse","HEAD"],i=(await w("git",n,e)).split(`
60
60
  `).filter(Boolean),o=[];for(let s of i){let a=await w("git",["log","-1","--format=%B",s],e),c=await x("git",["diff-tree","--no-commit-id","--name-only","-r","--root",s],e);o.push({hash:s,body:a,files:c.code===0?c.stdout.split(`
61
- `).filter(Boolean):[]})}return o}async function Dn(e,t,n){return!await Ve(e,`${t}^`,t,n)}function Fn(e,t,n,i){let o=De.join(e,t,n,"package.json"),s=te.readFileSync(o,"utf8"),a=JSON.parse(s);if(typeof a.version!=="string")throw new l(r("missingVersionField",{folder:n}));a.version=i;let c=/\n([\t ]+)"/.exec(s)?.[1]??" ";te.writeFileSync(o,JSON.stringify(a,null,c)+`
62
- `)}function Nn(e,t){let n=X(e,t),i=new Map(n.map((o)=>[F(e,t,o).name,F(e,t,o)]));for(let o of n){let s=De.join(e,t,o,"package.json"),a=te.readFileSync(s,"utf8"),c=JSON.parse(a),g=!1;for(let d of["dependencies","devDependencies"])for(let h of Object.keys(c[d]??{})){let y=i.get(h);if(!y)continue;let f=`^${y.version}`;if(c[d][h]!==f)c[d][h]=f,g=!0}if(g){let d=/\n([\t ]+)"/.exec(a)?.[1]??" ";te.writeFileSync(s,JSON.stringify(c,null,d)+`
61
+ `).filter(Boolean):[]})}return o}async function Dn(e,t,n){return!await Le(e,`${t}^`,t,n)}function Nn(e,t,n,i){let o=Fe.join(e,t,n,"package.json"),s=te.readFileSync(o,"utf8"),a=JSON.parse(s);if(typeof a.version!=="string")throw new l(r("missingVersionField",{folder:n}));a.version=i;let c=/\n([\t ]+)"/.exec(s)?.[1]??" ";te.writeFileSync(o,JSON.stringify(a,null,c)+`
62
+ `)}function En(e,t){let n=J(e,t),i=new Map(n.map((o)=>[D(e,t,o).name,D(e,t,o)]));for(let o of n){let s=Fe.join(e,t,o,"package.json"),a=te.readFileSync(s,"utf8"),c=JSON.parse(a),g=!1;for(let d of["dependencies","devDependencies"])for(let h of Object.keys(c[d]??{})){let y=i.get(h);if(!y)continue;let f=`^${y.version}`;if(c[d][h]!==f)c[d][h]=f,g=!0}if(g){let d=/\n([\t ]+)"/.exec(a)?.[1]??" ";te.writeFileSync(s,JSON.stringify(c,null,d)+`
63
63
  `)}}}async function Ne(e){let t=[],n=new Map,i;if(!e.formal)return{entries:t,remoteError:i};if(e.config.branch){let o=e.entries.flatMap((a)=>[`refs/tags/${a.name}@${a.to}`,`refs/tags/${a.name}@${a.to}^{}`]),s=await x("git",["ls-remote","--tags","origin",...o],e.root);if(s.code!==0)i=s.stderr.trim()||s.stdout.trim()||`git ls-remote: exit ${s.code}`;else for(let a of s.stdout.trim().split(`
64
- `).filter(Boolean)){let[c,g]=a.split(/\s+/);n.set(g,c)}}for(let o of e.entries){let s=`${o.name}@${o.to}`,a=await x("git",["rev-parse","--verify",`refs/tags/${s}^{commit}`],e.root),c=n.get(`refs/tags/${s}^{}`)??n.get(`refs/tags/${s}`);t.push({tag:s,localReady:a.code===0&&a.stdout.trim()===e.release.hash,remoteReady:!e.config.branch||!i&&c===e.release.hash})}return{entries:t,remoteError:i}}D();R();D();R();import En from"node:path";R();async function Y(e){let t=En.resolve(e.root);if(await w("git",["rev-parse","--show-toplevel"],t),!await q(t,e.commit)){console.log(P(r("statusNoBatch")));return}console.log(S(r("statusHeading")));let n=await ge(e,!0);console.log(r("publishSummaryContext",{commit:n.release.hash,tag:e.distTag}));let i=!0;for(let a of n.entries){let c=a.pkg.private?"summaryPrivate":!n.published.has(a.folder)?"statusUpload":n.distTagVersions.get(a.folder)!==a.to?"statusRetag":"summarySkipped";if(c==="statusUpload"||c==="statusRetag")i=!1;console.log(` ${(c==="statusUpload"||c==="statusRetag"?k:P)(r(c))}: ${a.name}@${a.to}`)}let o=await Ne(n);if(o.remoteError)i=!1,console.log(k(r("statusRemoteUnknown",{detail:o.remoteError})));for(let{tag:a,localReady:c,remoteReady:g}of o.entries){if(!c||!g)i=!1;console.log((c&&g?P:k)(r("statusGitTag",{tag:a,local:c?r("statusReady"):r("statusMissing"),remote:n.config.branch?g?r("statusReady"):r("statusMissing"):r("statusNotConfigured")})))}let s=await x("git",["status","--porcelain"],t);if(s.code!==0||s.stdout.trim())i=!1,console.log(k(r("dirtyTree")));console.log((i?W:k)(r(i?"statusExternalReady":"statusPending"))),console.log(P(r("statusHooksUnknown"))),console.log(A(V({...e,root:t,commit:n.release.hash})))}async function oe(e){let t=await q(e.root,e.commit),n={...e,commit:t?.hash??e.commit};while(!0)try{await zt(n);return}catch(i){if(i instanceof G||i instanceof l&&i.message===r("cancelledPublish")||e.yes||e.dryRun||!z()||!n.commit)throw i;console.error(j(i instanceof Error?i.message:String(i)));while(!0){let o;try{o=await _(r("recoveryAction"),[{value:"retry",label:r("actionRetry")},{value:"status",label:r("actionStatus")},{value:"exit",label:r("actionExitFailed")}])}catch(s){if(s instanceof G)throw i;throw s}if(o==="exit")throw i;if(o==="retry")break;try{await Y(n)}catch(s){console.error(j(s instanceof Error?s.message:String(s)))}}}}async function Ee(e){let t=An.resolve(e.root);if(e.distTag!==void 0&&!$e(e.distTag))throw new l(r("badDistTag"));await se(t,Boolean(e.dryRun),async()=>{if(e.resume||e.commit){if(e.bump||e.baseline||e.branchFromCli||e.messageFromCli)throw new l(r("releaseResumeOptions"));let s=await q(t,e.commit);if(!s)throw new l(r("noVersionCommit"));let a=s?Ht.prerelease(s.lines[0].to)?.[0]:void 0,c=e.distTag??e.preid??s?.distTag??String(a??"latest");await oe({...e,root:t,commit:s?.hash??e.commit,distTag:await de(e.distTag,c,e.yes)});return}await L(t);let n=await q(t);if(n&&await J(t,e.baseline)===n.hash){let s=n.distTag??String(Ht.prerelease(n.lines[0].to)?.[0]??"latest"),a=await ge({...e,root:t,distTag:s},!0,!0),c=await Ne(a);if(c.remoteError)throw new l(r("statusRemoteUnknown",{detail:c.remoteError}));if(a.steps.some((g)=>g.kind==="publish"||g.kind==="dist-tag")||c.entries.some((g)=>!g.localReady||!g.remoteReady)){let g=r("releasePending",{command:V({...e,root:t,distTag:s,commit:n.hash})});if(e.yes||!z())throw new l(g);console.log(k(g));while(!0){let d=await _(r("pendingAction"),[{value:"resume",label:r("actionResume")},{value:"status",label:r("actionStatus")},{value:"exit",label:r("actionExit")}]);if(d==="exit")return;if(d==="status"){try{await Y({...e,root:t,commit:n.hash,distTag:s})}catch(h){console.error(j(h instanceof Error?h.message:String(h)))}continue}await oe({...e,root:t,commit:n.hash,distTag:s});return}}}console.log(S(r("releaseVersionStage")));let i=e.distTag??e.preid??"latest",o=await Fe({...e,root:t,preparePublish:async({preid:s,config:a})=>{if(i=await de(e.distTag,s??"latest",e.yes),z()&&!e.yes){console.log(S(r("wizardExecutionPlan"))),console.log(r("wizardPlanContext",{tag:i,branch:a.branch??r("statusNotConfigured")}));for(let[c,g]of Object.entries(a.hooks))if(g)console.log(` ${c}: ${g}`)}return i}});if(e.dryRun){console.log(k(r("releasePreviewComplete")));return}if(!o)return;console.log(S(r("releasePublishStage"))),console.log(A(V({...e,root:t,distTag:i,commit:o}))),await oe({...e,root:t,distTag:i,commit:o})})}R();import In from"node:fs";import jn from"node:path";R();async function Ot(e=process.cwd()){let t={root:e,versionsFile:"change-versions.yml",branchFromCli:!1,messageFromCli:!1};while(!0){let n=In.existsSync(jn.resolve(e,t.versionsFile));if(!n)console.log(k(r("wizardNeedsConfig")));let i=n?[{value:"release",label:r("actionNewRelease")},{value:"resume",label:r("actionResume")},{value:"status",label:r("actionStatus")},{value:"exit",label:r("actionExit")}]:[{value:"init",label:r("actionInit")},{value:"exit",label:r("actionExit")}],o=await _(r("wizardAction"),i);if(o==="exit")return;if(o==="init"){await Re(t);continue}if(o==="status"){await Y({...t,distTag:await me(e)});continue}await Ee({...t,resume:o==="resume"});return}}D();var U=new Bn;U.name("change-versions").version(JSON.parse(Mn(new URL("../package.json",import.meta.url),"utf8")).version).description(r("cliDescription"));function ue(e){return e.option("--root <dir>",r("optRoot"),process.cwd()).option("--versions-file <file>",r("optVersionsFile"),"change-versions.yml").option("--packages <dir>",r("optPackages"))}U.command("init").description(r("cmdInit")).option("--root <dir>",r("optRoot"),process.cwd()).option("--versions-file <file>",r("optVersionsFile"),"change-versions.yml").option("--yes",r("optYesInit")).action(async function(){let e=this.opts();await Re(e)});ue(U.command("changed").description(r("cmdChanged"))).option("--baseline <rev>",r("optBaseline")).action(async function(){let e=this.opts();await pt(e)});ue(U.command("version").description(r("cmdVersion")).argument("[bump]",r("argBump"))).option("--preid <id>",r("optPreid")).option("--yes",r("optYes")).option("--dry-run",r("optDryRunVersion")).option("--baseline <rev>",r("optBaseline")).option("--branch <name>",r("optBranch")).option("--commit-message <template>",r("optCommitMessage")).action(async function(e){let t=this.opts();await Fe({...t,bump:e,branchFromCli:this.getOptionValueSource("branch")==="cli",messageFromCli:this.getOptionValueSource("commitMessage")==="cli"})});ue(U.command("publish").description(r("cmdPublish"))).option("--commit <rev>",r("optReleaseCommit")).option("--dist-tag <tag>",r("optDistTag")).option("--yes",r("optYes")).option("--dry-run",r("optDryRunPublish")).action(async function(){let e=this.opts();await oe({...e,distTag:await de(e.distTag,await me(e.root,e.distTag,e.commit),e.yes)})});ue(U.command("status").description(r("cmdStatus"))).option("--commit <rev>",r("optReleaseCommit")).option("--dist-tag <tag>",r("optDistTag")).action(async function(){let e=this.opts();await Y({...e,distTag:await me(e.root,e.distTag,e.commit)})});ue(U.command("release").description(r("cmdRelease")).argument("[bump]",r("argBump"))).option("--preid <id>",r("optPreid")).option("--dist-tag <tag>",r("optDistTag")).option("--yes",r("optYes")).option("--dry-run",r("optDryRunRelease")).option("--baseline <rev>",r("optBaseline")).option("--branch <name>",r("optBranch")).option("--commit-message <template>",r("optCommitMessage")).option("--resume",r("optResume")).option("--commit <rev>",r("optReleaseCommit")).action(async function(e){await Ee({...this.opts(),bump:e,branchFromCli:this.getOptionValueSource("branch")==="cli",messageFromCli:this.getOptionValueSource("commitMessage")==="cli"})});async function Hn(){if(process.argv.length<=2){if(z())await Ot();else U.outputHelp();return}await U.parseAsync(process.argv)}Hn().catch((e)=>{if(e instanceof G){console.log(P(e.message));return}if(e instanceof l)console.error(j(e.message));else console.error(e);process.exit(1)});
64
+ `).filter(Boolean)){let[c,g]=a.split(/\s+/);n.set(g,c)}}for(let o of e.entries){let s=`${o.name}@${o.to}`,a=await x("git",["rev-parse","--verify",`refs/tags/${s}^{commit}`],e.root),c=n.get(`refs/tags/${s}^{}`)??n.get(`refs/tags/${s}`);t.push({tag:s,localReady:a.code===0&&a.stdout.trim()===e.release.hash,remoteReady:!e.config.branch||!i&&c===e.release.hash})}return{entries:t,remoteError:i}}F();R();F();R();import Bn from"node:path";R();async function Q(e){let t=Bn.resolve(e.root);if(await w("git",["rev-parse","--show-toplevel"],t),!await j(t,e.commit)){console.log(P(r("statusNoBatch")));return}console.log(C(r("statusHeading")));let n=await me(e,!0);console.log(r("publishSummaryContext",{commit:n.release.hash,tag:e.distTag}));let i=!0;for(let a of n.entries){let c=a.pkg.private?"summaryPrivate":!n.published.has(a.folder)?"statusUpload":n.distTagVersions.get(a.folder)!==a.to?"statusRetag":"summarySkipped";if(c==="statusUpload"||c==="statusRetag")i=!1;console.log(` ${(c==="statusUpload"||c==="statusRetag"?k:P)(r(c))}: ${a.name}@${a.to}`)}let o=await Ne(n);if(o.remoteError)i=!1,console.log(k(r("statusRemoteUnknown",{detail:o.remoteError})));for(let{tag:a,localReady:c,remoteReady:g}of o.entries){if(!c||!g)i=!1;console.log((c&&g?P:k)(r("statusGitTag",{tag:a,local:c?r("statusReady"):r("statusMissing"),remote:n.config.branch?g?r("statusReady"):r("statusMissing"):r("statusNotConfigured")})))}let s=await x("git",["status","--porcelain"],t);if(s.code!==0||s.stdout.trim())i=!1,console.log(k(r("dirtyTree")));console.log((i?W:k)(r(i?"statusExternalReady":"statusPending"))),console.log(P(r("statusHooksUnknown"))),console.log(B(q({...e,root:t,commit:n.release.hash})))}async function oe(e){let t=await j(e.root,e.commit),n={...e,commit:t?.hash??e.commit};while(!0)try{await zt(n);return}catch(i){if(i instanceof V||i instanceof l&&i.message===r("cancelledPublish")||e.yes||e.dryRun||!z()||!n.commit)throw i;console.error(I(i instanceof Error?i.message:String(i)));while(!0){let o;try{o=await K(r("recoveryAction"),[{value:"retry",label:r("actionRetry")},{value:"status",label:r("actionStatus")},{value:"exit",label:r("actionExitFailed")}])}catch(s){if(s instanceof V)throw i;throw s}if(o==="exit")throw i;if(o==="retry")break;try{await Q(n)}catch(s){console.error(I(s instanceof Error?s.message:String(s)))}}}}async function Ee(e){let t=An.resolve(e.root);if(e.distTag!==void 0&&!$e(e.distTag))throw new l(r("badDistTag"));await se(t,Boolean(e.dryRun),async()=>{if(e.resume||e.commit){if(e.force||e.bump||e.baseline||e.branchFromCli||e.messageFromCli)throw new l(r("releaseResumeOptions"));let s=await j(t,e.commit);if(!s)throw new l(r("noVersionCommit"));let a=s?Ot.prerelease(s.lines[0].to)?.[0]:void 0,c=e.distTag??e.preid??s?.distTag??String(a??"latest");await oe({...e,root:t,commit:s?.hash??e.commit,distTag:await ue(e.distTag,c,e.yes)});return}await L(t);let n=await j(t);if(!e.force&&n&&await _(t,e.baseline)===n.hash){let s=n.distTag??String(Ot.prerelease(n.lines[0].to)?.[0]??"latest"),a=await me({...e,root:t,distTag:s},!0,!0),c=await Ne(a);if(c.remoteError)throw new l(r("statusRemoteUnknown",{detail:c.remoteError}));if(a.steps.some((g)=>g.kind==="publish"||g.kind==="dist-tag")||c.entries.some((g)=>!g.localReady||!g.remoteReady)){let g=r("releasePending",{command:q({...e,root:t,distTag:s,commit:n.hash})});if(e.yes||!z())throw new l(g);console.log(k(g));while(!0){let d=await K(r("pendingAction"),[{value:"resume",label:r("actionResume")},{value:"status",label:r("actionStatus")},{value:"exit",label:r("actionExit")},{value:"force",label:r("actionForceVersion")}]);if(d==="exit")return;if(d==="force"){e={...e,force:!0};break}if(d==="status"){try{await Q({...e,root:t,commit:n.hash,distTag:s})}catch(h){console.error(I(h instanceof Error?h.message:String(h)))}continue}await oe({...e,root:t,commit:n.hash,distTag:s});return}}}console.log(C(r("releaseVersionStage")));let i=e.distTag??e.preid??"latest",o=await De({...e,root:t,preparePublish:async({preid:s,config:a})=>{if(i=await ue(e.distTag,s??"latest",e.yes),z()&&!e.yes){console.log(C(r("wizardExecutionPlan"))),console.log(r("wizardPlanContext",{tag:i,branch:a.branch??r("statusNotConfigured")}));for(let[c,g]of Object.entries(a.hooks))if(g)console.log(` ${c}: ${g}`)}return i}});if(e.dryRun){console.log(k(r("releasePreviewComplete")));return}if(!o)return;console.log(C(r("releasePublishStage"))),console.log(B(q({...e,root:t,distTag:i,commit:o}))),await oe({...e,root:t,distTag:i,commit:o})})}R();import In from"node:fs";import jn from"node:path";R();async function Gt(e=process.cwd()){let t={root:e,versionsFile:"change-versions.yml",branchFromCli:!1,messageFromCli:!1};while(!0){let n=In.existsSync(jn.resolve(e,t.versionsFile));if(!n)console.log(k(r("wizardNeedsConfig")));let i=n?[{value:"release",label:r("actionNewRelease")},{value:"resume",label:r("actionResume")},{value:"status",label:r("actionStatus")},{value:"exit",label:r("actionExit")}]:[{value:"init",label:r("actionInit")},{value:"exit",label:r("actionExit")}],o=await K(r("wizardAction"),i);if(o==="exit")return;if(o==="init"){await Re(t);continue}if(o==="status"){await Q({...t,distTag:await de(e)});continue}await Ee({...t,resume:o==="resume"});return}}F();var U=new Mn;U.name("change-versions").version(JSON.parse(Hn(new URL("../package.json",import.meta.url),"utf8")).version).description(r("cliDescription"));function he(e){return e.option("--root <dir>",r("optRoot"),process.cwd()).option("--versions-file <file>",r("optVersionsFile"),"change-versions.yml").option("--packages <dir>",r("optPackages"))}U.command("init").description(r("cmdInit")).option("--root <dir>",r("optRoot"),process.cwd()).option("--versions-file <file>",r("optVersionsFile"),"change-versions.yml").option("--yes",r("optYesInit")).action(async function(){let e=this.opts();await Re(e)});he(U.command("changed").description(r("cmdChanged"))).option("--baseline <rev>",r("optBaseline")).action(async function(){let e=this.opts();await pt(e)});he(U.command("version").description(r("cmdVersion")).argument("[bump]",r("argBump"))).option("--force",r("optForceVersion")).option("--preid <id>",r("optPreid")).option("--yes",r("optYes")).option("--dry-run",r("optDryRunVersion")).option("--baseline <rev>",r("optBaseline")).option("--branch <name>",r("optBranch")).option("--commit-message <template>",r("optCommitMessage")).action(async function(e){let t=this.opts();await De({...t,bump:e,branchFromCli:this.getOptionValueSource("branch")==="cli",messageFromCli:this.getOptionValueSource("commitMessage")==="cli"})});he(U.command("publish").description(r("cmdPublish"))).option("--commit <rev>",r("optReleaseCommit")).option("--dist-tag <tag>",r("optDistTag")).option("--yes",r("optYes")).option("--dry-run",r("optDryRunPublish")).action(async function(){let e=this.opts();await oe({...e,distTag:await ue(e.distTag,await de(e.root,e.distTag,e.commit),e.yes)})});he(U.command("status").description(r("cmdStatus"))).option("--commit <rev>",r("optReleaseCommit")).option("--dist-tag <tag>",r("optDistTag")).action(async function(){let e=this.opts();await Q({...e,distTag:await de(e.root,e.distTag,e.commit)})});he(U.command("release").description(r("cmdRelease")).argument("[bump]",r("argBump"))).option("--force",r("optForceVersion")).option("--preid <id>",r("optPreid")).option("--dist-tag <tag>",r("optDistTag")).option("--yes",r("optYes")).option("--dry-run",r("optDryRunRelease")).option("--baseline <rev>",r("optBaseline")).option("--branch <name>",r("optBranch")).option("--commit-message <template>",r("optCommitMessage")).option("--resume",r("optResume")).option("--commit <rev>",r("optReleaseCommit")).action(async function(e){await Ee({...this.opts(),bump:e,branchFromCli:this.getOptionValueSource("branch")==="cli",messageFromCli:this.getOptionValueSource("commitMessage")==="cli"})});async function On(){if(process.argv.length<=2){if(z())await Gt();else U.outputHelp();return}await U.parseAsync(process.argv)}On().catch((e)=>{if(e instanceof V){console.log(P(e.message));return}if(e instanceof l)console.error(I(e.message));else console.error(e);process.exit(1)});
package/docs/commands.md CHANGED
@@ -7,7 +7,7 @@
7
7
  和 Lerna 差两处:
8
8
 
9
9
  - 非正式档位不写 CHANGELOG,也不打 git tag。`prerelease`、`prepatch`、`preminor`、`premajor` 需要预发布标识;交互时可补填,非交互或 `--yes` 时必须带 `--preid`。`patch` 再带 `--preid` 不接受。
10
- - 按需升版本。基线优先使用较新的旧式 `v<数字>` 提交,否则使用最近一条正文带 `Co-authored-by: change-versions <publish@change-versions.com>` 的提交,不是 `commitMessage`,也不是上一个 git tag。提交作者仍是执行命令的人。命中 `include` 且没有命中 `exclude` 的文件,或去掉 `devDependencies` 后仍有差异的 `package.json`,才让该包入选。入选包的依赖方一并升版。没有入选包就退出,不升任何版本。
10
+ - 按需升版本。基线优先使用较新的旧式 `v<数字>` 提交,否则使用最近一条正文带 `Co-authored-by: change-versions <publish@change-versions.com>` 的提交,不是 `commitMessage`,也不是上一个 git tag。提交作者仍是执行命令的人。命中 `include` 且没有命中 `exclude` 的文件,或去掉 `devDependencies` 后仍有差异的 `package.json`,才让该包入选。入选包的依赖方一并升版。没有入选包时默认退出;交互可选择仅对上一批包强制升版,或显式使用 `--force`。
11
11
 
12
12
  正式版(`patch`、`minor`、`major`)写各包 CHANGELOG,并把 workspace 依赖订正成 `^` 当前版本,然后提交。git tag 要等 `publish` 把非 private 包全部送到 registry,并且 `afterPublish` 成功,才打 `<name>@<version>`。tag 指向那条 version 提交。
13
13
 
@@ -34,7 +34,7 @@ change-versions publish
34
34
 
35
35
  仓库里还没有这条 `Co-authored-by` 的提交时,不把整段历史当成变更。加上 `--baseline`,值是 `git rev-parse` 能解析的 SHA 或 tag。它不写入配置。较新的旧式 `v<数字>` 提交也可覆盖较旧的工具提交,兼容混用旧流程或合并后标题保留版本号的历史。
36
36
 
37
- 没有需要发的包时,`changed` 和 `version` 退出 0,不改文件。
37
+ 没有需要发的包时,`changed` 退出 0;`version` 默认不改文件,交互时可选择强制升版。`version <bump> --force` / `release <bump> --force` 仅使用最近一次可识别的版本提交中的包名单,不追加其他变更包或依赖方,不全量发布;缺少历史批次、包缺失或当前版本与该批次不符时失败。`--force` 不可与 `--resume` / `--commit` 组合。
38
38
 
39
39
  `changed`、`version`、`publish`、`release` 在执行变更前都看 `git status --porcelain`。工作区不干净就退出 1。提示语看 `LC_ALL`、`LC_MESSAGES`、`LANG`:以 `zh` 开头用中文,否则用英文。
40
40
 
@@ -48,7 +48,7 @@ change-versions publish
48
48
 
49
49
  选择菜单使用数字;非法输入重新提问,不退出进程。文本问题按回车采用提示中的默认值,q 保留为取消指令。提问中的 q、Ctrl-C、EOF 会停止后续步骤并退出 0,已完成的阶段保留。发布运行期间的中断仍按失败处理。在发布失败后的恢复菜单退出或取消仍返回原失败状态,避免脚本误判成功。
50
50
 
51
- 上一批未完成时,交互式 release 提供查询状态、恢复发布或退出;非交互与 `--yes` 维持报错并输出恢复命令。发布失败后的菜单同样支持状态查询和重试,固定原 commit、root、配置、包目录与 dist-tag;重试重新查询 registry、跳过已上传版本,hooks 仍会执行。预览失败不会进入执行重试菜单。
51
+ 上一批未完成时,交互式 release 提供查询状态、恢复发布、仅对上一批强制升版或退出;非交互与 `--yes` 默认报错并输出恢复命令,显式 `--force` 时仅对上一批包生成新版本。发布失败后的菜单同样支持状态查询和重试,固定原 commit、root、配置、包目录与 dist-tag;重试重新查询 registry、跳过已上传版本,hooks 仍会执行。预览失败不会进入执行重试菜单。
52
52
 
53
53
  `--yes` 表示自动执行,不再补问缺少的档位、preid 或首次基线。CI 应传入必要参数,例如 `release prerelease --preid=alpha --yes`。确认计划后还会复查工作区与 HEAD;等待输入期间发生的外部改动会中止升版并保留。
54
54
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "change-versions",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "type": "module",
5
5
  "description": "Version and publish only the workspace packages that changed.",
6
6
  "bin": {