import { LogLevel } from '@maz-ui/node'; import { GitCommit, ChangelogConfig as ChangelogConfig$1, SemverBumpType } from 'changelogen'; import { ReleaseType } from 'semver'; import { DeepPartial } from '@maz-ui/utils'; import * as _slack_web_api from '@slack/web-api'; import * as twitter_api_v2 from 'twitter-api-v2'; declare function getDefaultConfig(): { cwd: string; types: NonNullable; templates: { commitMessage: string | undefined; commitBody: string | undefined; tagMessage: string; tagBody: string; emptyChangelogContent: string; twitterMessage: string; slackMessage: undefined; changelogTitle: string; }; excludeAuthors: never[]; noAuthors: boolean; bump: Required>; changelog: Required; monorepo: MonorepoConfig; publish: { private: false; args: never[]; token: string | undefined; registry: string; safetyCheck: true; packageManager: PackageManager; }; tokens: { registry: string | undefined; gitlab: string | undefined; github: string | undefined; twitter: { apiKey: string | undefined; apiKeySecret: string | undefined; accessToken: string | undefined; accessTokenSecret: string | undefined; }; slack: string | undefined; ai: { 'claude-code': { apiKey: string | undefined; oauthToken: string | undefined; }; }; }; scopeMap: {}; release: Required; social: { twitter: { enabled: false; onlyStable: true; postMaxLength: number; }; slack: { enabled: boolean; onlyStable: boolean; postMaxLength: number; noAuthors: boolean; noPackages: boolean; }; }; prComment: Required; ai: AIConfig; logLevel: LogLevel; safetyCheck: boolean; }; /** * Merge user types with defaults: each user-defined entry replaces the default entirely. * This prevents defu's deep merge from adding default sub-properties * the user intentionally omitted (e.g. `docs: { title: '...' }` without `semver`). */ declare function mergeTypes>(userTypes: T | undefined, defaultTypes: T): T; declare function loadRelizyConfig(options?: { baseConfig?: ResolvedRelizyConfig; overrides?: DeepPartial; configFile?: string; }): Promise; type ResolvedConfig = RelizyConfig & ReturnType; type ResolvedRelizyConfig = ResolvedConfig & { output: string; }; declare function defineConfig(config: RelizyConfig): RelizyConfig; /** * Controls which sections of the rendered changelog are produced. * Each flag defaults to `true`. `compareLink` and `contributors` are * additionally suppressed when `minify: true` (see `generateChangelog`). */ interface ChangelogInclude { title?: boolean; compareLink?: boolean; body?: boolean; contributors?: boolean; } /** * Generate the changelog string for a single package. * * - Fetches commits internally using `changelog: true`, so types that only * declare a `title` (e.g. `docs: { title: 'πŸ“– Documentation' }`) are * included even though they don't trigger a version bump. Callers must * provide `pkg.path` β€” `pkg.commits` is no longer consumed. * - `include` toggles which sections appear in the output. `compareLink` * and `contributors` are also skipped when `minify` is true. * - `transformBody` is invoked between body rendering and final assembly, * used by provider releases to plug an AI rewrite step on the body only. */ declare function generateChangelog({ pkg, config, dryRun, newVersion, minify, include, transformBody, }: { pkg: { fromTag?: string; name: string; path: string; newVersion?: string; }; config: ResolvedRelizyConfig; dryRun: boolean; newVersion: string; minify?: boolean; include?: ChangelogInclude; transformBody?: (body: string) => Promise | string; }): Promise; /** * Write changelog to file */ declare function writeChangelogToFile({ cwd, pkg, changelog, dryRun, }: { cwd: string; pkg: ReadPackage | PackageBase; changelog: string; dryRun: boolean; }): void; /** * Get workspace dependencies of a package (only dependencies and peerDependencies, not devDependencies) */ declare function getPackageDependencies({ packagePath, allPackageNames, dependencyTypes, }: { packagePath: string; allPackageNames: Set; dependencyTypes: BumpConfig['dependencyTypes']; }): string[]; /** * Get all packages that depend on the given package name */ declare function getDependentsOf({ allPackages, packageName, }: { allPackages: { name: string; dependencies: string[]; }[]; packageName: string; }): { name: string; dependencies: string[]; }[]; /** * Recursively expand packages to bump with all their dependents (transitive) * Returns packages with reason for bumping and dependency chain for traceability */ declare function expandPackagesToBumpWithDependents({ allPackages, packagesWithCommits, }: { allPackages: PackageBase[]; packagesWithCommits: PackageBase[]; }): PackageBase[]; /** * Topological sort of packages based on their dependencies * Ensures dependencies are processed before dependents */ declare function topologicalSort(packages: PackageBase[]): PackageBase[]; declare function getGitStatus(cwd?: string, trim?: boolean): string; declare function checkGitStatusIfDirty(): void; declare function fetchGitTags(cwd?: string): Promise; declare function detectGitProvider(cwd?: string): GitProvider | null; declare function parseGitRemoteUrl(remoteUrl: string): { owner: string; repo: string; } | null; /** * Get files modified in git status that are relevant for release * Returns only package.json, CHANGELOG.md, and lerna.json files */ declare function getModifiedReleaseFilePatterns({ config }: { config: ResolvedRelizyConfig; }): string[]; declare function createCommitAndTags({ config, noVerify, bumpedPackages, newVersion, dryRun, logLevel, }: { config: ResolvedRelizyConfig; noVerify: boolean; bumpedPackages: BumpResultTruthy['bumpedPackages']; newVersion?: string; dryRun?: boolean; logLevel: LogLevel; }): Promise; declare function pushCommitAndTags({ config, dryRun, logLevel, cwd }: { config: ResolvedRelizyConfig; dryRun: boolean; logLevel?: LogLevel; cwd: string; }): Promise; /** * Rollback modified files to their last committed state * Used when publish fails before commit/tag/push operations */ declare function rollbackModifiedFiles({ config, }: { config: ResolvedRelizyConfig; }): Promise; declare function getFirstCommit(cwd: string): string; declare function getCurrentGitBranch(cwd: string): string; declare function getCurrentGitRef(cwd: string): string; declare function getShortCommitSha(cwd: string, length?: number): string; declare function github(options: ProviderReleaseOptions): Promise; interface GitlabRelease { tag_name: string; name?: string; description?: string; ref?: string; milestones?: string[]; assets?: { links?: Array<{ name: string; url: string; }>; }; released_at?: string; } interface GitlabReleaseResponse { tag_name: string; name: string; description: string; created_at: string; released_at: string; _links: { self: string; }; } declare function createGitlabRelease({ config, release, dryRun, }: { config: ResolvedRelizyConfig; release: GitlabRelease; dryRun?: boolean; }): Promise; declare function gitlab(options?: Partial): Promise; interface Reference { type: 'hash' | 'issue' | 'pull-request'; value: string; } declare function buildCompareLink({ config, from, to, isFirstCommit }: { config: ResolvedRelizyConfig; from: string; to: string; isFirstCommit: boolean; }): string; declare function buildChangelogBody({ commits, config, minify }: { commits: GitCommit[]; config: ResolvedRelizyConfig; minify?: boolean; }): string; /** * Collect unique contributor names from a set of commits. * Respects `config.noAuthors`, filters `[bot]` authors, and applies `config.excludeAuthors`. * Returns plain formatted names (no emails, no GitHub handles) β€” useful for lightweight * rendering contexts like Slack messages. */ declare function collectContributorNames({ commits, config }: { commits: GitCommit[]; config: ResolvedRelizyConfig; }): string[]; declare function buildContributors({ commits, config }: { commits: GitCommit[]; config: ResolvedRelizyConfig; }): Promise; declare function generateMarkDown({ commits, config, from, to, isFirstCommit, minify, }: { commits: GitCommit[]; config: ResolvedRelizyConfig; from: string; to: string; isFirstCommit: boolean; minify?: boolean; }): Promise; declare function parseChangelogMarkdown(contents: string): { releases: { version?: string; body: string; }[]; }; declare function detectPackageManager(cwd?: string): PackageManager; declare function determinePublishTag(version: string, configTag?: string): string; declare function getPackagesToPublishInSelectiveMode(sortedPackages: PackageBase[], rootVersion: string | undefined): PackageBase[]; declare function getPackagesToPublishInIndependentMode(sortedPackages: PackageBase[], config: ResolvedRelizyConfig): Promise; declare function getAuthCommand({ packageManager, config, otp, }: { packageManager: PackageManager; config: ResolvedRelizyConfig; otp?: string; }): string; declare function publishPackage({ pkg, config, packageManager, dryRun, }: { pkg: PackageBase; config: ResolvedRelizyConfig; packageManager: PackageManager; dryRun: boolean; }): Promise; /** * A package entry as consumed by release-summary renderers (PR comments, Slack messages, etc.). * Normalizes the three possible shapes of "which packages shipped and at what version": * - `bumpedPackages` from a monorepo bump (has both `oldVersion` and `newVersion`) * - `packages` in standalone CLI mode (only `version`, no transition) * - a mixed case where a bumped package didn't produce a new version */ interface PackageBumpEntry { /** Package name (e.g. `@acme/ui`) */ name: string; /** Version before the release β€” only set when a real transition happened */ oldVersion?: string; /** Version after the release β€” only set when a real transition happened */ newVersion?: string; /** Fallback version when there is no oldβ†’new transition (standalone mode, graduations) */ version: string; /** True when `oldVersion` and `newVersion` are both set AND differ */ hasTransition: boolean; } /** * Collect package release data in a renderer-agnostic shape. * Shared by the PR-comment GFM table and the Slack mrkdwn list. */ declare function collectPackageBumps({ bumpedPackages, packages, }: { bumpedPackages?: BumpResultTruthy['bumpedPackages']; packages?: Array<{ name: string; version: string; }>; }): PackageBumpEntry[]; interface PullRequestInfo { /** * PR/MR number */ number: number; /** * PR/MR URL */ url: string; /** * Git provider */ provider: GitProvider; } declare function findGitHubPR({ token, repo, branch, domain, }: { token: string; repo: string; branch: string; domain?: string; }): Promise; declare function findGitLabMR({ token, repo, branch, domain, }: { token: string; repo: string; branch: string; domain?: string; }): Promise; declare function detectPullRequest({ config, prNumber, }: { config: ResolvedRelizyConfig; prNumber?: number; }): Promise; declare const PR_COMMENT_MARKER = ""; declare function postPrComment({ config, pr, body, }: { config: ResolvedRelizyConfig; pr: PullRequestInfo; body: string; }): Promise; declare function readPackageJson(packagePath: string): ReadPackage | undefined; interface RootPackage extends ReadPackage { fromTag: string; commits: GitCommit[]; newVersion?: string; } declare function getRootPackage({ config, force, from, to, suffix, changelog, }: { config: ResolvedRelizyConfig; force: boolean; from: string; to: string; suffix: string | undefined; changelog: boolean; }): Promise; declare function readPackages({ cwd, patterns, ignorePackageNames, includePrivates, }: { cwd: string; patterns?: string[]; ignorePackageNames: NonNullable['ignorePackageNames']; includePrivates?: boolean; }): ReadPackage[]; declare function getPackages({ config, suffix, force, includeAll, }: { config: ResolvedRelizyConfig; suffix: string | undefined; force: boolean; includeAll?: boolean; }): Promise; declare function getPackageCommits({ pkg, from, to, config, changelog, }: { pkg: ReadPackage; from: string; to: string; config: ResolvedRelizyConfig; changelog: boolean; }): Promise; declare function hasLernaJson(rootDir: string): boolean; /** * Get Slack token from config * Priority: social.slack.credentials > config.tokens.slack > environment variables (handled in config.ts) */ declare function getSlackToken(options: { socialCredentials?: SlackCredentials; tokenCredential?: string; }): string | null; /** * Get Slack Incoming Webhook URL from config or environment variables. * Priority: social.slack.webhookUrl > RELIZY_SLACK_WEBHOOK_URL > SLACK_WEBHOOK_URL. */ declare function getSlackWebhookUrl(options: { socialWebhookUrl?: string; }): string | null; /** * Format changelog for Slack (convert markdown to Slack's mrkdwn format) */ declare function formatChangelogForSlack(changelog: string, maxLength?: number): string; /** * Render a list of bumped packages as a Slack mrkdwn bullet list. * Each entry becomes `β€’ \`name\`: \`old\` β†’ \`new\`` when a transition is detected, * otherwise falls back to `β€’ \`name\`: \`version\``. */ declare function formatPackagesForSlack(packages: PackageBumpEntry[]): string; /** * Format the Slack message using blocks */ declare function formatSlackMessage({ projectName, version, changelog, releaseUrl, changelogUrl, template, contributors, packages, postMaxLength }: { template?: string; projectName: string; version: string; changelog: string; releaseUrl?: string; changelogUrl?: string; contributors?: string[]; packages?: PackageBumpEntry[]; postMaxLength?: number; }): any[]; /** * Post a release announcement to Slack. * Dispatches to Incoming Webhook (if `webhookUrl` is set) or Web API (`token` + `channel`). * When both are provided, the webhook takes priority. */ declare function postReleaseToSlack({ version, projectName, changelog, releaseUrl, changelogUrl, channel, token, webhookUrl, template, contributors, packages, postMaxLength, dryRun, }: SlackOptions): Promise<{ ok: true; transport: "webhook"; } | _slack_web_api.ChatPostMessageResponse | undefined>; /** * Extract a summary from changelog content */ declare function extractChangelogSummary(changelog: string, { stripBoldMarkers, maxLength }?: { stripBoldMarkers?: boolean; maxLength?: number; }): string; /** * Get the release URL from repo config and release tag */ declare function getReleaseUrl(config: ResolvedRelizyConfig, tag: string): string | undefined; declare function getIndependentTag({ version, name }: { version: string; name: string; }): string; declare function getLastStableTag({ logLevel, cwd }: { logLevel?: LogLevel; cwd?: string; }): Promise; declare function getLastTag({ logLevel, cwd }: { logLevel?: LogLevel; cwd?: string; }): Promise; declare function getLastRepoTag(options?: { onlyStable?: boolean; pkg?: ReadPackage; logLevel?: LogLevel; cwd?: string; }): Promise; declare function getLastPackageTag({ pkg, onlyStable, logLevel, cwd, }: { pkg: ReadPackage; onlyStable?: boolean; logLevel?: LogLevel; cwd?: string; }): Promise; type Step = 'bump' | 'changelog' | 'publish' | 'provider-release' | 'social'; interface ResolvedTags { from: string; to: string; } /** * Special marker indicating this is a new package with no previous tags. * When this marker is returned as the "from" tag, getPackageCommits should * return an empty array instead of analyzing all commits from the beginning * of the repository (which would cause ENOBUFS errors on large repos). */ declare const NEW_PACKAGE_MARKER: "__NEW_PACKAGE__"; declare function resolveTags({ config, step, pkg, newVersion, }: { config: ResolvedRelizyConfig; step: S; pkg: ReadPackage; newVersion: NewVersion; }): Promise; interface ResolvedTwitterCredentials { apiKey: string; apiKeySecret: string; accessToken: string; accessTokenSecret: string; } declare function getTwitterCredentials({ socialCredentials, tokenCredentials }: { socialCredentials?: TwitterCredentials; tokenCredentials?: TwitterCredentials; }): ResolvedTwitterCredentials | null; declare function formatTweetMessage({ template, projectName, version, changelog, releaseUrl, changelogUrl, postMaxLength }: { template: string; projectName: string; version: string; changelog: string; releaseUrl?: string; changelogUrl?: string; postMaxLength: number; }): string; declare function postReleaseToTwitter({ version, projectName, changelog, releaseUrl, changelogUrl, credentials, template, postMaxLength, dryRun, }: TwitterOptions): Promise; /** * Execute a hook */ declare function executeHook(hook: keyof HookConfig, config: ResolvedRelizyConfig, dryRun: boolean, params?: any): Promise; /** * Check if we are in a CI environment */ declare function isInCI(): boolean; /** * Get CI name */ declare function getCIName(): string | null; /** * Execute format command */ declare function executeFormatCmd({ config, dryRun, }: { config: ResolvedRelizyConfig; dryRun: boolean; }): Promise; /** * Execute build command */ declare function executeBuildCmd({ config, dryRun, }: { config: ResolvedRelizyConfig; dryRun: boolean; }): Promise; declare function isBumpedPackage(pkg: PackageBase): pkg is PackageBase & { oldVersion: string; }; declare function filterOutPrivatePackages(packages: T[]): T[]; declare function getPackagesOrBumpedPackages({ config, bumpResult, suffix, force, }: { config: ResolvedRelizyConfig; bumpResult: BumpResultTruthy | undefined; suffix: string | undefined; force: boolean; }): Promise; declare function isGraduatingToStableBetweenVersion(version: string, newVersion: string): boolean; type SemverChangeType = 'major' | 'minor' | 'patch' | undefined; /** * When the current version is in the `0.x.y` range (initial development per * semver Β§4), breaking changes must not graduate to `1.0.0` automatically. * This helper downgrades an auto-detected `major` change to `minor` in that * case. Explicit CLI release types (major, premajor, ...) are NOT passed * through this function β€” only commit-based detection is capped. */ declare function capReleaseTypeForZeroMajor(currentVersion: string, detected: SemverChangeType): SemverChangeType; declare function determineSemverChange(commits: GitCommit[], types: NonNullable, currentVersion?: string): SemverChangeType; declare function determineReleaseType({ currentVersion, commits, releaseType, preid, types, force, }: { currentVersion: string; commits?: GitCommit[]; releaseType: ReleaseType; preid: string | undefined; types: ResolvedRelizyConfig['types']; force: boolean; }): ReleaseType | undefined; declare function writeVersion(pkgPath: string, newVersion: string, dryRun?: boolean): void; declare function getPackageNewVersion({ name, currentVersion, releaseType, preid, suffix, }: { name: string; currentVersion: string; releaseType: ReleaseType; preid: string | undefined; suffix: string | undefined; }): string; declare function updateLernaVersion({ rootDir, versionMode, version, dryRun, }: { rootDir: string; versionMode?: VersionMode; version: string; dryRun?: boolean; }): void; declare function extractVersionFromPackageTag(tag: string): string | null; declare function isPrerelease(version?: string): boolean; declare function isStableReleaseType(releaseType: ReleaseType): boolean; declare function isPrereleaseReleaseType(releaseType: ReleaseType): boolean; declare function isGraduating(currentVersion: string, releaseType: ReleaseType): boolean; declare function getPreid(version: string): string | null; declare function isChangedPreid(currentVersion: string, targetPreid?: string): boolean; declare function getBumpedPackageIndependently({ pkg, dryRun, }: { pkg: PackageBase; dryRun: boolean; }): { bumped: true; newVersion: string; oldVersion: string; } | { bumped: false; }; declare function confirmBump({ versionMode, config, packages, force, currentVersion, newVersion, dryRun, }: { versionMode: VersionMode; config: ResolvedRelizyConfig; packages: PackageBase[]; force: boolean; currentVersion?: string; newVersion?: string; dryRun: boolean; }): Promise; declare function getBumpedIndependentPackages({ packages, dryRun, }: { packages: PackageBase[]; dryRun: boolean; }): PackageBase[]; /** * Determines if prerelease tags should be filtered out when searching for tags. * Returns true when the current version is stable AND we're not graduating to stable. * * This prevents beta/prerelease tags from being used as the base for stable version bumps. * * @example * shouldFilterPrereleaseTags('4.1.1', false) // true - stable version, not graduating * shouldFilterPrereleaseTags('4.1.1-beta.0', true) // false - graduating to stable * shouldFilterPrereleaseTags('4.1.1-beta.0', false) // false - prerelease version */ declare function shouldFilterPrereleaseTags(currentVersion: string, graduating: boolean): boolean; /** * Extracts a semantic version from a git tag. * Supports multiple tag formats: * - v1.2.3 β†’ 1.2.3 * - 1.2.3 β†’ 1.2.3 * - package-name@1.2.3 β†’ 1.2.3 * - v1.2.3-beta.0 β†’ 1.2.3-beta.0 * * @param tag - The git tag to extract version from * @param packageName - Optional package name for independent mode tags (e.g., "pkg-name@1.2.3") * @returns The extracted version string or null if invalid */ declare function extractVersionFromTag(tag: string, packageName?: string): string | null; /** * Checks if a tag's version is compatible with the current version. * A tag is compatible if its major version is less than or equal to the current major version. * * This prevents accidentally using tags from future major versions (e.g., v5.0.0-beta.0) * when bumping a current stable version (e.g., 4.1.1 β†’ 4.1.2). * * @param payload - The payload to check * @param payload.currentVersion - The current package version * @param payload.releaseType - The release type * @param payload.preid - The pre-release identifier * @param payload.sha - The sha of the commit * @returns true if the tag version's major is <= current major version * * @example * isTagVersionCompatibleWithCurrent('4.1.1', '4.1.0') // true - same major * isTagVersionCompatibleWithCurrent('5.0.0-beta.0', '4.1.1') // false - newer major * isTagVersionCompatibleWithCurrent('3.9.9', '4.1.1') // true - older major */ declare function getCanaryVersion({ currentVersion, releaseType, preid, sha, }: { currentVersion: string; releaseType: 'major' | 'minor' | 'patch' | undefined; preid?: string; sha: string; }): string; declare function isTagVersionCompatibleWithCurrent(tagVersion: string, currentVersion: string): boolean; type VersionMode = 'unified' | 'independent' | 'selective'; type GitProvider = 'github' | 'gitlab' | 'bitbucket'; type PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun'; /** * PACAKGE TYPES */ interface ReadPackage { /** * Package name */ name: string; /** * Package path */ path: string; /** * Current version */ version: string; /** * Package path */ private: boolean; } interface PackageBase extends ReadPackage { /** * From tag */ fromTag: string; /** * Commits */ commits: GitCommit[]; /** * New version */ newVersion?: string; /** * Dependencies */ dependencies: string[]; /** * Reason for bumping */ reason?: 'commits' | 'dependency' | 'graduation'; /** * Dependency chain */ dependencyChain?: string[]; } /** * OTHERS */ interface PublishResponse { publishedPackages: PackageBase[]; } interface BumpResultTruthy { /** * Old version */ oldVersion?: string; /** * New version */ newVersion?: string; /** * Tag name */ fromTag?: string; /** * Root package */ rootPackage?: RootPackage; /** * Bumped packages */ bumpedPackages: (PackageBase & { oldVersion: string; })[]; /** * Bumped */ bumped: true; } interface BumpResultFalsy { /** * Bumped */ bumped: false; } type BumpResult = BumpResultTruthy | BumpResultFalsy; interface PostedRelease { /** * Release name */ name: string; /** * Release tag */ tag: string; /** * Is prerelease */ prerelease: boolean; /** * Release version */ version: string; } interface SocialNetworkResult { /** * Social platform name (e.g., 'twitter', 'slack') */ platform: string; /** * Whether the post was successful */ success: boolean; /** * Error message if the post failed */ error?: string; } interface SocialResult { /** * Results for each social platform */ results: SocialNetworkResult[]; /** * Whether any of the social posts had errors */ hasErrors: boolean; } interface ProviderReleaseResult { /** * Detected Git provider */ detectedProvider: GitProvider; /** * Posted releases */ postedReleases: PostedRelease[]; /** * Error message if provider release failed */ error?: string; } type PrCommentMode = 'append' | 'update'; interface PrCommentConfig { /** * PR comment mode * @default 'append' */ mode?: PrCommentMode; } type PrCommentStatus = 'success' | 'no-release' | 'failed'; interface ReleaseContext { /** * Release status */ status: PrCommentStatus; /** * Bump result (available when status is 'success') */ bumpResult?: BumpResultTruthy; /** * Git tags created during release */ tags?: string[]; /** * Error message (available when status is 'failed') */ error?: string; } interface MonorepoConfig { /** * Version mode for the monorepo. */ versionMode: VersionMode; /** * Glob pattern matching for packages to bump. */ packages: string[]; /** * Package names to ignore. * @default [] */ ignorePackageNames?: string[]; /** * Include private packages (with `"private": true` in package.json) in * bump and changelog operations. Private packages remain excluded from * publish, provider-release, and pr-comment regardless of this flag. * @default false */ includePrivates?: boolean; } type ConfigType = { /** * Title */ title: string; /** * Semver bump type */ semver?: SemverBumpType; } | boolean; interface BumpConfig { /** * Release type (e.g. 'major', 'minor', 'patch', 'prerelease', 'prepatch', 'preminor', 'premajor') * @default 'release' */ type?: ReleaseType; /** * Prerelease identifier (e.g. 'beta', 'alpha') */ preid?: string; /** * Check if there are any changes to commit before bumping. * @default true */ clean?: boolean; /** * Include dependencies when bumping. * @default ['dependencies'] */ dependencyTypes?: ('dependencies' | 'devDependencies' | 'peerDependencies')[]; /** * Skip confirmation prompt about bumping packages * @default true */ yes?: boolean; } interface BumpOptions extends BumpConfig { /** * Run without side effects * @default false */ dryRun?: boolean; /** * Use custom config */ config?: ResolvedRelizyConfig; /** * Set log level */ logLevel?: LogLevel; /** * Bump all packages even if there are no commits * @default false */ force?: boolean; /** * Custom config file name (e.g. `relizy.standalone` for `relizy.standalone.config.ts`) * @default 'relizy' */ configName?: string; /** * Custom suffix for prerelease versions - replace the last .X with .suffix (e.g. 1.0.0-beta.0 -> 1.0.0-beta.suffix) */ suffix?: string; /** * Publish a canary release from the current commit * @default false */ canary?: boolean; /** * Include private packages in the bump. * @default false */ includePrivates?: boolean; } interface ChangelogConfig { /** * Command to format the changelog (e.g. `prettier --write CHANGELOG.md`). */ formatCmd?: string; /** * Generate changelog at root level with all changes * @default true */ rootChangelog?: boolean; /** * Include commit body in the changelog. * @default true */ includeCommitBody?: boolean; } interface ChangelogOptions extends ChangelogConfig { /** * Start tag */ from?: string; /** * End tag */ to?: string; /** * Run without side effects * @default false */ dryRun?: boolean; /** * Bump result */ bumpResult?: BumpResultTruthy; /** * Use custom config */ config?: ResolvedRelizyConfig; /** * Set log level */ logLevel?: LogLevel; /** * Custom config file name (e.g. `relizy.standalone` for `relizy.standalone.config.ts`) * @default 'relizy' */ configName?: string; /** * Generate changelog for all packages even if there are no commits * @default false */ force: boolean; /** * Custom suffix for prerelease versions - replace the last .X with .suffix (e.g. 1.0.0-beta.0 -> 1.0.0-beta.suffix) */ suffix?: string; /** * Include private packages in the changelog generation. * @default false */ includePrivates?: boolean; } interface ProviderReleaseOptions { /** * Start tag */ from?: string; /** * End tag */ to?: string; /** * Git token (GitHub or GitLab) */ token?: string; /** * Use custom config */ config?: ResolvedRelizyConfig; /** * Custom config file name (e.g. `relizy.standalone` for `relizy.standalone.config.ts`) * @default 'relizy' */ configName?: string; /** * Git provider * @default 'github' */ provider?: GitProvider; /** * Bump result */ bumpResult?: BumpResultTruthy; /** * Set log level */ logLevel?: LogLevel; /** * Run without side effects * @default false */ dryRun?: boolean; /** * Skip safety check * @default true */ safetyCheck?: boolean; /** * Generate changelog for all packages even if there are no commits * @default false */ force: boolean; /** * Custom suffix for prerelease versions - replace the last .X with .suffix (e.g. 1.0.0-beta.0 -> 1.0.0-beta.suffix) */ suffix?: string; /** * Override AI configuration for this run * true = force-enable AI, false = force-disable AI, undefined = use config */ ai?: boolean; } interface SocialOptions { /** * Start tag */ from?: string; /** * End tag */ to?: string; /** * Use custom config */ config?: ResolvedRelizyConfig; /** * Custom config file name (e.g. `relizy.standalone` for `relizy.standalone.config.ts`) * @default 'relizy' */ configName?: string; /** * Bump result (contains release information) */ bumpResult?: BumpResultTruthy; /** * Set log level */ logLevel?: LogLevel; /** * Run without side effects * @default false */ dryRun?: boolean; /** * Skip safety check * @default true */ safetyCheck?: boolean; /** * Override AI configuration for this run * true = force-enable AI, false = force-disable AI, undefined = use config */ ai?: boolean; } type PublishConfig = ChangelogConfig$1['publish'] & { /** * Package manager (e.g. `pnpm`, `npm`, `yarn` or `bun`) */ packageManager?: PackageManager; /** * NPM registry URL (e.g. `https://registry.npmjs.org/`) */ registry?: string; /** * NPM tag (e.g. `latest`) */ tag?: string; /** * NPM access level (e.g. `public` or `restricted`) */ access?: 'public' | 'restricted'; /** * NPM OTP (e.g. `123456`) */ otp?: string; /** * Glob pattern matching for packages to publish */ packages?: string[]; /** * Command to build your packages before publishing (e.g. `pnpm build`) */ buildCmd?: string; /** * NPM token (e.g. `123456`) - only supported for pnpm and npm */ token?: string; /** * Skip safety check * @default true */ safetyCheck?: boolean; }; interface PublishOptions extends PublishConfig { /** * Run without side effects * @default false */ dryRun?: boolean; /** * Use custom config */ config?: ResolvedRelizyConfig; /** * Bump result */ bumpResult?: BumpResultTruthy; /** * Set log level */ logLevel?: LogLevel; /** * Custom config file name (e.g. `relizy.standalone` for `relizy.standalone.config.ts`) * @default 'relizy' */ configName?: string; /** * Custom suffix for prerelease versions - replace the last .X with .suffix (e.g. 1.0.0-beta.0 -> 1.0.0-beta.suffix) */ suffix?: string; /** * Bump even if there are no commits * @default false */ force?: boolean; } interface ReleaseConfig { /** * Commit changes and create tag * @default true */ commit?: boolean; /** * Push changes to your repository (commit and tag(s)) * @default true */ push?: boolean; /** * Generate changelog files (CHANGELOG.md) * @default true */ changelog?: boolean; /** * Publish release to your repository (github or gitlab) * @default true */ providerRelease?: boolean; /** * Publish release to your registry * @default true */ publish?: boolean; /** * Skip git verification while committing by using --no-verify flag * @default true */ noVerify?: boolean; /** * Determine if the working directory is clean and if it is not clean, exit * @default false */ clean?: boolean; /** * Create tag * @default true */ gitTag?: boolean; /** * Post release announcements to social media platforms * @default false */ social?: boolean; /** * Post release announcements to social media platforms * @default false */ prComment?: boolean; } interface ReleaseOptions extends ReleaseConfig, BumpConfig, ChangelogConfig, PublishConfig { /** * Run without side effects * @default false */ dryRun?: boolean; /** */ from?: string; /** */ to?: string; /** */ token?: string; /** */ logLevel?: LogLevel; /** * @default 'relizy' */ configName?: string; /** * Bump even if there are no commits * @default false */ force?: boolean; /** * Custom suffix for prerelease versions - replace the last .X with .suffix (e.g. 1.0.0-beta.0 -> 1.0.0-beta.suffix) */ suffix?: string; /** * Git provider (e.g. `github` or `gitlab`) * @default 'github' */ provider?: GitProvider; /** * Skip safety check * @default true */ safetyCheck?: boolean; /** * NPM token (e.g. "123456") */ publishToken?: string; /** * Override PR/MR number for PR comment features */ prNumber?: number; /** * Publish a canary release from the current commit * @default false */ canary?: boolean; /** * Include private packages in bump and changelog operations. * @default false */ includePrivates?: boolean; /** * Override AI configuration for this run * true = force-enable AI, false = force-disable AI, undefined = use config */ ai?: boolean; } interface TwitterCredentials { /** * Twitter API Key (Consumer Key) */ apiKey?: string; /** * Twitter API Secret (Consumer Secret) */ apiKeySecret?: string; /** * Twitter Access Token */ accessToken?: string; /** * Twitter Access Token Secret */ accessTokenSecret?: string; } interface TwitterSocialConfig { /** * Enable Twitter posting * @default false */ enabled?: boolean; /** * Skip Twitter posting for prerelease versions (alpha, beta, rc, etc.) * Only stable versions will be posted to Twitter * @default true */ onlyStable?: boolean; /** * Custom message template * Available variables: {{projectName}}, {{newVersion}}, {{changelog}}, {{releaseUrl}}, {{changelogUrl}} * @default 'πŸ“£ {{projectName}} {{newVersion}} is out!\n\n{{changelog}}\n\n{{releaseUrl}}\n{{changelogUrl}}' */ template?: string; /** * Twitter credentials (optional - falls back to environment variables) */ credentials?: TwitterCredentials; /** * Maximum length of the tweet * @default 280 */ postMaxLength?: number; } interface SlackCredentials { /** * Slack Bot Token or User OAuth Token (starts with `xoxb-`). * Required scopes: chat:write (and chat:write.public for public channels without bot invite). * Env fallback: SLACK_TOKEN, RELIZY_SLACK_TOKEN. * Ignored when social.slack.webhookUrl is set (webhook takes priority). */ token?: string; } interface SlackSocialConfig { /** * Enable Slack posting * @default false */ enabled?: boolean; /** * Skip Slack posting for prerelease versions (alpha, beta, rc, etc.) * Only stable versions will be posted to Slack * @default true */ onlyStable?: boolean; /** * Slack channel ID or name (e.g., "#releases" or "C1234567890"). * Required when using token-based authentication. * Ignored (with warning) when webhookUrl is set β€” the channel is baked into the webhook URL. */ channel?: string; /** * Slack Incoming Webhook URL. When set, takes priority over token-based auth. * Env fallback: SLACK_WEBHOOK_URL, RELIZY_SLACK_WEBHOOK_URL. * See: https://api.slack.com/messaging/webhooks */ webhookUrl?: string; /** * Custom message template * Available variables: {{projectName}}, {{newVersion}}, {{changelog}}, {{releaseUrl}}, {{changelogUrl}}, {{contributors}} */ template?: string; /** * Slack credentials (optional - falls back to environment variables) */ credentials?: SlackCredentials; /** * Maximum length (in characters) of the changelog rendered inside the Slack message. * Slack's per-section-block limit is 3000; default 2500 leaves margin for emoji/formatting. * @default 2500 */ postMaxLength?: number; /** * Hide the contributors block in Slack messages. * If config.noAuthors is true globally, contributors are always hidden regardless of this setting. * @default false */ noAuthors?: boolean; /** * Hide the packages block (list of bumped packages with their before β†’ after versions). * @default false */ noPackages?: boolean; } type AIProviderName = 'claude-code'; interface ClaudeCodeProviderOptions { /** * Anthropic API key. * Fallback env: `RELIZY_ANTHROPIC_API_KEY`, `ANTHROPIC_API_KEY`. */ apiKey?: string; /** * Claude Code OAuth token. * Fallback env: `RELIZY_CLAUDE_CODE_OAUTH_TOKEN`, `CLAUDE_CODE_OAUTH_TOKEN`. */ oauthToken?: string; /** * Model id or alias (e.g. `haiku`, `sonnet`, `opus`, or a versioned id). * @default 'haiku' */ model?: string; } type AIPromptTarget = 'providerRelease' | 'twitter' | 'slack'; type AISystemPromptOverrides = Partial>; interface AITargetConfig { /** * Enable AI for this target * @default false */ enabled?: boolean; } interface AISocialConfig { /** * Twitter-specific AI activation */ twitter?: AITargetConfig; /** * Slack-specific AI activation */ slack?: AITargetConfig; } interface AIConfig { /** * AI provider name * @default 'claude-code' */ provider?: AIProviderName; /** * Provider-specific options, keyed by provider name. */ providers?: { 'claude-code'?: ClaudeCodeProviderOptions; }; /** * Output language (ISO 639-1 code or plain English name). * @default 'en' */ language?: string; /** * Behavior when the provider call fails. * - `raw`: fall back to the unmodified changelog body. * - `fail`: re-throw the error. * @default 'raw' */ fallback?: 'raw' | 'fail'; /** * Extra directives appended to every built-in system prompt. * @example 'Always use emojis in the changelog' */ extraGuidelines?: string; /** * Full replacement of the built-in system prompts. * When set, the extraGuidelines and base prompts are ignored for that target. */ systemPromptOverrides?: AISystemPromptOverrides; /** * Enable AI rewriting for GitHub/GitLab release notes. */ providerRelease?: AITargetConfig; /** * Enable AI rewriting for social media posts. */ social?: AISocialConfig; } interface SocialConfig { /** * Twitter configuration */ twitter?: TwitterSocialConfig; /** * Slack configuration */ slack?: SlackSocialConfig; /** * URL to full changelog (e.g., https://example.com/changelog) * This URL will be included in social media posts to allow users to view the complete changelog */ changelogUrl?: string; } interface TwitterOptions { /** * Release information */ version: string; /** * Project name */ projectName: string; /** * Changelog content */ changelog: string; /** * Release URL (GitHub/GitLab) */ releaseUrl?: string; /** * Full changelog URL (e.g., https://example.com/changelog) */ changelogUrl?: string; /** * Twitter credentials (all fields required) */ credentials: { apiKey: string; apiKeySecret: string; accessToken: string; accessTokenSecret: string; }; /** * Custom Twitter message template */ template: string; /** * Run without side effects * @default false */ dryRun?: boolean; /** * Maximum length of the tweet * @default 280 */ postMaxLength: number; } interface SlackOptions { /** * Release information */ version: string; /** * Project name */ projectName: string; /** * Changelog content */ changelog: string; /** * Release URL (GitHub/GitLab) */ releaseUrl?: string; /** * Full changelog URL (e.g., https://example.com/changelog) */ changelogUrl?: string; /** * Slack channel ID or name. Required when using token-based auth. */ channel?: string; /** * Slack Bot Token. Ignored if webhookUrl is set. */ token?: string; /** * Slack Incoming Webhook URL. Takes priority over token. */ webhookUrl?: string; /** * Custom message template */ template?: string; /** * Maximum chars of the changelog rendered in the message. * @default 2500 */ postMaxLength?: number; /** * Contributor names (plain strings, no email/handle). Empty array or undefined β†’ no contributors block. */ contributors?: string[]; /** * Packages bumped in this release. Empty array or undefined β†’ no packages block. */ packages?: SlackPackageEntry[]; /** * Run without side effects * @default false */ dryRun?: boolean; } /** * A bumped-package entry in a Slack message (derived from PackageBumpEntry in src/core/packages.ts). * Duplicated here to avoid a coreβ†’types back-import; kept in sync by design. */ interface SlackPackageEntry { name: string; oldVersion?: string; newVersion?: string; version: string; hasTransition: boolean; } interface TemplatesConfig { /** * Commit message template (title). * * Default in `unified`/`selective` modes: `'chore(release): bump version to {{newVersion}}'`. * Default in `independent` mode (when not customized): `'chore(release): bump {{packageCount}} packages'`. * * Available variables: * - `{{newVersion}}` β€” in `independent` mode, comma-separated list of bumped `name@version` (legacy behavior); otherwise the new version. * - `{{packageCount}}` β€” number of bumped packages. * - `{{packageNames}}` β€” comma-separated list of bumped package names. * - `{{packageList}}` β€” comma-separated list of bumped `name@version`. * - `{{rootVersion}}` β€” version from the root `package.json`. */ commitMessage?: string; /** * Commit message body template. When defined, it is passed as the commit body. * * Default in `unified`/`selective` modes: `undefined` (no body). * Default in `independent` mode (when `commitMessage` and `commitBody` are not customized): `'{{packageList}}'`. * * Same variables as `commitMessage`. */ commitBody?: string; /** * Tag message template * @default 'Bump version to {{newVersion}}' * Available variables: {{newVersion}} */ tagMessage?: string; /** * Not used with "independent" version mode * @default 'v{{newVersion}}' * Available variables: {{newVersion}} */ tagBody?: string; /** * Empty changelog content * @default 'No relevant changes for this release' */ emptyChangelogContent?: string; /** * Twitter message template * Available variables: {{projectName}}, {{newVersion}}, {{changelog}}, {{releaseUrl}}, {{changelogUrl}} * @default 'πŸ“£ {{projectName}} {{newVersion}} is out!\n\n{{changelog}}\n\n{{releaseUrl}}\n{{changelogUrl}}' */ twitterMessage?: string; /** * Slack message template (optional - if not provided, uses rich blocks format) * Available variables: {{projectName}}, {{newVersion}}, {{changelog}}, {{releaseUrl}}, {{changelogUrl}} * @default undefined */ slackMessage?: string; /** * Changelog section title template * Available variables: {{oldVersion}}, {{newVersion}}, {{date}} * @default '{{oldVersion}}...{{newVersion}}' */ changelogTitle?: string; } interface RepoConfig { /** * Git domain (e.g. `github.com`) */ domain?: string; /** * Git repository (e.g. `user/repo`) */ repo?: string; /** * Git token */ token?: string; /** * Git provider (e.g. `github` or `gitlab`) * @default 'github' */ provider?: GitProvider; } type HookType = 'before' | 'success' | 'error'; type HookStep = 'bump' | 'changelog' | 'commit-and-tag' | 'provider-release' | 'publish' | 'push' | 'release' | 'social' | 'twitter' | 'slack'; /** * API tokens configuration */ interface TokensConfig { /** * registry token for publishing * Environment variables: NPM_TOKEN, RELIZY_NPM_TOKEN, NODE_AUTH_TOKEN */ registry?: string; /** * GitHub token for creating releases * Environment variables: GITHUB_TOKEN, GH_TOKEN, RELIZY_GITHUB_TOKEN */ github?: string; /** * GitLab token for creating releases * Environment variables: GITLAB_TOKEN, GITLAB_API_TOKEN, CI_JOB_TOKEN, RELIZY_GITLAB_TOKEN */ gitlab?: string; /** * Twitter API credentials for posting tweets * Environment variables: TWITTER_API_KEY, TWITTER_API_KEY_SECRET, TWITTER_ACCESS_TOKEN, TWITTER_ACCESS_TOKEN_SECRET * Or with RELIZY_ prefix: RELIZY_TWITTER_API_KEY, etc. */ twitter?: { apiKey?: string; apiKeySecret?: string; accessToken?: string; accessTokenSecret?: string; }; /** * Slack bot token for posting messages * Environment variables: SLACK_TOKEN, RELIZY_SLACK_TOKEN */ slack?: string; /** * AI provider credentials */ ai?: { 'claude-code'?: { apiKey?: string; oauthToken?: string; }; }; } /** * Hooks configuration * Useful to run custom scripts before, after a step or on error */ type HookConfig = { [K in `${HookType}:${HookStep}`]?: string | ((config: ResolvedRelizyConfig, dryRun: boolean) => any); } & { 'generate:changelog'?: (config: ResolvedRelizyConfig, dryRun: boolean, params: { commits: GitCommit[]; changelog: string; }) => string | void | null | undefined | Promise; }; /** * Relizy configuration * @see https://relizy.dev/config/overview */ interface RelizyConfig extends Partial> { /** * Project name * Useful for tweet and slack posts */ projectName?: string; types?: Record; /** * Current working directory * @default process.cwd() */ cwd?: string; /** * Start tag */ from?: string; /** * End tag */ to?: string; /** * Monorepo config */ monorepo?: MonorepoConfig; /** * Repo config */ repo?: RepoConfig; /** * Templates config */ templates?: TemplatesConfig; /** * Bump config */ bump?: BumpConfig; /** * Publish config */ publish?: PublishConfig; /** * Changelog config */ changelog?: ChangelogConfig; /** * Release config */ release?: ReleaseConfig; /** * Social media configuration */ social?: SocialConfig; /** * PR comment configuration */ prComment?: PrCommentConfig; /** * API tokens configuration */ tokens?: TokensConfig; /** * AI-powered changelog and release notes configuration */ ai?: AIConfig; /** * Hooks config */ hooks?: HookConfig; /** * Set log level * @default 'default' */ logLevel?: LogLevel; /** * Global safety check. The safety check will verify if tokens or others required for release are set (depends on the release options) * @default true */ safetyCheck?: boolean; } declare function bump(options?: Partial): Promise; declare function changelog(options?: Partial): Promise; interface PrCommentOptions { prNumber?: number; dryRun?: boolean; logLevel?: LogLevel; configName?: string; /** Pre-loaded config to avoid redundant config loading when called from release flow */ config?: ResolvedRelizyConfig; /** Release context passed from the release flow. When absent, standalone mode is used. */ releaseContext?: ReleaseContext; } interface CommentBodyParams { config: ResolvedRelizyConfig; branch: string; date: string; releaseContext?: ReleaseContext; /** Fallback packages for standalone CLI mode (no releaseContext) */ packages?: Array<{ name: string; version: string; }>; /** Fallback root version for standalone CLI mode */ rootVersion?: string; } declare function buildCommentBody(params: CommentBodyParams): string; declare function prComment(options?: PrCommentOptions): Promise; declare function providerReleaseSafetyCheck({ config, provider }: { config: ResolvedRelizyConfig; provider?: GitProvider | null; }): Promise; declare function providerRelease(options?: Partial): Promise; declare function publishSafetyCheck({ config }: { config: ResolvedRelizyConfig; }): Promise; declare function publish(options?: Partial): Promise<{ publishedPackages: PackageBase[]; } | undefined>; declare function release(options?: Partial): Promise; declare function socialSafetyCheck({ config }: { config: ResolvedRelizyConfig; }): Promise; declare function social(options?: Partial): Promise; 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 }; export type { AIConfig, AIPromptTarget, AIProviderName, AISocialConfig, AISystemPromptOverrides, AITargetConfig, BumpConfig, BumpOptions, BumpResult, BumpResultFalsy, BumpResultTruthy, ChangelogConfig, ChangelogInclude, 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 };