relizy 1.3.3 → 1.4.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -5,7 +5,7 @@ import process from 'node:process';
5
5
  import { fileURLToPath } from 'node:url';
6
6
  import { printBanner, logger } from '@maz-ui/node';
7
7
  import { Command } from 'commander';
8
- import { am as isInCI, an as getCIName, b as bump, c as changelog, g as publish, e as providerRelease, h as social, p as prComment, r as release } from './shared/relizy.BRFiG2GH.mjs';
8
+ import { aq as isInCI, ar as getCIName, b as bump, c as changelog, g as publish, e as providerRelease, h as social, p as prComment, r as release } from './shared/relizy.BbFf6ZTs.mjs';
9
9
  import 'node:child_process';
10
10
  import '@maz-ui/utils';
11
11
  import 'c12';
package/dist/index.d.mts CHANGED
@@ -60,6 +60,9 @@ declare function getDefaultConfig(): {
60
60
  slack: {
61
61
  enabled: boolean;
62
62
  onlyStable: boolean;
63
+ postMaxLength: number;
64
+ noAuthors: boolean;
65
+ noPackages: boolean;
63
66
  };
64
67
  };
65
68
  prComment: Required<PrCommentConfig>;
@@ -233,6 +236,16 @@ declare function buildChangelogBody({ commits, config, minify }: {
233
236
  config: ResolvedRelizyConfig;
234
237
  minify?: boolean;
235
238
  }): string;
239
+ /**
240
+ * Collect unique contributor names from a set of commits.
241
+ * Respects `config.noAuthors`, filters `[bot]` authors, and applies `config.excludeAuthors`.
242
+ * Returns plain formatted names (no emails, no GitHub handles) — useful for lightweight
243
+ * rendering contexts like Slack messages.
244
+ */
245
+ declare function collectContributorNames({ commits, config }: {
246
+ commits: GitCommit[];
247
+ config: ResolvedRelizyConfig;
248
+ }): string[];
236
249
  declare function buildContributors({ commits, config }: {
237
250
  commits: GitCommit[];
238
251
  config: ResolvedRelizyConfig;
@@ -268,6 +281,37 @@ declare function publishPackage({ pkg, config, packageManager, dryRun, }: {
268
281
  dryRun: boolean;
269
282
  }): Promise<void>;
270
283
 
284
+ /**
285
+ * A package entry as consumed by release-summary renderers (PR comments, Slack messages, etc.).
286
+ * Normalizes the three possible shapes of "which packages shipped and at what version":
287
+ * - `bumpedPackages` from a monorepo bump (has both `oldVersion` and `newVersion`)
288
+ * - `packages` in standalone CLI mode (only `version`, no transition)
289
+ * - a mixed case where a bumped package didn't produce a new version
290
+ */
291
+ interface PackageBumpEntry {
292
+ /** Package name (e.g. `@acme/ui`) */
293
+ name: string;
294
+ /** Version before the release — only set when a real transition happened */
295
+ oldVersion?: string;
296
+ /** Version after the release — only set when a real transition happened */
297
+ newVersion?: string;
298
+ /** Fallback version when there is no old→new transition (standalone mode, graduations) */
299
+ version: string;
300
+ /** True when `oldVersion` and `newVersion` are both set AND differ */
301
+ hasTransition: boolean;
302
+ }
303
+ /**
304
+ * Collect package release data in a renderer-agnostic shape.
305
+ * Shared by the PR-comment GFM table and the Slack mrkdwn list.
306
+ */
307
+ declare function collectPackageBumps({ bumpedPackages, packages, }: {
308
+ bumpedPackages?: BumpResultTruthy['bumpedPackages'];
309
+ packages?: Array<{
310
+ name: string;
311
+ version: string;
312
+ }>;
313
+ }): PackageBumpEntry[];
314
+
271
315
  interface PullRequestInfo {
272
316
  /**
273
317
  * PR/MR number
@@ -347,25 +391,46 @@ declare function getSlackToken(options: {
347
391
  socialCredentials?: SlackCredentials;
348
392
  tokenCredential?: string;
349
393
  }): string | null;
394
+ /**
395
+ * Get Slack Incoming Webhook URL from config or environment variables.
396
+ * Priority: social.slack.webhookUrl > RELIZY_SLACK_WEBHOOK_URL > SLACK_WEBHOOK_URL.
397
+ */
398
+ declare function getSlackWebhookUrl(options: {
399
+ socialWebhookUrl?: string;
400
+ }): string | null;
350
401
  /**
351
402
  * Format changelog for Slack (convert markdown to Slack's mrkdwn format)
352
403
  */
353
404
  declare function formatChangelogForSlack(changelog: string, maxLength?: number): string;
405
+ /**
406
+ * Render a list of bumped packages as a Slack mrkdwn bullet list.
407
+ * Each entry becomes `• \`name\`: \`old\` → \`new\`` when a transition is detected,
408
+ * otherwise falls back to `• \`name\`: \`version\``.
409
+ */
410
+ declare function formatPackagesForSlack(packages: PackageBumpEntry[]): string;
354
411
  /**
355
412
  * Format the Slack message using blocks
356
413
  */
357
- declare function formatSlackMessage({ projectName, version, changelog, releaseUrl, changelogUrl, template }: {
414
+ declare function formatSlackMessage({ projectName, version, changelog, releaseUrl, changelogUrl, template, contributors, packages, postMaxLength }: {
358
415
  template?: string;
359
416
  projectName: string;
360
417
  version: string;
361
418
  changelog: string;
362
419
  releaseUrl?: string;
363
420
  changelogUrl?: string;
421
+ contributors?: string[];
422
+ packages?: PackageBumpEntry[];
423
+ postMaxLength?: number;
364
424
  }): any[];
365
425
  /**
366
- * Post a release announcement to Slack
426
+ * Post a release announcement to Slack.
427
+ * Dispatches to Incoming Webhook (if `webhookUrl` is set) or Web API (`token` + `channel`).
428
+ * When both are provided, the webhook takes priority.
367
429
  */
368
- declare function postReleaseToSlack({ version, projectName, changelog, releaseUrl, changelogUrl, channel, token, template, dryRun, }: SlackOptions): Promise<_slack_web_api.ChatPostMessageResponse | undefined>;
430
+ declare function postReleaseToSlack({ version, projectName, changelog, releaseUrl, changelogUrl, channel, token, webhookUrl, template, contributors, packages, postMaxLength, dryRun, }: SlackOptions): Promise<{
431
+ ok: true;
432
+ transport: "webhook";
433
+ } | _slack_web_api.ChatPostMessageResponse | undefined>;
369
434
 
370
435
  /**
371
436
  * Extract a summary from changelog content
@@ -1254,7 +1319,7 @@ interface TwitterSocialConfig {
1254
1319
  /**
1255
1320
  * Custom message template
1256
1321
  * Available variables: {{projectName}}, {{newVersion}}, {{changelog}}, {{releaseUrl}}, {{changelogUrl}}
1257
- * @default '🚀 {{projectName}} {{newVersion}} is out!\n\n{{changelog}}\n\n{{releaseUrl}}\n{{changelogUrl}}'
1322
+ * @default '📣 {{projectName}} {{newVersion}} is out!\n\n{{changelog}}\n\n{{releaseUrl}}\n{{changelogUrl}}'
1258
1323
  */
1259
1324
  template?: string;
1260
1325
  /**
@@ -1269,8 +1334,10 @@ interface TwitterSocialConfig {
1269
1334
  }
1270
1335
  interface SlackCredentials {
1271
1336
  /**
1272
- * Slack Bot Token or User OAuth Token
1273
- * Required scopes: chat:write, chat:write.public (for public channels)
1337
+ * Slack Bot Token or User OAuth Token (starts with `xoxb-`).
1338
+ * Required scopes: chat:write (and chat:write.public for public channels without bot invite).
1339
+ * Env fallback: SLACK_TOKEN, RELIZY_SLACK_TOKEN.
1340
+ * Ignored when social.slack.webhookUrl is set (webhook takes priority).
1274
1341
  */
1275
1342
  token?: string;
1276
1343
  }
@@ -1287,18 +1354,43 @@ interface SlackSocialConfig {
1287
1354
  */
1288
1355
  onlyStable?: boolean;
1289
1356
  /**
1290
- * Slack channel ID or name (e.g., "#releases" or "C1234567890")
1357
+ * Slack channel ID or name (e.g., "#releases" or "C1234567890").
1358
+ * Required when using token-based authentication.
1359
+ * Ignored (with warning) when webhookUrl is set — the channel is baked into the webhook URL.
1360
+ */
1361
+ channel?: string;
1362
+ /**
1363
+ * Slack Incoming Webhook URL. When set, takes priority over token-based auth.
1364
+ * Env fallback: SLACK_WEBHOOK_URL, RELIZY_SLACK_WEBHOOK_URL.
1365
+ * See: https://api.slack.com/messaging/webhooks
1291
1366
  */
1292
- channel: string;
1367
+ webhookUrl?: string;
1293
1368
  /**
1294
1369
  * Custom message template
1295
- * Available variables: {{projectName}}, {{newVersion}}, {{changelog}}, {{releaseUrl}}, {{changelogUrl}}
1370
+ * Available variables: {{projectName}}, {{newVersion}}, {{changelog}}, {{releaseUrl}}, {{changelogUrl}}, {{contributors}}
1296
1371
  */
1297
1372
  template?: string;
1298
1373
  /**
1299
1374
  * Slack credentials (optional - falls back to environment variables)
1300
1375
  */
1301
1376
  credentials?: SlackCredentials;
1377
+ /**
1378
+ * Maximum length (in characters) of the changelog rendered inside the Slack message.
1379
+ * Slack's per-section-block limit is 3000; default 2500 leaves margin for emoji/formatting.
1380
+ * @default 2500
1381
+ */
1382
+ postMaxLength?: number;
1383
+ /**
1384
+ * Hide the contributors block in Slack messages.
1385
+ * If config.noAuthors is true globally, contributors are always hidden regardless of this setting.
1386
+ * @default false
1387
+ */
1388
+ noAuthors?: boolean;
1389
+ /**
1390
+ * Hide the packages block (list of bumped packages with their before → after versions).
1391
+ * @default false
1392
+ */
1393
+ noPackages?: boolean;
1302
1394
  }
1303
1395
  type AIProviderName = 'claude-code';
1304
1396
  interface ClaudeCodeProviderOptions {
@@ -1462,23 +1554,51 @@ interface SlackOptions {
1462
1554
  */
1463
1555
  changelogUrl?: string;
1464
1556
  /**
1465
- * Slack channel ID or name
1557
+ * Slack channel ID or name. Required when using token-based auth.
1466
1558
  */
1467
- channel: string;
1559
+ channel?: string;
1468
1560
  /**
1469
- * Slack token (required)
1561
+ * Slack Bot Token. Ignored if webhookUrl is set.
1470
1562
  */
1471
- token: string;
1563
+ token?: string;
1564
+ /**
1565
+ * Slack Incoming Webhook URL. Takes priority over token.
1566
+ */
1567
+ webhookUrl?: string;
1472
1568
  /**
1473
1569
  * Custom message template
1474
1570
  */
1475
1571
  template?: string;
1572
+ /**
1573
+ * Maximum chars of the changelog rendered in the message.
1574
+ * @default 2500
1575
+ */
1576
+ postMaxLength?: number;
1577
+ /**
1578
+ * Contributor names (plain strings, no email/handle). Empty array or undefined → no contributors block.
1579
+ */
1580
+ contributors?: string[];
1581
+ /**
1582
+ * Packages bumped in this release. Empty array or undefined → no packages block.
1583
+ */
1584
+ packages?: SlackPackageEntry[];
1476
1585
  /**
1477
1586
  * Run without side effects
1478
1587
  * @default false
1479
1588
  */
1480
1589
  dryRun?: boolean;
1481
1590
  }
1591
+ /**
1592
+ * A bumped-package entry in a Slack message (derived from PackageBumpEntry in src/core/packages.ts).
1593
+ * Duplicated here to avoid a core→types back-import; kept in sync by design.
1594
+ */
1595
+ interface SlackPackageEntry {
1596
+ name: string;
1597
+ oldVersion?: string;
1598
+ newVersion?: string;
1599
+ version: string;
1600
+ hasTransition: boolean;
1601
+ }
1482
1602
  interface TemplatesConfig {
1483
1603
  /**
1484
1604
  * Commit message template (title).
@@ -1523,7 +1643,7 @@ interface TemplatesConfig {
1523
1643
  /**
1524
1644
  * Twitter message template
1525
1645
  * Available variables: {{projectName}}, {{newVersion}}, {{changelog}}, {{releaseUrl}}, {{changelogUrl}}
1526
- * @default '🚀 {{projectName}} {{newVersion}} is out!\n\n{{changelog}}\n\n{{releaseUrl}}\n{{changelogUrl}}'
1646
+ * @default '📣 {{projectName}} {{newVersion}} is out!\n\n{{changelog}}\n\n{{releaseUrl}}\n{{changelogUrl}}'
1527
1647
  */
1528
1648
  twitterMessage?: string;
1529
1649
  /**
@@ -1754,5 +1874,5 @@ declare function socialSafetyCheck({ config }: {
1754
1874
  }): Promise<void>;
1755
1875
  declare function social(options?: Partial<SocialOptions>): Promise<SocialResult>;
1756
1876
 
1757
- export { NEW_PACKAGE_MARKER, PR_COMMENT_MARKER, buildChangelogBody, buildCommentBody, buildCompareLink, buildContributors, bump, capReleaseTypeForZeroMajor, changelog, checkGitStatusIfDirty, confirmBump, createCommitAndTags, createGitlabRelease, defineConfig, detectGitProvider, detectPackageManager, detectPullRequest, determinePublishTag, determineReleaseType, determineSemverChange, executeBuildCmd, executeFormatCmd, executeHook, expandPackagesToBumpWithDependents, extractChangelogSummary, extractVersionFromPackageTag, extractVersionFromTag, fetchGitTags, filterOutPrivatePackages, findGitHubPR, findGitLabMR, formatChangelogForSlack, formatSlackMessage, formatTweetMessage, generateChangelog, generateMarkDown, getAuthCommand, getBumpedIndependentPackages, getBumpedPackageIndependently, getCIName, getCanaryVersion, getCurrentGitBranch, getCurrentGitRef, getDefaultConfig, getDependentsOf, getFirstCommit, getGitStatus, getIndependentTag, getLastPackageTag, getLastRepoTag, getLastStableTag, getLastTag, getModifiedReleaseFilePatterns, getPackageCommits, getPackageDependencies, getPackageNewVersion, getPackages, getPackagesOrBumpedPackages, getPackagesToPublishInIndependentMode, getPackagesToPublishInSelectiveMode, getPreid, getReleaseUrl, getRootPackage, getShortCommitSha, getSlackToken, getTwitterCredentials, github, gitlab, hasLernaJson, isBumpedPackage, isChangedPreid, isGraduating, isGraduatingToStableBetweenVersion, isInCI, isPrerelease, isPrereleaseReleaseType, isStableReleaseType, isTagVersionCompatibleWithCurrent, loadRelizyConfig, mergeTypes, parseChangelogMarkdown, parseGitRemoteUrl, postPrComment, postReleaseToSlack, postReleaseToTwitter, prComment, providerRelease, providerReleaseSafetyCheck, publish, publishPackage, publishSafetyCheck, pushCommitAndTags, readPackageJson, readPackages, release, resolveTags, rollbackModifiedFiles, shouldFilterPrereleaseTags, social, socialSafetyCheck, topologicalSort, updateLernaVersion, writeChangelogToFile, writeVersion };
1758
- export type { AIConfig, AIPromptTarget, AIProviderName, AISocialConfig, AISystemPromptOverrides, AITargetConfig, BumpConfig, BumpOptions, BumpResult, BumpResultFalsy, BumpResultTruthy, ChangelogConfig, ChangelogOptions, ClaudeCodeProviderOptions, ConfigType, GitProvider, GitlabRelease, GitlabReleaseResponse, HookConfig, HookStep, HookType, MonorepoConfig, PackageBase, PackageManager, PostedRelease, PrCommentConfig, PrCommentMode, PrCommentOptions, PrCommentStatus, ProviderReleaseOptions, ProviderReleaseResult, PublishConfig, PublishOptions, PublishResponse, PullRequestInfo, ReadPackage, Reference, ReleaseConfig, ReleaseContext, ReleaseOptions, RelizyConfig, RepoConfig, ResolvedConfig, ResolvedRelizyConfig, ResolvedTags, ResolvedTwitterCredentials, RootPackage, SlackCredentials, SlackOptions, SlackSocialConfig, SocialConfig, SocialNetworkResult, SocialOptions, SocialResult, Step, TemplatesConfig, TokensConfig, TwitterCredentials, TwitterOptions, TwitterSocialConfig, VersionMode };
1877
+ export { NEW_PACKAGE_MARKER, PR_COMMENT_MARKER, buildChangelogBody, buildCommentBody, buildCompareLink, buildContributors, bump, capReleaseTypeForZeroMajor, changelog, checkGitStatusIfDirty, collectContributorNames, collectPackageBumps, confirmBump, createCommitAndTags, createGitlabRelease, defineConfig, detectGitProvider, detectPackageManager, detectPullRequest, determinePublishTag, determineReleaseType, determineSemverChange, executeBuildCmd, executeFormatCmd, executeHook, expandPackagesToBumpWithDependents, extractChangelogSummary, extractVersionFromPackageTag, extractVersionFromTag, fetchGitTags, filterOutPrivatePackages, findGitHubPR, findGitLabMR, formatChangelogForSlack, formatPackagesForSlack, formatSlackMessage, formatTweetMessage, generateChangelog, generateMarkDown, getAuthCommand, getBumpedIndependentPackages, getBumpedPackageIndependently, getCIName, getCanaryVersion, getCurrentGitBranch, getCurrentGitRef, getDefaultConfig, getDependentsOf, getFirstCommit, getGitStatus, getIndependentTag, getLastPackageTag, getLastRepoTag, getLastStableTag, getLastTag, getModifiedReleaseFilePatterns, getPackageCommits, getPackageDependencies, getPackageNewVersion, getPackages, getPackagesOrBumpedPackages, getPackagesToPublishInIndependentMode, getPackagesToPublishInSelectiveMode, getPreid, getReleaseUrl, getRootPackage, getShortCommitSha, getSlackToken, getSlackWebhookUrl, getTwitterCredentials, github, gitlab, hasLernaJson, isBumpedPackage, isChangedPreid, isGraduating, isGraduatingToStableBetweenVersion, isInCI, isPrerelease, isPrereleaseReleaseType, isStableReleaseType, isTagVersionCompatibleWithCurrent, loadRelizyConfig, mergeTypes, parseChangelogMarkdown, parseGitRemoteUrl, postPrComment, postReleaseToSlack, postReleaseToTwitter, prComment, providerRelease, providerReleaseSafetyCheck, publish, publishPackage, publishSafetyCheck, pushCommitAndTags, readPackageJson, readPackages, release, resolveTags, rollbackModifiedFiles, shouldFilterPrereleaseTags, social, socialSafetyCheck, topologicalSort, updateLernaVersion, writeChangelogToFile, writeVersion };
1878
+ export type { AIConfig, AIPromptTarget, AIProviderName, AISocialConfig, AISystemPromptOverrides, AITargetConfig, BumpConfig, BumpOptions, BumpResult, BumpResultFalsy, BumpResultTruthy, ChangelogConfig, ChangelogOptions, ClaudeCodeProviderOptions, ConfigType, GitProvider, GitlabRelease, GitlabReleaseResponse, HookConfig, HookStep, HookType, MonorepoConfig, PackageBase, PackageBumpEntry, PackageManager, PostedRelease, PrCommentConfig, PrCommentMode, PrCommentOptions, PrCommentStatus, ProviderReleaseOptions, ProviderReleaseResult, PublishConfig, PublishOptions, PublishResponse, PullRequestInfo, ReadPackage, Reference, ReleaseConfig, ReleaseContext, ReleaseOptions, RelizyConfig, RepoConfig, ResolvedConfig, ResolvedRelizyConfig, ResolvedTags, ResolvedTwitterCredentials, RootPackage, SlackCredentials, SlackOptions, SlackPackageEntry, SlackSocialConfig, SocialConfig, SocialNetworkResult, SocialOptions, SocialResult, Step, TemplatesConfig, TokensConfig, TwitterCredentials, TwitterOptions, TwitterSocialConfig, VersionMode };
package/dist/index.d.ts CHANGED
@@ -60,6 +60,9 @@ declare function getDefaultConfig(): {
60
60
  slack: {
61
61
  enabled: boolean;
62
62
  onlyStable: boolean;
63
+ postMaxLength: number;
64
+ noAuthors: boolean;
65
+ noPackages: boolean;
63
66
  };
64
67
  };
65
68
  prComment: Required<PrCommentConfig>;
@@ -233,6 +236,16 @@ declare function buildChangelogBody({ commits, config, minify }: {
233
236
  config: ResolvedRelizyConfig;
234
237
  minify?: boolean;
235
238
  }): string;
239
+ /**
240
+ * Collect unique contributor names from a set of commits.
241
+ * Respects `config.noAuthors`, filters `[bot]` authors, and applies `config.excludeAuthors`.
242
+ * Returns plain formatted names (no emails, no GitHub handles) — useful for lightweight
243
+ * rendering contexts like Slack messages.
244
+ */
245
+ declare function collectContributorNames({ commits, config }: {
246
+ commits: GitCommit[];
247
+ config: ResolvedRelizyConfig;
248
+ }): string[];
236
249
  declare function buildContributors({ commits, config }: {
237
250
  commits: GitCommit[];
238
251
  config: ResolvedRelizyConfig;
@@ -268,6 +281,37 @@ declare function publishPackage({ pkg, config, packageManager, dryRun, }: {
268
281
  dryRun: boolean;
269
282
  }): Promise<void>;
270
283
 
284
+ /**
285
+ * A package entry as consumed by release-summary renderers (PR comments, Slack messages, etc.).
286
+ * Normalizes the three possible shapes of "which packages shipped and at what version":
287
+ * - `bumpedPackages` from a monorepo bump (has both `oldVersion` and `newVersion`)
288
+ * - `packages` in standalone CLI mode (only `version`, no transition)
289
+ * - a mixed case where a bumped package didn't produce a new version
290
+ */
291
+ interface PackageBumpEntry {
292
+ /** Package name (e.g. `@acme/ui`) */
293
+ name: string;
294
+ /** Version before the release — only set when a real transition happened */
295
+ oldVersion?: string;
296
+ /** Version after the release — only set when a real transition happened */
297
+ newVersion?: string;
298
+ /** Fallback version when there is no old→new transition (standalone mode, graduations) */
299
+ version: string;
300
+ /** True when `oldVersion` and `newVersion` are both set AND differ */
301
+ hasTransition: boolean;
302
+ }
303
+ /**
304
+ * Collect package release data in a renderer-agnostic shape.
305
+ * Shared by the PR-comment GFM table and the Slack mrkdwn list.
306
+ */
307
+ declare function collectPackageBumps({ bumpedPackages, packages, }: {
308
+ bumpedPackages?: BumpResultTruthy['bumpedPackages'];
309
+ packages?: Array<{
310
+ name: string;
311
+ version: string;
312
+ }>;
313
+ }): PackageBumpEntry[];
314
+
271
315
  interface PullRequestInfo {
272
316
  /**
273
317
  * PR/MR number
@@ -347,25 +391,46 @@ declare function getSlackToken(options: {
347
391
  socialCredentials?: SlackCredentials;
348
392
  tokenCredential?: string;
349
393
  }): string | null;
394
+ /**
395
+ * Get Slack Incoming Webhook URL from config or environment variables.
396
+ * Priority: social.slack.webhookUrl > RELIZY_SLACK_WEBHOOK_URL > SLACK_WEBHOOK_URL.
397
+ */
398
+ declare function getSlackWebhookUrl(options: {
399
+ socialWebhookUrl?: string;
400
+ }): string | null;
350
401
  /**
351
402
  * Format changelog for Slack (convert markdown to Slack's mrkdwn format)
352
403
  */
353
404
  declare function formatChangelogForSlack(changelog: string, maxLength?: number): string;
405
+ /**
406
+ * Render a list of bumped packages as a Slack mrkdwn bullet list.
407
+ * Each entry becomes `• \`name\`: \`old\` → \`new\`` when a transition is detected,
408
+ * otherwise falls back to `• \`name\`: \`version\``.
409
+ */
410
+ declare function formatPackagesForSlack(packages: PackageBumpEntry[]): string;
354
411
  /**
355
412
  * Format the Slack message using blocks
356
413
  */
357
- declare function formatSlackMessage({ projectName, version, changelog, releaseUrl, changelogUrl, template }: {
414
+ declare function formatSlackMessage({ projectName, version, changelog, releaseUrl, changelogUrl, template, contributors, packages, postMaxLength }: {
358
415
  template?: string;
359
416
  projectName: string;
360
417
  version: string;
361
418
  changelog: string;
362
419
  releaseUrl?: string;
363
420
  changelogUrl?: string;
421
+ contributors?: string[];
422
+ packages?: PackageBumpEntry[];
423
+ postMaxLength?: number;
364
424
  }): any[];
365
425
  /**
366
- * Post a release announcement to Slack
426
+ * Post a release announcement to Slack.
427
+ * Dispatches to Incoming Webhook (if `webhookUrl` is set) or Web API (`token` + `channel`).
428
+ * When both are provided, the webhook takes priority.
367
429
  */
368
- declare function postReleaseToSlack({ version, projectName, changelog, releaseUrl, changelogUrl, channel, token, template, dryRun, }: SlackOptions): Promise<_slack_web_api.ChatPostMessageResponse | undefined>;
430
+ declare function postReleaseToSlack({ version, projectName, changelog, releaseUrl, changelogUrl, channel, token, webhookUrl, template, contributors, packages, postMaxLength, dryRun, }: SlackOptions): Promise<{
431
+ ok: true;
432
+ transport: "webhook";
433
+ } | _slack_web_api.ChatPostMessageResponse | undefined>;
369
434
 
370
435
  /**
371
436
  * Extract a summary from changelog content
@@ -1254,7 +1319,7 @@ interface TwitterSocialConfig {
1254
1319
  /**
1255
1320
  * Custom message template
1256
1321
  * Available variables: {{projectName}}, {{newVersion}}, {{changelog}}, {{releaseUrl}}, {{changelogUrl}}
1257
- * @default '🚀 {{projectName}} {{newVersion}} is out!\n\n{{changelog}}\n\n{{releaseUrl}}\n{{changelogUrl}}'
1322
+ * @default '📣 {{projectName}} {{newVersion}} is out!\n\n{{changelog}}\n\n{{releaseUrl}}\n{{changelogUrl}}'
1258
1323
  */
1259
1324
  template?: string;
1260
1325
  /**
@@ -1269,8 +1334,10 @@ interface TwitterSocialConfig {
1269
1334
  }
1270
1335
  interface SlackCredentials {
1271
1336
  /**
1272
- * Slack Bot Token or User OAuth Token
1273
- * Required scopes: chat:write, chat:write.public (for public channels)
1337
+ * Slack Bot Token or User OAuth Token (starts with `xoxb-`).
1338
+ * Required scopes: chat:write (and chat:write.public for public channels without bot invite).
1339
+ * Env fallback: SLACK_TOKEN, RELIZY_SLACK_TOKEN.
1340
+ * Ignored when social.slack.webhookUrl is set (webhook takes priority).
1274
1341
  */
1275
1342
  token?: string;
1276
1343
  }
@@ -1287,18 +1354,43 @@ interface SlackSocialConfig {
1287
1354
  */
1288
1355
  onlyStable?: boolean;
1289
1356
  /**
1290
- * Slack channel ID or name (e.g., "#releases" or "C1234567890")
1357
+ * Slack channel ID or name (e.g., "#releases" or "C1234567890").
1358
+ * Required when using token-based authentication.
1359
+ * Ignored (with warning) when webhookUrl is set — the channel is baked into the webhook URL.
1360
+ */
1361
+ channel?: string;
1362
+ /**
1363
+ * Slack Incoming Webhook URL. When set, takes priority over token-based auth.
1364
+ * Env fallback: SLACK_WEBHOOK_URL, RELIZY_SLACK_WEBHOOK_URL.
1365
+ * See: https://api.slack.com/messaging/webhooks
1291
1366
  */
1292
- channel: string;
1367
+ webhookUrl?: string;
1293
1368
  /**
1294
1369
  * Custom message template
1295
- * Available variables: {{projectName}}, {{newVersion}}, {{changelog}}, {{releaseUrl}}, {{changelogUrl}}
1370
+ * Available variables: {{projectName}}, {{newVersion}}, {{changelog}}, {{releaseUrl}}, {{changelogUrl}}, {{contributors}}
1296
1371
  */
1297
1372
  template?: string;
1298
1373
  /**
1299
1374
  * Slack credentials (optional - falls back to environment variables)
1300
1375
  */
1301
1376
  credentials?: SlackCredentials;
1377
+ /**
1378
+ * Maximum length (in characters) of the changelog rendered inside the Slack message.
1379
+ * Slack's per-section-block limit is 3000; default 2500 leaves margin for emoji/formatting.
1380
+ * @default 2500
1381
+ */
1382
+ postMaxLength?: number;
1383
+ /**
1384
+ * Hide the contributors block in Slack messages.
1385
+ * If config.noAuthors is true globally, contributors are always hidden regardless of this setting.
1386
+ * @default false
1387
+ */
1388
+ noAuthors?: boolean;
1389
+ /**
1390
+ * Hide the packages block (list of bumped packages with their before → after versions).
1391
+ * @default false
1392
+ */
1393
+ noPackages?: boolean;
1302
1394
  }
1303
1395
  type AIProviderName = 'claude-code';
1304
1396
  interface ClaudeCodeProviderOptions {
@@ -1462,23 +1554,51 @@ interface SlackOptions {
1462
1554
  */
1463
1555
  changelogUrl?: string;
1464
1556
  /**
1465
- * Slack channel ID or name
1557
+ * Slack channel ID or name. Required when using token-based auth.
1466
1558
  */
1467
- channel: string;
1559
+ channel?: string;
1468
1560
  /**
1469
- * Slack token (required)
1561
+ * Slack Bot Token. Ignored if webhookUrl is set.
1470
1562
  */
1471
- token: string;
1563
+ token?: string;
1564
+ /**
1565
+ * Slack Incoming Webhook URL. Takes priority over token.
1566
+ */
1567
+ webhookUrl?: string;
1472
1568
  /**
1473
1569
  * Custom message template
1474
1570
  */
1475
1571
  template?: string;
1572
+ /**
1573
+ * Maximum chars of the changelog rendered in the message.
1574
+ * @default 2500
1575
+ */
1576
+ postMaxLength?: number;
1577
+ /**
1578
+ * Contributor names (plain strings, no email/handle). Empty array or undefined → no contributors block.
1579
+ */
1580
+ contributors?: string[];
1581
+ /**
1582
+ * Packages bumped in this release. Empty array or undefined → no packages block.
1583
+ */
1584
+ packages?: SlackPackageEntry[];
1476
1585
  /**
1477
1586
  * Run without side effects
1478
1587
  * @default false
1479
1588
  */
1480
1589
  dryRun?: boolean;
1481
1590
  }
1591
+ /**
1592
+ * A bumped-package entry in a Slack message (derived from PackageBumpEntry in src/core/packages.ts).
1593
+ * Duplicated here to avoid a core→types back-import; kept in sync by design.
1594
+ */
1595
+ interface SlackPackageEntry {
1596
+ name: string;
1597
+ oldVersion?: string;
1598
+ newVersion?: string;
1599
+ version: string;
1600
+ hasTransition: boolean;
1601
+ }
1482
1602
  interface TemplatesConfig {
1483
1603
  /**
1484
1604
  * Commit message template (title).
@@ -1523,7 +1643,7 @@ interface TemplatesConfig {
1523
1643
  /**
1524
1644
  * Twitter message template
1525
1645
  * Available variables: {{projectName}}, {{newVersion}}, {{changelog}}, {{releaseUrl}}, {{changelogUrl}}
1526
- * @default '🚀 {{projectName}} {{newVersion}} is out!\n\n{{changelog}}\n\n{{releaseUrl}}\n{{changelogUrl}}'
1646
+ * @default '📣 {{projectName}} {{newVersion}} is out!\n\n{{changelog}}\n\n{{releaseUrl}}\n{{changelogUrl}}'
1527
1647
  */
1528
1648
  twitterMessage?: string;
1529
1649
  /**
@@ -1754,5 +1874,5 @@ declare function socialSafetyCheck({ config }: {
1754
1874
  }): Promise<void>;
1755
1875
  declare function social(options?: Partial<SocialOptions>): Promise<SocialResult>;
1756
1876
 
1757
- export { NEW_PACKAGE_MARKER, PR_COMMENT_MARKER, buildChangelogBody, buildCommentBody, buildCompareLink, buildContributors, bump, capReleaseTypeForZeroMajor, changelog, checkGitStatusIfDirty, confirmBump, createCommitAndTags, createGitlabRelease, defineConfig, detectGitProvider, detectPackageManager, detectPullRequest, determinePublishTag, determineReleaseType, determineSemverChange, executeBuildCmd, executeFormatCmd, executeHook, expandPackagesToBumpWithDependents, extractChangelogSummary, extractVersionFromPackageTag, extractVersionFromTag, fetchGitTags, filterOutPrivatePackages, findGitHubPR, findGitLabMR, formatChangelogForSlack, formatSlackMessage, formatTweetMessage, generateChangelog, generateMarkDown, getAuthCommand, getBumpedIndependentPackages, getBumpedPackageIndependently, getCIName, getCanaryVersion, getCurrentGitBranch, getCurrentGitRef, getDefaultConfig, getDependentsOf, getFirstCommit, getGitStatus, getIndependentTag, getLastPackageTag, getLastRepoTag, getLastStableTag, getLastTag, getModifiedReleaseFilePatterns, getPackageCommits, getPackageDependencies, getPackageNewVersion, getPackages, getPackagesOrBumpedPackages, getPackagesToPublishInIndependentMode, getPackagesToPublishInSelectiveMode, getPreid, getReleaseUrl, getRootPackage, getShortCommitSha, getSlackToken, getTwitterCredentials, github, gitlab, hasLernaJson, isBumpedPackage, isChangedPreid, isGraduating, isGraduatingToStableBetweenVersion, isInCI, isPrerelease, isPrereleaseReleaseType, isStableReleaseType, isTagVersionCompatibleWithCurrent, loadRelizyConfig, mergeTypes, parseChangelogMarkdown, parseGitRemoteUrl, postPrComment, postReleaseToSlack, postReleaseToTwitter, prComment, providerRelease, providerReleaseSafetyCheck, publish, publishPackage, publishSafetyCheck, pushCommitAndTags, readPackageJson, readPackages, release, resolveTags, rollbackModifiedFiles, shouldFilterPrereleaseTags, social, socialSafetyCheck, topologicalSort, updateLernaVersion, writeChangelogToFile, writeVersion };
1758
- export type { AIConfig, AIPromptTarget, AIProviderName, AISocialConfig, AISystemPromptOverrides, AITargetConfig, BumpConfig, BumpOptions, BumpResult, BumpResultFalsy, BumpResultTruthy, ChangelogConfig, ChangelogOptions, ClaudeCodeProviderOptions, ConfigType, GitProvider, GitlabRelease, GitlabReleaseResponse, HookConfig, HookStep, HookType, MonorepoConfig, PackageBase, PackageManager, PostedRelease, PrCommentConfig, PrCommentMode, PrCommentOptions, PrCommentStatus, ProviderReleaseOptions, ProviderReleaseResult, PublishConfig, PublishOptions, PublishResponse, PullRequestInfo, ReadPackage, Reference, ReleaseConfig, ReleaseContext, ReleaseOptions, RelizyConfig, RepoConfig, ResolvedConfig, ResolvedRelizyConfig, ResolvedTags, ResolvedTwitterCredentials, RootPackage, SlackCredentials, SlackOptions, SlackSocialConfig, SocialConfig, SocialNetworkResult, SocialOptions, SocialResult, Step, TemplatesConfig, TokensConfig, TwitterCredentials, TwitterOptions, TwitterSocialConfig, VersionMode };
1877
+ export { NEW_PACKAGE_MARKER, PR_COMMENT_MARKER, buildChangelogBody, buildCommentBody, buildCompareLink, buildContributors, bump, capReleaseTypeForZeroMajor, changelog, checkGitStatusIfDirty, collectContributorNames, collectPackageBumps, confirmBump, createCommitAndTags, createGitlabRelease, defineConfig, detectGitProvider, detectPackageManager, detectPullRequest, determinePublishTag, determineReleaseType, determineSemverChange, executeBuildCmd, executeFormatCmd, executeHook, expandPackagesToBumpWithDependents, extractChangelogSummary, extractVersionFromPackageTag, extractVersionFromTag, fetchGitTags, filterOutPrivatePackages, findGitHubPR, findGitLabMR, formatChangelogForSlack, formatPackagesForSlack, formatSlackMessage, formatTweetMessage, generateChangelog, generateMarkDown, getAuthCommand, getBumpedIndependentPackages, getBumpedPackageIndependently, getCIName, getCanaryVersion, getCurrentGitBranch, getCurrentGitRef, getDefaultConfig, getDependentsOf, getFirstCommit, getGitStatus, getIndependentTag, getLastPackageTag, getLastRepoTag, getLastStableTag, getLastTag, getModifiedReleaseFilePatterns, getPackageCommits, getPackageDependencies, getPackageNewVersion, getPackages, getPackagesOrBumpedPackages, getPackagesToPublishInIndependentMode, getPackagesToPublishInSelectiveMode, getPreid, getReleaseUrl, getRootPackage, getShortCommitSha, getSlackToken, getSlackWebhookUrl, getTwitterCredentials, github, gitlab, hasLernaJson, isBumpedPackage, isChangedPreid, isGraduating, isGraduatingToStableBetweenVersion, isInCI, isPrerelease, isPrereleaseReleaseType, isStableReleaseType, isTagVersionCompatibleWithCurrent, loadRelizyConfig, mergeTypes, parseChangelogMarkdown, parseGitRemoteUrl, postPrComment, postReleaseToSlack, postReleaseToTwitter, prComment, providerRelease, providerReleaseSafetyCheck, publish, publishPackage, publishSafetyCheck, pushCommitAndTags, readPackageJson, readPackages, release, resolveTags, rollbackModifiedFiles, shouldFilterPrereleaseTags, social, socialSafetyCheck, topologicalSort, updateLernaVersion, writeChangelogToFile, writeVersion };
1878
+ export type { AIConfig, AIPromptTarget, AIProviderName, AISocialConfig, AISystemPromptOverrides, AITargetConfig, BumpConfig, BumpOptions, BumpResult, BumpResultFalsy, BumpResultTruthy, ChangelogConfig, ChangelogOptions, ClaudeCodeProviderOptions, ConfigType, GitProvider, GitlabRelease, GitlabReleaseResponse, HookConfig, HookStep, HookType, MonorepoConfig, PackageBase, PackageBumpEntry, PackageManager, PostedRelease, PrCommentConfig, PrCommentMode, PrCommentOptions, PrCommentStatus, ProviderReleaseOptions, ProviderReleaseResult, PublishConfig, PublishOptions, PublishResponse, PullRequestInfo, ReadPackage, Reference, ReleaseConfig, ReleaseContext, ReleaseOptions, RelizyConfig, RepoConfig, ResolvedConfig, ResolvedRelizyConfig, ResolvedTags, ResolvedTwitterCredentials, RootPackage, SlackCredentials, SlackOptions, SlackPackageEntry, SlackSocialConfig, SocialConfig, SocialNetworkResult, SocialOptions, SocialResult, Step, TemplatesConfig, TokensConfig, TwitterCredentials, TwitterOptions, TwitterSocialConfig, VersionMode };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { ag as NEW_PACKAGE_MARKER, Z as PR_COMMENT_MARKER, M as buildChangelogBody, a as buildCommentBody, L as buildCompareLink, N as buildContributors, b as bump, au as capReleaseTypeForZeroMajor, c as changelog, v as checkGitStatusIfDirty, aI as confirmBump, B as createCommitAndTags, J as createGitlabRelease, k as defineConfig, y as detectGitProvider, Q as detectPackageManager, Y as detectPullRequest, R as determinePublishTag, aw as determineReleaseType, av as determineSemverChange, ap as executeBuildCmd, ao as executeFormatCmd, al as executeHook, q as expandPackagesToBumpWithDependents, a9 as extractChangelogSummary, aA as extractVersionFromPackageTag, aL as extractVersionFromTag, x as fetchGitTags, ar as filterOutPrivatePackages, W as findGitHubPR, X as findGitLabMR, a6 as formatChangelogForSlack, a7 as formatSlackMessage, aj as formatTweetMessage, i as generateChangelog, O as generateMarkDown, U as getAuthCommand, aJ as getBumpedIndependentPackages, aH as getBumpedPackageIndependently, an as getCIName, aM as getCanaryVersion, F as getCurrentGitBranch, G as getCurrentGitRef, j as getDefaultConfig, o as getDependentsOf, E as getFirstCommit, u as getGitStatus, ab as getIndependentTag, af as getLastPackageTag, ae as getLastRepoTag, ac as getLastStableTag, ad as getLastTag, A as getModifiedReleaseFilePatterns, a3 as getPackageCommits, n as getPackageDependencies, ay as getPackageNewVersion, a2 as getPackages, as as getPackagesOrBumpedPackages, T as getPackagesToPublishInIndependentMode, S as getPackagesToPublishInSelectiveMode, aF as getPreid, aa as getReleaseUrl, a0 as getRootPackage, H as getShortCommitSha, a5 as getSlackToken, ai as getTwitterCredentials, I as github, K as gitlab, a4 as hasLernaJson, aq as isBumpedPackage, aG as isChangedPreid, aE as isGraduating, at as isGraduatingToStableBetweenVersion, am as isInCI, aB as isPrerelease, aD as isPrereleaseReleaseType, aC as isStableReleaseType, aN as isTagVersionCompatibleWithCurrent, l as loadRelizyConfig, m as mergeTypes, P as parseChangelogMarkdown, z as parseGitRemoteUrl, _ as postPrComment, a8 as postReleaseToSlack, ak as postReleaseToTwitter, p as prComment, e as providerRelease, d as providerReleaseSafetyCheck, g as publish, V as publishPackage, f as publishSafetyCheck, C as pushCommitAndTags, $ as readPackageJson, a1 as readPackages, r as release, ah as resolveTags, D as rollbackModifiedFiles, aK as shouldFilterPrereleaseTags, h as social, s as socialSafetyCheck, t as topologicalSort, az as updateLernaVersion, w as writeChangelogToFile, ax as writeVersion } from './shared/relizy.BRFiG2GH.mjs';
1
+ export { ak as NEW_PACKAGE_MARKER, $ as PR_COMMENT_MARKER, M as buildChangelogBody, a as buildCommentBody, L as buildCompareLink, O as buildContributors, b as bump, ay as capReleaseTypeForZeroMajor, c as changelog, v as checkGitStatusIfDirty, N as collectContributorNames, X as collectPackageBumps, aM as confirmBump, B as createCommitAndTags, J as createGitlabRelease, k as defineConfig, y as detectGitProvider, R as detectPackageManager, _ as detectPullRequest, S as determinePublishTag, aA as determineReleaseType, az as determineSemverChange, at as executeBuildCmd, as as executeFormatCmd, ap as executeHook, q as expandPackagesToBumpWithDependents, ad as extractChangelogSummary, aE as extractVersionFromPackageTag, aP as extractVersionFromTag, x as fetchGitTags, av as filterOutPrivatePackages, Y as findGitHubPR, Z as findGitLabMR, a9 as formatChangelogForSlack, aa as formatPackagesForSlack, ab as formatSlackMessage, an as formatTweetMessage, i as generateChangelog, P as generateMarkDown, V as getAuthCommand, aN as getBumpedIndependentPackages, aL as getBumpedPackageIndependently, ar as getCIName, aQ as getCanaryVersion, F as getCurrentGitBranch, G as getCurrentGitRef, j as getDefaultConfig, o as getDependentsOf, E as getFirstCommit, u as getGitStatus, af as getIndependentTag, aj as getLastPackageTag, ai as getLastRepoTag, ag as getLastStableTag, ah as getLastTag, A as getModifiedReleaseFilePatterns, a5 as getPackageCommits, n as getPackageDependencies, aC as getPackageNewVersion, a4 as getPackages, aw as getPackagesOrBumpedPackages, U as getPackagesToPublishInIndependentMode, T as getPackagesToPublishInSelectiveMode, aJ as getPreid, ae as getReleaseUrl, a2 as getRootPackage, H as getShortCommitSha, a7 as getSlackToken, a8 as getSlackWebhookUrl, am as getTwitterCredentials, I as github, K as gitlab, a6 as hasLernaJson, au as isBumpedPackage, aK as isChangedPreid, aI as isGraduating, ax as isGraduatingToStableBetweenVersion, aq as isInCI, aF as isPrerelease, aH as isPrereleaseReleaseType, aG as isStableReleaseType, aR as isTagVersionCompatibleWithCurrent, l as loadRelizyConfig, m as mergeTypes, Q as parseChangelogMarkdown, z as parseGitRemoteUrl, a0 as postPrComment, ac as postReleaseToSlack, ao as postReleaseToTwitter, p as prComment, e as providerRelease, d as providerReleaseSafetyCheck, g as publish, W as publishPackage, f as publishSafetyCheck, C as pushCommitAndTags, a1 as readPackageJson, a3 as readPackages, r as release, al as resolveTags, D as rollbackModifiedFiles, aO as shouldFilterPrereleaseTags, h as social, s as socialSafetyCheck, t as topologicalSort, aD as updateLernaVersion, w as writeChangelogToFile, aB as writeVersion } from './shared/relizy.BbFf6ZTs.mjs';
2
2
  import '@maz-ui/node';
3
3
  import 'node:child_process';
4
4
  import 'node:process';
@@ -1847,7 +1847,7 @@ function getDefaultConfig() {
1847
1847
  tagMessage: "Bump version to {{newVersion}}",
1848
1848
  tagBody: "v{{newVersion}}",
1849
1849
  emptyChangelogContent: "No relevant changes for this release",
1850
- twitterMessage: "\u{1F680} {{projectName}} {{newVersion}} is out!\n\n{{changelog}}\n\n{{releaseUrl}}\n{{changelogUrl}}",
1850
+ twitterMessage: "\u{1F4E3} {{projectName}} {{newVersion}} is out!\n\n{{changelog}}\n\n{{releaseUrl}}\n{{changelogUrl}}",
1851
1851
  slackMessage: void 0,
1852
1852
  // Use rich blocks format by default (no template)
1853
1853
  changelogTitle: "{{oldVersion}}...{{newVersion}}"
@@ -1914,7 +1914,10 @@ function getDefaultConfig() {
1914
1914
  },
1915
1915
  slack: {
1916
1916
  enabled: false,
1917
- onlyStable: true
1917
+ onlyStable: true,
1918
+ postMaxLength: 2500,
1919
+ noAuthors: false,
1920
+ noPackages: false
1918
1921
  }
1919
1922
  },
1920
1923
  prComment: {
@@ -2382,11 +2385,11 @@ function buildChangelogBody({ commits, config, minify }) {
2382
2385
  }
2383
2386
  return convert(markdown.join("\n").trim(), true);
2384
2387
  }
2385
- async function buildContributors({ commits, config }) {
2388
+ function collectContributorNames({ commits, config }) {
2386
2389
  if (config.noAuthors) {
2387
- return "";
2390
+ return [];
2388
2391
  }
2389
- const _authors = /* @__PURE__ */ new Map();
2392
+ const names = /* @__PURE__ */ new Set();
2390
2393
  for (const commit of commits) {
2391
2394
  if (!commit.author) {
2392
2395
  continue;
@@ -2400,11 +2403,26 @@ async function buildContributors({ commits, config }) {
2400
2403
  )) {
2401
2404
  continue;
2402
2405
  }
2403
- if (_authors.has(name)) {
2404
- const entry = _authors.get(name);
2405
- entry?.email.add(commit.author.email);
2406
- } else {
2407
- _authors.set(name, { email: /* @__PURE__ */ new Set([commit.author.email]), name });
2406
+ names.add(name);
2407
+ }
2408
+ return Array.from(names);
2409
+ }
2410
+ async function buildContributors({ commits, config }) {
2411
+ const names = collectContributorNames({ commits, config });
2412
+ if (names.length === 0) {
2413
+ return "";
2414
+ }
2415
+ const _authors = /* @__PURE__ */ new Map();
2416
+ for (const name of names) {
2417
+ _authors.set(name, { email: /* @__PURE__ */ new Set(), name });
2418
+ }
2419
+ for (const commit of commits) {
2420
+ if (!commit.author)
2421
+ continue;
2422
+ const name = formatName(commit.author.name);
2423
+ const entry = _authors.get(name);
2424
+ if (entry && commit.author.email) {
2425
+ entry.email.add(commit.author.email);
2408
2426
  }
2409
2427
  }
2410
2428
  if (config.repo?.provider === "github") {
@@ -3301,6 +3319,32 @@ async function gitlab(options = {}) {
3301
3319
  }
3302
3320
  }
3303
3321
 
3322
+ function collectPackageBumps({
3323
+ bumpedPackages,
3324
+ packages
3325
+ }) {
3326
+ if (bumpedPackages && bumpedPackages.length > 0) {
3327
+ return bumpedPackages.map((pkg) => {
3328
+ const hasTransition = Boolean(pkg.newVersion && pkg.oldVersion !== pkg.newVersion);
3329
+ return {
3330
+ name: pkg.name,
3331
+ oldVersion: pkg.oldVersion,
3332
+ newVersion: pkg.newVersion,
3333
+ version: pkg.newVersion || pkg.version,
3334
+ hasTransition
3335
+ };
3336
+ });
3337
+ }
3338
+ if (packages && packages.length > 0) {
3339
+ return packages.map((pkg) => ({
3340
+ name: pkg.name,
3341
+ version: pkg.version,
3342
+ hasTransition: false
3343
+ }));
3344
+ }
3345
+ return [];
3346
+ }
3347
+
3304
3348
  function getGitHubApiBase(domain) {
3305
3349
  const apiDomain = domain === "github.com" || !domain ? "api.github.com" : domain;
3306
3350
  return apiDomain === "api.github.com" ? `https://${apiDomain}` : `https://${apiDomain}/api/v3`;
@@ -3717,8 +3761,11 @@ function getSlackToken(options) {
3717
3761
  }
3718
3762
  return token;
3719
3763
  }
3720
- function formatChangelogForSlack(changelog, maxLength = 500) {
3721
- let formatted = changelog.replace(/^### (.+)$/gm, "*$1*").replace(/^## (.+)$/gm, "*$1*").replace(/^# (.+)$/gm, "*$1*").replace(/\*\*(.+?)\*\*/g, "*$1*");
3764
+ function getSlackWebhookUrl(options) {
3765
+ return options.socialWebhookUrl || process.env.RELIZY_SLACK_WEBHOOK_URL || process.env.SLACK_WEBHOOK_URL || null;
3766
+ }
3767
+ function formatChangelogForSlack(changelog, maxLength = 2500) {
3768
+ let formatted = changelog.replace(/^### (.+)$/gm, "*$1*").replace(/^## (.+)$/gm, "*$1*").replace(/^# (.+)$/gm, "*$1*").replace(/\*\*(.+?)\*\*/g, "*$1*").replace(/^([ \t]*)-[ \t]+/gm, "$1\u2022 ");
3722
3769
  const linkPattern = /\[([^\]]*)]\(([^)]*)\)/g;
3723
3770
  formatted = formatted.replace(linkPattern, (_, text, url) => `<${url}|${text}>`);
3724
3771
  if (formatted.length > maxLength) {
@@ -3726,10 +3773,20 @@ function formatChangelogForSlack(changelog, maxLength = 500) {
3726
3773
  }
3727
3774
  return formatted;
3728
3775
  }
3729
- function formatSlackMessage({ projectName, version, changelog, releaseUrl, changelogUrl, template }) {
3776
+ function formatPackagesForSlack(packages) {
3777
+ if (packages.length === 0) {
3778
+ return "";
3779
+ }
3780
+ return packages.map(
3781
+ (pkg) => pkg.hasTransition ? `\u2022 \`${pkg.name}\`: \`${pkg.oldVersion}\` \u2192 \`${pkg.newVersion}\`` : `\u2022 \`${pkg.name}\`: \`${pkg.version}\``
3782
+ ).join("\n");
3783
+ }
3784
+ function formatSlackMessage({ projectName, version, changelog, releaseUrl, changelogUrl, template, contributors = [], packages = [], postMaxLength = 2500 }) {
3785
+ const contributorsLine = contributors.length > 0 ? contributors.map((n) => `\u2022 ${n}`).join("\n") : "";
3786
+ const packagesLine = formatPackagesForSlack(packages);
3730
3787
  if (template) {
3731
- const summary = extractChangelogSummary(changelog, { maxLength: 500 });
3732
- let message = template.replace("{{projectName}}", projectName).replace("{{newVersion}}", version).replace("{{changelog}}", summary);
3788
+ const summary = extractChangelogSummary(changelog, { maxLength: postMaxLength });
3789
+ let message = template.replace("{{projectName}}", projectName).replace("{{newVersion}}", version).replace("{{changelog}}", summary).replace("{{contributors}}", contributorsLine).replace("{{packages}}", packagesLine);
3733
3790
  if (releaseUrl) {
3734
3791
  message = message.replace("{{releaseUrl}}", releaseUrl);
3735
3792
  } else {
@@ -3755,12 +3812,12 @@ function formatSlackMessage({ projectName, version, changelog, releaseUrl, chang
3755
3812
  type: "header",
3756
3813
  text: {
3757
3814
  type: "plain_text",
3758
- text: `\u{1F680} ${projectName} ${version} is out!`,
3815
+ text: `\u{1F4E3} ${projectName} ${version} is out!`,
3759
3816
  emoji: true
3760
3817
  }
3761
3818
  }
3762
3819
  ];
3763
- const formattedChangelog = formatChangelogForSlack(changelog, 500);
3820
+ const formattedChangelog = formatChangelogForSlack(changelog, postMaxLength);
3764
3821
  if (formattedChangelog) {
3765
3822
  blocks.push({
3766
3823
  type: "section",
@@ -3770,6 +3827,28 @@ function formatSlackMessage({ projectName, version, changelog, releaseUrl, chang
3770
3827
  }
3771
3828
  });
3772
3829
  }
3830
+ if (packages.length > 0) {
3831
+ blocks.push({
3832
+ type: "section",
3833
+ text: {
3834
+ type: "mrkdwn",
3835
+ text: `*\u{1F4E6} Packages*
3836
+
3837
+ ${packagesLine}`
3838
+ }
3839
+ });
3840
+ }
3841
+ if (contributors.length > 0) {
3842
+ blocks.push({
3843
+ type: "section",
3844
+ text: {
3845
+ type: "mrkdwn",
3846
+ text: `*\u2764\uFE0F Contributors*
3847
+
3848
+ ${contributorsLine}`
3849
+ }
3850
+ });
3851
+ }
3773
3852
  blocks.push({
3774
3853
  type: "divider"
3775
3854
  });
@@ -3806,44 +3885,44 @@ function formatSlackMessage({ projectName, version, changelog, releaseUrl, chang
3806
3885
  }
3807
3886
  return blocks;
3808
3887
  }
3809
- async function postReleaseToSlack({
3810
- version,
3811
- projectName,
3812
- changelog,
3813
- releaseUrl,
3814
- changelogUrl,
3815
- channel,
3816
- token,
3817
- template,
3818
- dryRun = false
3819
- }) {
3820
- logger.debug("Preparing Slack post...");
3821
- const blocks = formatSlackMessage({
3822
- template,
3823
- projectName,
3824
- version,
3825
- changelog,
3826
- releaseUrl,
3827
- changelogUrl
3888
+ function mapWebhookError(status, body) {
3889
+ if (status === 404 || body.includes("no_service")) {
3890
+ return "The webhook URL is invalid or has been deactivated. Regenerate it in your Slack app settings.";
3891
+ }
3892
+ if (body.includes("invalid_payload")) {
3893
+ return "The message payload was rejected by Slack (likely exceeds 3000 chars per block). Lower social.slack.postMaxLength.";
3894
+ }
3895
+ if (body.includes("channel_not_found")) {
3896
+ return "The channel bound to this webhook was archived or removed. Create a new webhook.";
3897
+ }
3898
+ if (body.includes("action_prohibited")) {
3899
+ return "Your workspace has blocked the webhook. Check workspace settings.";
3900
+ }
3901
+ return null;
3902
+ }
3903
+ async function postViaWebhook({ url, blocks, text }) {
3904
+ const response = await fetch(url, {
3905
+ method: "POST",
3906
+ headers: { "Content-Type": "application/json" },
3907
+ body: JSON.stringify({ blocks, text })
3828
3908
  });
3829
- logger.debug(`Message blocks (${blocks.length} blocks)`);
3830
- if (dryRun) {
3831
- const preview = blocks.filter((b) => b.type === "header" || b.type === "section").map((b) => b.text?.text ?? "").filter(Boolean).join("\n\n");
3832
- logger.box(`[dry-run] Slack Post Preview (channel: ${channel})
3833
-
3834
- ${preview}`);
3835
- return;
3909
+ if (!response.ok) {
3910
+ const body = await response.text().catch(() => "");
3911
+ const hint = mapWebhookError(response.status, body);
3912
+ const detail = body ? ` - ${body}` : "";
3913
+ const hintLine = hint ? `
3914
+ \u2192 ${hint}` : "";
3915
+ throw new Error(`Slack webhook failed: ${response.status} ${response.statusText}${detail}${hintLine}`);
3836
3916
  }
3917
+ logger.success("Message posted successfully via Slack webhook!");
3918
+ return { ok: true, transport: "webhook" };
3919
+ }
3920
+ async function postViaWebApi({ token, channel, blocks, text }) {
3837
3921
  try {
3838
3922
  const { WebClient } = await import('@slack/web-api');
3839
3923
  const client = new WebClient(token);
3840
3924
  logger.debug(`Posting message to Slack channel: ${channel}`);
3841
- const result = await client.chat.postMessage({
3842
- channel,
3843
- blocks,
3844
- text: `${projectName} ${version} is out!`
3845
- // Fallback text for notifications
3846
- });
3925
+ const result = await client.chat.postMessage({ channel, blocks, text });
3847
3926
  logger.success(`Message posted successfully! Channel: ${result.channel}, Timestamp: ${result.ts}`);
3848
3927
  return result;
3849
3928
  } catch (error) {
@@ -3870,6 +3949,56 @@ ${preview}`);
3870
3949
  throw error;
3871
3950
  }
3872
3951
  }
3952
+ async function postReleaseToSlack({
3953
+ version,
3954
+ projectName,
3955
+ changelog,
3956
+ releaseUrl,
3957
+ changelogUrl,
3958
+ channel,
3959
+ token,
3960
+ webhookUrl,
3961
+ template,
3962
+ contributors,
3963
+ packages,
3964
+ postMaxLength,
3965
+ dryRun = false
3966
+ }) {
3967
+ const useWebhook = Boolean(webhookUrl);
3968
+ if (!useWebhook && !token) {
3969
+ throw new Error("Slack: either webhookUrl or token must be provided");
3970
+ }
3971
+ if (!useWebhook && !channel) {
3972
+ throw new Error("Slack: channel is required when using token-based authentication");
3973
+ }
3974
+ logger.debug(`Slack transport: ${useWebhook ? "webhook" : "web-api"}`);
3975
+ logger.debug("Preparing Slack post...");
3976
+ const blocks = formatSlackMessage({
3977
+ template,
3978
+ projectName,
3979
+ version,
3980
+ changelog,
3981
+ releaseUrl,
3982
+ changelogUrl,
3983
+ contributors,
3984
+ packages,
3985
+ postMaxLength
3986
+ });
3987
+ const fallbackText = `${projectName} ${version} is out!`;
3988
+ logger.debug(`Message blocks (${blocks.length} blocks)`);
3989
+ if (dryRun) {
3990
+ const preview = blocks.filter((b) => b.type === "header" || b.type === "section").map((b) => b.text?.text ?? "").filter(Boolean).join("\n\n");
3991
+ const target = useWebhook ? "webhook" : `channel: ${channel}`;
3992
+ logger.box(`[dry-run] Slack Post Preview (${target})
3993
+
3994
+ ${preview}`);
3995
+ return;
3996
+ }
3997
+ if (useWebhook) {
3998
+ return await postViaWebhook({ url: webhookUrl, blocks, text: fallbackText });
3999
+ }
4000
+ return await postViaWebApi({ token, channel, blocks, text: fallbackText });
4001
+ }
3873
4002
 
3874
4003
  function getTwitterCredentials({ socialCredentials, tokenCredentials }) {
3875
4004
  const apiKey = socialCredentials?.apiKey || tokenCredentials?.apiKey;
@@ -4693,23 +4822,15 @@ function buildMetadataLines({
4693
4822
  return lines;
4694
4823
  }
4695
4824
  function buildPackageTableLines(bumpedPackages, packages) {
4696
- const lines = [];
4697
- const header = ["", "### Packages", "", "| Package | Version |", "| --- | --- |"];
4698
- if (bumpedPackages.length > 0) {
4699
- lines.push(...header);
4700
- for (const pkg of bumpedPackages) {
4701
- const hasTransition = pkg.newVersion && pkg.oldVersion !== pkg.newVersion;
4702
- lines.push(
4703
- hasTransition ? `| \`${pkg.name}\` | \`${pkg.oldVersion}\` \u2192 \`${pkg.newVersion}\` |` : `| \`${pkg.name}\` | \`${pkg.version}\` |`
4704
- );
4705
- }
4706
- return lines;
4825
+ const entries = collectPackageBumps({ bumpedPackages, packages });
4826
+ if (entries.length === 0) {
4827
+ return [];
4707
4828
  }
4708
- if (packages && packages.length > 0) {
4709
- lines.push(...header);
4710
- for (const pkg of packages) {
4711
- lines.push(`| \`${pkg.name}\` | \`${pkg.version}\` |`);
4712
- }
4829
+ const lines = ["", "### Packages", "", "| Package | Version |", "| --- | --- |"];
4830
+ for (const entry of entries) {
4831
+ lines.push(
4832
+ entry.hasTransition ? `| \`${entry.name}\` | \`${entry.oldVersion}\` \u2192 \`${entry.newVersion}\` |` : `| \`${entry.name}\` | \`${entry.version}\` |`
4833
+ );
4713
4834
  }
4714
4835
  return lines;
4715
4836
  }
@@ -5180,27 +5301,37 @@ async function socialSafetyCheck({ config }) {
5180
5301
  }
5181
5302
  const slackConfig = config.social?.slack;
5182
5303
  if (slackConfig?.enabled) {
5304
+ const webhookUrl = getSlackWebhookUrl({ socialWebhookUrl: slackConfig.webhookUrl });
5183
5305
  const token = getSlackToken({
5184
5306
  socialCredentials: slackConfig.credentials,
5185
5307
  tokenCredential: config.tokens?.slack
5186
5308
  });
5187
- try {
5188
- await import('@slack/web-api');
5189
- } catch {
5190
- logger.fail("@slack/web-api is not installed, please install it");
5191
- throw new Error("@slack/web-api is not installed");
5192
- }
5193
- if (!token) {
5194
- logger.fail("Slack is enabled but credentials are missing.");
5195
- logger.log("Set the following environment variables or configure them in social.slack.credentials or tokens.slack:");
5196
- logger.log(" - SLACK_TOKEN or RELIZY_SLACK_TOKEN");
5309
+ if (webhookUrl) {
5310
+ if (slackConfig.channel) {
5311
+ logger.warn("social.slack.channel is ignored when webhookUrl is set (channel is baked into the webhook URL).");
5312
+ }
5313
+ if (token) {
5314
+ logger.warn("Slack token is ignored when webhookUrl is set (webhook takes priority).");
5315
+ }
5316
+ } else if (token) {
5317
+ try {
5318
+ await import('@slack/web-api');
5319
+ } catch {
5320
+ logger.fail("@slack/web-api is not installed, please install it");
5321
+ throw new Error("@slack/web-api is not installed");
5322
+ }
5323
+ if (!slackConfig.channel) {
5324
+ logger.fail("Slack is enabled but no channel is configured.");
5325
+ logger.log('Set the channel in social.slack.channel (e.g., "#releases" or "C1234567890") or switch to webhookUrl for a simpler setup.');
5326
+ throw new Error("Slack channel not found");
5327
+ }
5328
+ } else {
5329
+ logger.fail("Slack is enabled but no credentials are configured.");
5330
+ logger.log("Provide ONE of the following:");
5331
+ logger.log(" (a) social.slack.webhookUrl (or SLACK_WEBHOOK_URL / RELIZY_SLACK_WEBHOOK_URL env var) \u2014 simpler setup, channel baked in");
5332
+ logger.log(" (b) social.slack.credentials.token (or SLACK_TOKEN / RELIZY_SLACK_TOKEN env var) + social.slack.channel \u2014 requires bot invite");
5197
5333
  throw new Error("Slack credentials not found");
5198
5334
  }
5199
- if (!slackConfig.channel) {
5200
- logger.fail("Slack is enabled but no channel is configured.");
5201
- logger.log('Set the channel in social.slack.channel (e.g., "#releases" or "C1234567890")');
5202
- throw new Error("Slack channel not found");
5203
- }
5204
5335
  }
5205
5336
  if (isAISocialEnabled(config, "twitter") || isAISocialEnabled(config, "slack")) {
5206
5337
  await aiSafetyCheck({ config });
@@ -5281,7 +5412,9 @@ async function handleSlackPost({
5281
5412
  changelog,
5282
5413
  dryRun,
5283
5414
  newVersion,
5284
- tag
5415
+ tag,
5416
+ commits,
5417
+ bumpedPackages
5285
5418
  }) {
5286
5419
  const slackConfig = config.social?.slack;
5287
5420
  if (!slackConfig?.enabled) {
@@ -5290,22 +5423,23 @@ async function handleSlackPost({
5290
5423
  }
5291
5424
  logger.debug("Slack posting is enabled");
5292
5425
  try {
5426
+ const webhookUrl = getSlackWebhookUrl({ socialWebhookUrl: slackConfig.webhookUrl });
5293
5427
  const token = getSlackToken({
5294
5428
  socialCredentials: slackConfig.credentials,
5295
5429
  tokenCredential: config.tokens?.slack
5296
5430
  });
5297
- if (!token) {
5298
- logger.warn("Slack token not found. Set SLACK_TOKEN or RELIZY_SLACK_TOKEN environment variable or configure it in social.slack.credentials or tokens.slack.");
5431
+ if (!webhookUrl && !token) {
5432
+ logger.warn("Neither Slack webhookUrl nor token is configured. Set SLACK_WEBHOOK_URL / SLACK_TOKEN or configure social.slack.webhookUrl / credentials.token.");
5299
5433
  logger.info("Skipping Slack post");
5300
- return { success: false, error: "Slack token not found" };
5434
+ return { success: false, error: "Slack credentials not found" };
5301
5435
  }
5302
- logger.debug("Token found \u2713");
5303
- if (!slackConfig.channel) {
5304
- logger.warn("Slack channel not configured. Set it in social.slack.channel.");
5436
+ if (!webhookUrl && !slackConfig.channel) {
5437
+ logger.warn("Slack channel not configured (required in token mode). Set it in social.slack.channel.");
5305
5438
  logger.info("Skipping Slack post");
5306
5439
  return { success: false, error: "Slack channel not configured" };
5307
5440
  }
5308
- logger.debug(`Channel configured: ${slackConfig.channel}`);
5441
+ const slackMode = webhookUrl ? "webhook mode" : `token mode, channel: ${slackConfig.channel}`;
5442
+ logger.debug(`Slack: ${slackMode}`);
5309
5443
  logger.debug(`Preparing Slack message for release: ${tag} (${newVersion})`);
5310
5444
  const onlyStable = slackConfig.onlyStable ?? true;
5311
5445
  if (onlyStable && isPrerelease(newVersion)) {
@@ -5325,6 +5459,11 @@ async function handleSlackPost({
5325
5459
  logger.debug(`Changelog URL: ${changelogUrl || "none"}`);
5326
5460
  logger.debug(`Changelog generated (${changelog.length} chars)`);
5327
5461
  const template = slackConfig.template || config.templates.slackMessage;
5462
+ const shouldHideContributors = config.noAuthors === true || slackConfig.noAuthors === true;
5463
+ const contributors = shouldHideContributors ? [] : collectContributorNames({ commits, config });
5464
+ logger.debug(`Contributors: ${contributors.length}`);
5465
+ const packages = slackConfig.noPackages === true ? [] : collectPackageBumps({ bumpedPackages });
5466
+ logger.debug(`Packages: ${packages.length}`);
5328
5467
  const response = await postReleaseToSlack({
5329
5468
  version: newVersion,
5330
5469
  projectName: config.projectName || rootPackageBase.name,
@@ -5332,8 +5471,12 @@ async function handleSlackPost({
5332
5471
  releaseUrl,
5333
5472
  changelogUrl,
5334
5473
  channel: slackConfig.channel,
5335
- token,
5474
+ token: token ?? void 0,
5475
+ webhookUrl: webhookUrl ?? void 0,
5336
5476
  template,
5477
+ contributors,
5478
+ packages,
5479
+ postMaxLength: slackConfig.postMaxLength ?? 2500,
5337
5480
  dryRun
5338
5481
  });
5339
5482
  await executeHook("success:slack", config, dryRun);
@@ -5448,7 +5591,9 @@ ${twitterChangelog}`);
5448
5591
  changelog: slackChangelog,
5449
5592
  dryRun,
5450
5593
  newVersion,
5451
- tag: to
5594
+ tag: to,
5595
+ commits: rootPackage.commits,
5596
+ bumpedPackages: options.bumpResult?.bumpedPackages
5452
5597
  });
5453
5598
  const results = [];
5454
5599
  if (config.social?.twitter?.enabled) {
@@ -5818,4 +5963,4 @@ Git provider: ${provider}`);
5818
5963
  }
5819
5964
  }
5820
5965
 
5821
- export { readPackageJson as $, getModifiedReleaseFilePatterns as A, createCommitAndTags as B, pushCommitAndTags as C, rollbackModifiedFiles as D, getFirstCommit as E, getCurrentGitBranch as F, getCurrentGitRef as G, getShortCommitSha as H, github as I, createGitlabRelease as J, gitlab as K, buildCompareLink as L, buildChangelogBody as M, buildContributors as N, generateMarkDown as O, parseChangelogMarkdown as P, detectPackageManager as Q, determinePublishTag as R, getPackagesToPublishInSelectiveMode as S, getPackagesToPublishInIndependentMode as T, getAuthCommand as U, publishPackage as V, findGitHubPR as W, findGitLabMR as X, detectPullRequest as Y, PR_COMMENT_MARKER as Z, postPrComment as _, buildCommentBody as a, getRootPackage as a0, readPackages as a1, getPackages as a2, getPackageCommits as a3, hasLernaJson as a4, getSlackToken as a5, formatChangelogForSlack as a6, formatSlackMessage as a7, postReleaseToSlack as a8, extractChangelogSummary as a9, extractVersionFromPackageTag as aA, isPrerelease as aB, isStableReleaseType as aC, isPrereleaseReleaseType as aD, isGraduating as aE, getPreid as aF, isChangedPreid as aG, getBumpedPackageIndependently as aH, confirmBump as aI, getBumpedIndependentPackages as aJ, shouldFilterPrereleaseTags as aK, extractVersionFromTag as aL, getCanaryVersion as aM, isTagVersionCompatibleWithCurrent as aN, getReleaseUrl as aa, getIndependentTag as ab, getLastStableTag as ac, getLastTag as ad, getLastRepoTag as ae, getLastPackageTag as af, NEW_PACKAGE_MARKER as ag, resolveTags as ah, getTwitterCredentials as ai, formatTweetMessage as aj, postReleaseToTwitter as ak, executeHook as al, isInCI as am, getCIName as an, executeFormatCmd as ao, executeBuildCmd as ap, isBumpedPackage as aq, filterOutPrivatePackages as ar, getPackagesOrBumpedPackages as as, isGraduatingToStableBetweenVersion as at, capReleaseTypeForZeroMajor as au, determineSemverChange as av, determineReleaseType as aw, writeVersion as ax, getPackageNewVersion as ay, updateLernaVersion as az, bump as b, changelog as c, providerReleaseSafetyCheck as d, providerRelease as e, publishSafetyCheck as f, publish as g, social as h, generateChangelog as i, getDefaultConfig as j, defineConfig as k, loadRelizyConfig as l, mergeTypes as m, getPackageDependencies as n, getDependentsOf as o, prComment as p, expandPackagesToBumpWithDependents as q, release as r, socialSafetyCheck as s, topologicalSort as t, getGitStatus as u, checkGitStatusIfDirty as v, writeChangelogToFile as w, fetchGitTags as x, detectGitProvider as y, parseGitRemoteUrl as z };
5966
+ export { PR_COMMENT_MARKER as $, getModifiedReleaseFilePatterns as A, createCommitAndTags as B, pushCommitAndTags as C, rollbackModifiedFiles as D, getFirstCommit as E, getCurrentGitBranch as F, getCurrentGitRef as G, getShortCommitSha as H, github as I, createGitlabRelease as J, gitlab as K, buildCompareLink as L, buildChangelogBody as M, collectContributorNames as N, buildContributors as O, generateMarkDown as P, parseChangelogMarkdown as Q, detectPackageManager as R, determinePublishTag as S, getPackagesToPublishInSelectiveMode as T, getPackagesToPublishInIndependentMode as U, getAuthCommand as V, publishPackage as W, collectPackageBumps as X, findGitHubPR as Y, findGitLabMR as Z, detectPullRequest as _, buildCommentBody as a, postPrComment as a0, readPackageJson as a1, getRootPackage as a2, readPackages as a3, getPackages as a4, getPackageCommits as a5, hasLernaJson as a6, getSlackToken as a7, getSlackWebhookUrl as a8, formatChangelogForSlack as a9, determineReleaseType as aA, writeVersion as aB, getPackageNewVersion as aC, updateLernaVersion as aD, extractVersionFromPackageTag as aE, isPrerelease as aF, isStableReleaseType as aG, isPrereleaseReleaseType as aH, isGraduating as aI, getPreid as aJ, isChangedPreid as aK, getBumpedPackageIndependently as aL, confirmBump as aM, getBumpedIndependentPackages as aN, shouldFilterPrereleaseTags as aO, extractVersionFromTag as aP, getCanaryVersion as aQ, isTagVersionCompatibleWithCurrent as aR, formatPackagesForSlack as aa, formatSlackMessage as ab, postReleaseToSlack as ac, extractChangelogSummary as ad, getReleaseUrl as ae, getIndependentTag as af, getLastStableTag as ag, getLastTag as ah, getLastRepoTag as ai, getLastPackageTag as aj, NEW_PACKAGE_MARKER as ak, resolveTags as al, getTwitterCredentials as am, formatTweetMessage as an, postReleaseToTwitter as ao, executeHook as ap, isInCI as aq, getCIName as ar, executeFormatCmd as as, executeBuildCmd as at, isBumpedPackage as au, filterOutPrivatePackages as av, getPackagesOrBumpedPackages as aw, isGraduatingToStableBetweenVersion as ax, capReleaseTypeForZeroMajor as ay, determineSemverChange as az, bump as b, changelog as c, providerReleaseSafetyCheck as d, providerRelease as e, publishSafetyCheck as f, publish as g, social as h, generateChangelog as i, getDefaultConfig as j, defineConfig as k, loadRelizyConfig as l, mergeTypes as m, getPackageDependencies as n, getDependentsOf as o, prComment as p, expandPackagesToBumpWithDependents as q, release as r, socialSafetyCheck as s, topologicalSort as t, getGitStatus as u, checkGitStatusIfDirty as v, writeChangelogToFile as w, fetchGitTags as x, detectGitProvider as y, parseGitRemoteUrl as z };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "relizy",
3
3
  "type": "module",
4
- "version": "1.3.3",
4
+ "version": "1.4.0-beta.1",
5
5
  "description": "Changelogen adapter for monorepo management with unified and independent versioning",
6
6
  "author": "Louis Mazel <me@loicmazuel.com>",
7
7
  "license": "MIT",
@@ -71,7 +71,7 @@
71
71
  }
72
72
  },
73
73
  "dependencies": {
74
- "@inquirer/prompts": "^8.4.1",
74
+ "@inquirer/prompts": "^8.4.2",
75
75
  "@maz-ui/node": "4.6.1",
76
76
  "@maz-ui/utils": "^4.7.6",
77
77
  "c12": "^3.3.3",
@@ -88,23 +88,23 @@
88
88
  "@commitlint/config-conventional": "20.5.0",
89
89
  "@commitlint/cz-commitlint": "^20.5.1",
90
90
  "@commitlint/types": "^20.5.0",
91
- "@maz-ui/eslint-config": "^4.8.0",
92
- "@slack/web-api": "7.15.0",
91
+ "@maz-ui/eslint-config": "^4.9.1",
92
+ "@slack/web-api": "7.15.1",
93
93
  "@types/node": "^25.6.0",
94
94
  "@types/semver": "^7.7.1",
95
- "@vitest/coverage-v8": "^4.1.4",
95
+ "@vitest/coverage-v8": "^4.1.5",
96
96
  "@yoloship/claude-sdk": "0.1.0-beta.3",
97
97
  "cross-env": "10.1.0",
98
- "eslint": "^10.2.0",
98
+ "eslint": "^10.2.1",
99
99
  "husky": "9.1.7",
100
100
  "jiti": "2.6.1",
101
101
  "lint-staged": "^16.4.0",
102
- "memfs": "^4.57.1",
102
+ "memfs": "^4.57.2",
103
103
  "tsx": "^4.21.0",
104
104
  "twitter-api-v2": "^1.29.0",
105
105
  "typescript": "^5.9.3",
106
106
  "unbuild": "^3.6.1",
107
- "vitest": "^4.1.4"
107
+ "vitest": "^4.1.5"
108
108
  },
109
109
  "lint-staged": {
110
110
  "*.{js,jsx,ts,tsx,mjs,mts,cjs,md,yml,json}": [