relizy 1.3.0-beta.2 → 1.3.0-beta.3
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 +10 -7
- package/dist/index.d.mts +152 -3
- package/dist/index.d.ts +152 -3
- package/dist/index.mjs +1 -1
- package/dist/shared/{relizy.CupzvopJ.mjs → relizy.BHnDdNQq.mjs} +409 -87
- package/package.json +7 -2
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 {
|
|
8
|
+
import { al as isInCI, am 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.BHnDdNQq.mjs';
|
|
9
9
|
import '@maz-ui/utils';
|
|
10
10
|
import 'c12';
|
|
11
11
|
import 'changelogen';
|
|
@@ -124,7 +124,7 @@ program.command("publish").description("Publish packages to registry").option("-
|
|
|
124
124
|
process.exit(1);
|
|
125
125
|
}
|
|
126
126
|
});
|
|
127
|
-
program.command("provider-release").description("Publish release to git provider (github or gitlab)").option("--from <ref>", "Start commit reference").option("--to <ref>", "End commit reference").option("--token <token>", "Provider token").option("--provider <provider>", "Git provider (github or gitlab)").action(async (options) => {
|
|
127
|
+
program.command("provider-release").description("Publish release to git provider (github or gitlab)").option("--from <ref>", "Start commit reference").option("--to <ref>", "End commit reference").option("--token <token>", "Provider token").option("--provider <provider>", "Git provider (github or gitlab)").option("--ai", "Force-enable AI for release notes").option("--no-ai", "Force-disable AI for release notes").action(async (options) => {
|
|
128
128
|
try {
|
|
129
129
|
await providerRelease({
|
|
130
130
|
token: options.token,
|
|
@@ -134,14 +134,15 @@ program.command("provider-release").description("Publish release to git provider
|
|
|
134
134
|
dryRun: program.opts().dryRun,
|
|
135
135
|
logLevel: program.opts().logLevel,
|
|
136
136
|
configName: program.opts().config,
|
|
137
|
-
safetyCheck: hasCliFlag("--no-safety-check") ? false : void 0
|
|
137
|
+
safetyCheck: hasCliFlag("--no-safety-check") ? false : void 0,
|
|
138
|
+
ai: hasCliFlag("--ai") ? true : hasCliFlag("--no-ai") ? false : void 0
|
|
138
139
|
});
|
|
139
140
|
} catch (error) {
|
|
140
141
|
logger.error("Failed to publish release -", error);
|
|
141
142
|
process.exit(1);
|
|
142
143
|
}
|
|
143
144
|
});
|
|
144
|
-
program.command("social").description("Post release announcements to social media platforms").option("--from <ref>", "Start commit reference").option("--to <ref>", "End commit reference").action(async (options) => {
|
|
145
|
+
program.command("social").description("Post release announcements to social media platforms").option("--from <ref>", "Start commit reference").option("--to <ref>", "End commit reference").option("--ai", "Force-enable AI for social posts").option("--no-ai", "Force-disable AI for social posts").action(async (options) => {
|
|
145
146
|
try {
|
|
146
147
|
await social({
|
|
147
148
|
from: options.from,
|
|
@@ -149,7 +150,8 @@ program.command("social").description("Post release announcements to social medi
|
|
|
149
150
|
dryRun: program.opts().dryRun,
|
|
150
151
|
logLevel: program.opts().logLevel,
|
|
151
152
|
configName: program.opts().config,
|
|
152
|
-
safetyCheck: hasCliFlag("--no-safety-check") ? false : void 0
|
|
153
|
+
safetyCheck: hasCliFlag("--no-safety-check") ? false : void 0,
|
|
154
|
+
ai: hasCliFlag("--ai") ? true : hasCliFlag("--no-ai") ? false : void 0
|
|
153
155
|
});
|
|
154
156
|
} catch {
|
|
155
157
|
process.exit(1);
|
|
@@ -168,7 +170,7 @@ program.command("pr-comment").description("Post or re-post a PR comment with rel
|
|
|
168
170
|
process.exit(1);
|
|
169
171
|
}
|
|
170
172
|
});
|
|
171
|
-
program.command("release").description("Complete release workflow (bump + changelog + commit + tag + push to remote + publish release)").option("--major", "Bump major version").option("--minor", "Bump minor version").option("--patch", "Bump patch version").option("--prerelease", "Bump prerelease version").option("--premajor", "Bump premajor version").option("--preminor", "Bump preminor version").option("--prepatch", "Bump prepatch version").option("--preid <id>", "Prerelease identifier (alpha, beta, rc, etc.)").option("--suffix <suffix>", "Custom suffix for prerelease versions - replace the last .X with .suffix (e.g. 1.0.0-beta.0 -> 1.0.0-beta.suffix)").option("--from <ref>", "Start commit reference").option("--to <ref>", "End commit reference").option("--no-push", "Skip push changes and tags to remote").option("--no-provider-release", "Skip release creation (GitHub/GitLab)").option("--no-publish", "Skip npm publish").option("--registry <url>", "Custom npm registry URL").option("--tag <tag>", "Publish with specific tag (default: latest for stable, next for prerelease)").option("--access <type>", "Package access level (public or restricted)").option("--otp <code>", "One-time password for 2FA").option("--no-verify", "Skip git hooks during commit").option("--format-cmd <cmd>", 'Command to format CHANGELOG files after generation (e.g. "pnpm lint")').option("--build-cmd <cmd>", 'Command to build packages before publish (e.g. "pnpm build")').option("--no-root-changelog", "Skip generation of root changelog file").option("--token <token>", "Git token (github or gitlab)").option("--force", "Bump even if there are no commits").option("--no-clean", "Skip check if the working directory is clean").option("--no-commit", "Skip commit and tag").option("--no-git-tag", "Skip tag creation").option("--no-changelog", "Skip changelog generation files").option("--provider <provider>", "Git provider (github or gitlab)").option("--no-social", "Skip social media posting").option("--no-pr-comment", "Skip PR comment posting").option("--yes", "Skip confirmation prompt about bumping packages").option("--publish-token <token>", 'NPM token (e.g. "123456") - only supported for pnpm and npm').option("--canary", "Publish a canary release from the current commit").option("--include-private", "Include private packages in bump and changelog phases").action(async (options) => {
|
|
173
|
+
program.command("release").description("Complete release workflow (bump + changelog + commit + tag + push to remote + publish release)").option("--major", "Bump major version").option("--minor", "Bump minor version").option("--patch", "Bump patch version").option("--prerelease", "Bump prerelease version").option("--premajor", "Bump premajor version").option("--preminor", "Bump preminor version").option("--prepatch", "Bump prepatch version").option("--preid <id>", "Prerelease identifier (alpha, beta, rc, etc.)").option("--suffix <suffix>", "Custom suffix for prerelease versions - replace the last .X with .suffix (e.g. 1.0.0-beta.0 -> 1.0.0-beta.suffix)").option("--from <ref>", "Start commit reference").option("--to <ref>", "End commit reference").option("--no-push", "Skip push changes and tags to remote").option("--no-provider-release", "Skip release creation (GitHub/GitLab)").option("--no-publish", "Skip npm publish").option("--registry <url>", "Custom npm registry URL").option("--tag <tag>", "Publish with specific tag (default: latest for stable, next for prerelease)").option("--access <type>", "Package access level (public or restricted)").option("--otp <code>", "One-time password for 2FA").option("--no-verify", "Skip git hooks during commit").option("--format-cmd <cmd>", 'Command to format CHANGELOG files after generation (e.g. "pnpm lint")').option("--build-cmd <cmd>", 'Command to build packages before publish (e.g. "pnpm build")').option("--no-root-changelog", "Skip generation of root changelog file").option("--token <token>", "Git token (github or gitlab)").option("--force", "Bump even if there are no commits").option("--no-clean", "Skip check if the working directory is clean").option("--no-commit", "Skip commit and tag").option("--no-git-tag", "Skip tag creation").option("--no-changelog", "Skip changelog generation files").option("--provider <provider>", "Git provider (github or gitlab)").option("--no-social", "Skip social media posting").option("--no-pr-comment", "Skip PR comment posting").option("--yes", "Skip confirmation prompt about bumping packages").option("--publish-token <token>", 'NPM token (e.g. "123456") - only supported for pnpm and npm').option("--canary", "Publish a canary release from the current commit").option("--include-private", "Include private packages in bump and changelog phases").option("--ai", "Force-enable AI for release notes and social posts").option("--no-ai", "Force-disable AI for release notes and social posts").action(async (options) => {
|
|
172
174
|
try {
|
|
173
175
|
await release({
|
|
174
176
|
type: getReleaseType(options),
|
|
@@ -203,7 +205,8 @@ program.command("release").description("Complete release workflow (bump + change
|
|
|
203
205
|
safetyCheck: hasCliFlag("--no-safety-check") ? false : void 0,
|
|
204
206
|
social: hasCliFlag("--no-social") ? false : void 0,
|
|
205
207
|
prComment: hasCliFlag("--no-pr-comment") ? false : void 0,
|
|
206
|
-
prNumber: program.opts().prNumber
|
|
208
|
+
prNumber: program.opts().prNumber,
|
|
209
|
+
ai: hasCliFlag("--ai") ? true : hasCliFlag("--no-ai") ? false : void 0
|
|
207
210
|
});
|
|
208
211
|
} catch (error) {
|
|
209
212
|
logger.error("Failed to release -", error);
|
package/dist/index.d.mts
CHANGED
|
@@ -42,6 +42,12 @@ declare function getDefaultConfig(): {
|
|
|
42
42
|
accessTokenSecret: string | undefined;
|
|
43
43
|
};
|
|
44
44
|
slack: string | undefined;
|
|
45
|
+
ai: {
|
|
46
|
+
'claude-code': {
|
|
47
|
+
apiKey: string | undefined;
|
|
48
|
+
oauthToken: string | undefined;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
45
51
|
};
|
|
46
52
|
scopeMap: {};
|
|
47
53
|
release: Required<ReleaseConfig>;
|
|
@@ -57,6 +63,7 @@ declare function getDefaultConfig(): {
|
|
|
57
63
|
};
|
|
58
64
|
};
|
|
59
65
|
prComment: Required<PrCommentConfig>;
|
|
66
|
+
ai: AIConfig;
|
|
60
67
|
logLevel: LogLevel;
|
|
61
68
|
safetyCheck: boolean;
|
|
62
69
|
};
|
|
@@ -205,6 +212,40 @@ declare function createGitlabRelease({ config, release, dryRun, }: {
|
|
|
205
212
|
}): Promise<GitlabReleaseResponse>;
|
|
206
213
|
declare function gitlab(options?: Partial<ProviderReleaseOptions>): Promise<PostedRelease[]>;
|
|
207
214
|
|
|
215
|
+
interface Reference {
|
|
216
|
+
type: 'hash' | 'issue' | 'pull-request';
|
|
217
|
+
value: string;
|
|
218
|
+
}
|
|
219
|
+
declare function buildCompareLink({ config, from, to, isFirstCommit }: {
|
|
220
|
+
config: ResolvedRelizyConfig;
|
|
221
|
+
from: string;
|
|
222
|
+
to: string;
|
|
223
|
+
isFirstCommit: boolean;
|
|
224
|
+
}): string;
|
|
225
|
+
declare function buildChangelogBody({ commits, config, minify }: {
|
|
226
|
+
commits: GitCommit[];
|
|
227
|
+
config: ResolvedRelizyConfig;
|
|
228
|
+
minify?: boolean;
|
|
229
|
+
}): string;
|
|
230
|
+
declare function buildContributors({ commits, config }: {
|
|
231
|
+
commits: GitCommit[];
|
|
232
|
+
config: ResolvedRelizyConfig;
|
|
233
|
+
}): Promise<string>;
|
|
234
|
+
declare function generateMarkDown({ commits, config, from, to, isFirstCommit, minify, }: {
|
|
235
|
+
commits: GitCommit[];
|
|
236
|
+
config: ResolvedRelizyConfig;
|
|
237
|
+
from: string;
|
|
238
|
+
to: string;
|
|
239
|
+
isFirstCommit: boolean;
|
|
240
|
+
minify?: boolean;
|
|
241
|
+
}): Promise<string>;
|
|
242
|
+
declare function parseChangelogMarkdown(contents: string): {
|
|
243
|
+
releases: {
|
|
244
|
+
version?: string;
|
|
245
|
+
body: string;
|
|
246
|
+
}[];
|
|
247
|
+
};
|
|
248
|
+
|
|
208
249
|
declare function detectPackageManager(cwd?: string): PackageManager;
|
|
209
250
|
declare function determinePublishTag(version: string, configTag?: string): string;
|
|
210
251
|
declare function getPackagesToPublishInSelectiveMode(sortedPackages: PackageBase[], rootVersion: string | undefined): PackageBase[];
|
|
@@ -937,6 +978,11 @@ interface ProviderReleaseOptions {
|
|
|
937
978
|
* Custom suffix for prerelease versions - replace the last .X with .suffix (e.g. 1.0.0-beta.0 -> 1.0.0-beta.suffix)
|
|
938
979
|
*/
|
|
939
980
|
suffix?: string;
|
|
981
|
+
/**
|
|
982
|
+
* Override AI configuration for this run
|
|
983
|
+
* true = force-enable AI, false = force-disable AI, undefined = use config
|
|
984
|
+
*/
|
|
985
|
+
ai?: boolean;
|
|
940
986
|
}
|
|
941
987
|
interface SocialOptions {
|
|
942
988
|
/**
|
|
@@ -974,6 +1020,11 @@ interface SocialOptions {
|
|
|
974
1020
|
* @default true
|
|
975
1021
|
*/
|
|
976
1022
|
safetyCheck?: boolean;
|
|
1023
|
+
/**
|
|
1024
|
+
* Override AI configuration for this run
|
|
1025
|
+
* true = force-enable AI, false = force-disable AI, undefined = use config
|
|
1026
|
+
*/
|
|
1027
|
+
ai?: boolean;
|
|
977
1028
|
}
|
|
978
1029
|
type PublishConfig = ChangelogConfig$1['publish'] & {
|
|
979
1030
|
/**
|
|
@@ -1158,6 +1209,11 @@ interface ReleaseOptions extends ReleaseConfig, BumpConfig, ChangelogConfig, Pub
|
|
|
1158
1209
|
* @default false
|
|
1159
1210
|
*/
|
|
1160
1211
|
includePrivates?: boolean;
|
|
1212
|
+
/**
|
|
1213
|
+
* Override AI configuration for this run
|
|
1214
|
+
* true = force-enable AI, false = force-disable AI, undefined = use config
|
|
1215
|
+
*/
|
|
1216
|
+
ai?: boolean;
|
|
1161
1217
|
}
|
|
1162
1218
|
interface TwitterCredentials {
|
|
1163
1219
|
/**
|
|
@@ -1238,6 +1294,86 @@ interface SlackSocialConfig {
|
|
|
1238
1294
|
*/
|
|
1239
1295
|
credentials?: SlackCredentials;
|
|
1240
1296
|
}
|
|
1297
|
+
type AIProviderName = 'claude-code';
|
|
1298
|
+
interface ClaudeCodeProviderOptions {
|
|
1299
|
+
/**
|
|
1300
|
+
* Anthropic API key.
|
|
1301
|
+
* Fallback env: `RELIZY_ANTHROPIC_API_KEY`, `ANTHROPIC_API_KEY`.
|
|
1302
|
+
*/
|
|
1303
|
+
apiKey?: string;
|
|
1304
|
+
/**
|
|
1305
|
+
* Claude Code OAuth token.
|
|
1306
|
+
* Fallback env: `RELIZY_CLAUDE_CODE_OAUTH_TOKEN`, `CLAUDE_CODE_OAUTH_TOKEN`.
|
|
1307
|
+
*/
|
|
1308
|
+
oauthToken?: string;
|
|
1309
|
+
/**
|
|
1310
|
+
* Model id or alias (e.g. `haiku`, `sonnet`, `opus`, or a versioned id).
|
|
1311
|
+
* @default 'haiku'
|
|
1312
|
+
*/
|
|
1313
|
+
model?: string;
|
|
1314
|
+
}
|
|
1315
|
+
type AIPromptTarget = 'providerRelease' | 'twitter' | 'slack';
|
|
1316
|
+
type AISystemPromptOverrides = Partial<Record<AIPromptTarget, string>>;
|
|
1317
|
+
interface AITargetConfig {
|
|
1318
|
+
/**
|
|
1319
|
+
* Enable AI for this target
|
|
1320
|
+
* @default false
|
|
1321
|
+
*/
|
|
1322
|
+
enabled?: boolean;
|
|
1323
|
+
}
|
|
1324
|
+
interface AISocialConfig {
|
|
1325
|
+
/**
|
|
1326
|
+
* Twitter-specific AI activation
|
|
1327
|
+
*/
|
|
1328
|
+
twitter?: AITargetConfig;
|
|
1329
|
+
/**
|
|
1330
|
+
* Slack-specific AI activation
|
|
1331
|
+
*/
|
|
1332
|
+
slack?: AITargetConfig;
|
|
1333
|
+
}
|
|
1334
|
+
interface AIConfig {
|
|
1335
|
+
/**
|
|
1336
|
+
* AI provider name
|
|
1337
|
+
* @default 'claude-code'
|
|
1338
|
+
*/
|
|
1339
|
+
provider?: AIProviderName;
|
|
1340
|
+
/**
|
|
1341
|
+
* Provider-specific options, keyed by provider name.
|
|
1342
|
+
*/
|
|
1343
|
+
providers?: {
|
|
1344
|
+
'claude-code'?: ClaudeCodeProviderOptions;
|
|
1345
|
+
};
|
|
1346
|
+
/**
|
|
1347
|
+
* Output language (ISO 639-1 code or plain English name).
|
|
1348
|
+
* @default 'en'
|
|
1349
|
+
*/
|
|
1350
|
+
language?: string;
|
|
1351
|
+
/**
|
|
1352
|
+
* Behavior when the provider call fails.
|
|
1353
|
+
* - `raw`: fall back to the unmodified changelog body.
|
|
1354
|
+
* - `fail`: re-throw the error.
|
|
1355
|
+
* @default 'raw'
|
|
1356
|
+
*/
|
|
1357
|
+
fallback?: 'raw' | 'fail';
|
|
1358
|
+
/**
|
|
1359
|
+
* Extra directives appended to every built-in system prompt.
|
|
1360
|
+
* @example 'Always use emojis in the changelog'
|
|
1361
|
+
*/
|
|
1362
|
+
extraGuidelines?: string;
|
|
1363
|
+
/**
|
|
1364
|
+
* Full replacement of the built-in system prompts.
|
|
1365
|
+
* When set, the extraGuidelines and base prompts are ignored for that target.
|
|
1366
|
+
*/
|
|
1367
|
+
systemPromptOverrides?: AISystemPromptOverrides;
|
|
1368
|
+
/**
|
|
1369
|
+
* Enable AI rewriting for GitHub/GitLab release notes.
|
|
1370
|
+
*/
|
|
1371
|
+
providerRelease?: AITargetConfig;
|
|
1372
|
+
/**
|
|
1373
|
+
* Enable AI rewriting for social media posts.
|
|
1374
|
+
*/
|
|
1375
|
+
social?: AISocialConfig;
|
|
1376
|
+
}
|
|
1241
1377
|
interface SocialConfig {
|
|
1242
1378
|
/**
|
|
1243
1379
|
* Twitter configuration
|
|
@@ -1453,6 +1589,15 @@ interface TokensConfig {
|
|
|
1453
1589
|
* Environment variables: SLACK_TOKEN, RELIZY_SLACK_TOKEN
|
|
1454
1590
|
*/
|
|
1455
1591
|
slack?: string;
|
|
1592
|
+
/**
|
|
1593
|
+
* AI provider credentials
|
|
1594
|
+
*/
|
|
1595
|
+
ai?: {
|
|
1596
|
+
'claude-code'?: {
|
|
1597
|
+
apiKey?: string;
|
|
1598
|
+
oauthToken?: string;
|
|
1599
|
+
};
|
|
1600
|
+
};
|
|
1456
1601
|
}
|
|
1457
1602
|
/**
|
|
1458
1603
|
* Hooks configuration
|
|
@@ -1533,6 +1678,10 @@ interface RelizyConfig extends Partial<Omit<ChangelogConfig$1, 'output' | 'templ
|
|
|
1533
1678
|
* API tokens configuration
|
|
1534
1679
|
*/
|
|
1535
1680
|
tokens?: TokensConfig;
|
|
1681
|
+
/**
|
|
1682
|
+
* AI-powered changelog and release notes configuration
|
|
1683
|
+
*/
|
|
1684
|
+
ai?: AIConfig;
|
|
1536
1685
|
/**
|
|
1537
1686
|
* Hooks config
|
|
1538
1687
|
*/
|
|
@@ -1582,7 +1731,7 @@ declare function prComment(options?: PrCommentOptions): Promise<boolean>;
|
|
|
1582
1731
|
declare function providerReleaseSafetyCheck({ config, provider }: {
|
|
1583
1732
|
config: ResolvedRelizyConfig;
|
|
1584
1733
|
provider?: GitProvider | null;
|
|
1585
|
-
}): void
|
|
1734
|
+
}): Promise<void>;
|
|
1586
1735
|
declare function providerRelease(options?: Partial<ProviderReleaseOptions>): Promise<ProviderReleaseResult>;
|
|
1587
1736
|
|
|
1588
1737
|
declare function publishSafetyCheck({ config }: {
|
|
@@ -1599,5 +1748,5 @@ declare function socialSafetyCheck({ config }: {
|
|
|
1599
1748
|
}): Promise<void>;
|
|
1600
1749
|
declare function social(options?: Partial<SocialOptions>): Promise<SocialResult>;
|
|
1601
1750
|
|
|
1602
|
-
export { NEW_PACKAGE_MARKER, PR_COMMENT_MARKER, buildCommentBody, 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, 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, parseGitRemoteUrl, postPrComment, postReleaseToSlack, postReleaseToTwitter, prComment, providerRelease, providerReleaseSafetyCheck, publish, publishPackage, publishSafetyCheck, pushCommitAndTags, readPackageJson, readPackages, release, resolveTags, rollbackModifiedFiles, shouldFilterPrereleaseTags, social, socialSafetyCheck, topologicalSort, updateLernaVersion, writeChangelogToFile, writeVersion };
|
|
1603
|
-
export type { BumpConfig, BumpOptions, BumpResult, BumpResultFalsy, BumpResultTruthy, ChangelogConfig, ChangelogOptions, ConfigType, GitProvider, GitlabRelease, GitlabReleaseResponse, HookConfig, HookStep, HookType, MonorepoConfig, PackageBase, PackageManager, PostedRelease, PrCommentConfig, PrCommentMode, PrCommentOptions, PrCommentStatus, ProviderReleaseOptions, ProviderReleaseResult, PublishConfig, PublishOptions, PublishResponse, PullRequestInfo, ReadPackage, ReleaseConfig, ReleaseContext, ReleaseOptions, RelizyConfig, RepoConfig, ResolvedConfig, ResolvedRelizyConfig, ResolvedTags, ResolvedTwitterCredentials, RootPackage, SlackCredentials, SlackOptions, SlackSocialConfig, SocialConfig, SocialNetworkResult, SocialOptions, SocialResult, Step, TemplatesConfig, TokensConfig, TwitterCredentials, TwitterOptions, TwitterSocialConfig, VersionMode };
|
|
1751
|
+
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, parseChangelogMarkdown, parseGitRemoteUrl, postPrComment, postReleaseToSlack, postReleaseToTwitter, prComment, providerRelease, providerReleaseSafetyCheck, publish, publishPackage, publishSafetyCheck, pushCommitAndTags, readPackageJson, readPackages, release, resolveTags, rollbackModifiedFiles, shouldFilterPrereleaseTags, social, socialSafetyCheck, topologicalSort, updateLernaVersion, writeChangelogToFile, writeVersion };
|
|
1752
|
+
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -42,6 +42,12 @@ declare function getDefaultConfig(): {
|
|
|
42
42
|
accessTokenSecret: string | undefined;
|
|
43
43
|
};
|
|
44
44
|
slack: string | undefined;
|
|
45
|
+
ai: {
|
|
46
|
+
'claude-code': {
|
|
47
|
+
apiKey: string | undefined;
|
|
48
|
+
oauthToken: string | undefined;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
45
51
|
};
|
|
46
52
|
scopeMap: {};
|
|
47
53
|
release: Required<ReleaseConfig>;
|
|
@@ -57,6 +63,7 @@ declare function getDefaultConfig(): {
|
|
|
57
63
|
};
|
|
58
64
|
};
|
|
59
65
|
prComment: Required<PrCommentConfig>;
|
|
66
|
+
ai: AIConfig;
|
|
60
67
|
logLevel: LogLevel;
|
|
61
68
|
safetyCheck: boolean;
|
|
62
69
|
};
|
|
@@ -205,6 +212,40 @@ declare function createGitlabRelease({ config, release, dryRun, }: {
|
|
|
205
212
|
}): Promise<GitlabReleaseResponse>;
|
|
206
213
|
declare function gitlab(options?: Partial<ProviderReleaseOptions>): Promise<PostedRelease[]>;
|
|
207
214
|
|
|
215
|
+
interface Reference {
|
|
216
|
+
type: 'hash' | 'issue' | 'pull-request';
|
|
217
|
+
value: string;
|
|
218
|
+
}
|
|
219
|
+
declare function buildCompareLink({ config, from, to, isFirstCommit }: {
|
|
220
|
+
config: ResolvedRelizyConfig;
|
|
221
|
+
from: string;
|
|
222
|
+
to: string;
|
|
223
|
+
isFirstCommit: boolean;
|
|
224
|
+
}): string;
|
|
225
|
+
declare function buildChangelogBody({ commits, config, minify }: {
|
|
226
|
+
commits: GitCommit[];
|
|
227
|
+
config: ResolvedRelizyConfig;
|
|
228
|
+
minify?: boolean;
|
|
229
|
+
}): string;
|
|
230
|
+
declare function buildContributors({ commits, config }: {
|
|
231
|
+
commits: GitCommit[];
|
|
232
|
+
config: ResolvedRelizyConfig;
|
|
233
|
+
}): Promise<string>;
|
|
234
|
+
declare function generateMarkDown({ commits, config, from, to, isFirstCommit, minify, }: {
|
|
235
|
+
commits: GitCommit[];
|
|
236
|
+
config: ResolvedRelizyConfig;
|
|
237
|
+
from: string;
|
|
238
|
+
to: string;
|
|
239
|
+
isFirstCommit: boolean;
|
|
240
|
+
minify?: boolean;
|
|
241
|
+
}): Promise<string>;
|
|
242
|
+
declare function parseChangelogMarkdown(contents: string): {
|
|
243
|
+
releases: {
|
|
244
|
+
version?: string;
|
|
245
|
+
body: string;
|
|
246
|
+
}[];
|
|
247
|
+
};
|
|
248
|
+
|
|
208
249
|
declare function detectPackageManager(cwd?: string): PackageManager;
|
|
209
250
|
declare function determinePublishTag(version: string, configTag?: string): string;
|
|
210
251
|
declare function getPackagesToPublishInSelectiveMode(sortedPackages: PackageBase[], rootVersion: string | undefined): PackageBase[];
|
|
@@ -937,6 +978,11 @@ interface ProviderReleaseOptions {
|
|
|
937
978
|
* Custom suffix for prerelease versions - replace the last .X with .suffix (e.g. 1.0.0-beta.0 -> 1.0.0-beta.suffix)
|
|
938
979
|
*/
|
|
939
980
|
suffix?: string;
|
|
981
|
+
/**
|
|
982
|
+
* Override AI configuration for this run
|
|
983
|
+
* true = force-enable AI, false = force-disable AI, undefined = use config
|
|
984
|
+
*/
|
|
985
|
+
ai?: boolean;
|
|
940
986
|
}
|
|
941
987
|
interface SocialOptions {
|
|
942
988
|
/**
|
|
@@ -974,6 +1020,11 @@ interface SocialOptions {
|
|
|
974
1020
|
* @default true
|
|
975
1021
|
*/
|
|
976
1022
|
safetyCheck?: boolean;
|
|
1023
|
+
/**
|
|
1024
|
+
* Override AI configuration for this run
|
|
1025
|
+
* true = force-enable AI, false = force-disable AI, undefined = use config
|
|
1026
|
+
*/
|
|
1027
|
+
ai?: boolean;
|
|
977
1028
|
}
|
|
978
1029
|
type PublishConfig = ChangelogConfig$1['publish'] & {
|
|
979
1030
|
/**
|
|
@@ -1158,6 +1209,11 @@ interface ReleaseOptions extends ReleaseConfig, BumpConfig, ChangelogConfig, Pub
|
|
|
1158
1209
|
* @default false
|
|
1159
1210
|
*/
|
|
1160
1211
|
includePrivates?: boolean;
|
|
1212
|
+
/**
|
|
1213
|
+
* Override AI configuration for this run
|
|
1214
|
+
* true = force-enable AI, false = force-disable AI, undefined = use config
|
|
1215
|
+
*/
|
|
1216
|
+
ai?: boolean;
|
|
1161
1217
|
}
|
|
1162
1218
|
interface TwitterCredentials {
|
|
1163
1219
|
/**
|
|
@@ -1238,6 +1294,86 @@ interface SlackSocialConfig {
|
|
|
1238
1294
|
*/
|
|
1239
1295
|
credentials?: SlackCredentials;
|
|
1240
1296
|
}
|
|
1297
|
+
type AIProviderName = 'claude-code';
|
|
1298
|
+
interface ClaudeCodeProviderOptions {
|
|
1299
|
+
/**
|
|
1300
|
+
* Anthropic API key.
|
|
1301
|
+
* Fallback env: `RELIZY_ANTHROPIC_API_KEY`, `ANTHROPIC_API_KEY`.
|
|
1302
|
+
*/
|
|
1303
|
+
apiKey?: string;
|
|
1304
|
+
/**
|
|
1305
|
+
* Claude Code OAuth token.
|
|
1306
|
+
* Fallback env: `RELIZY_CLAUDE_CODE_OAUTH_TOKEN`, `CLAUDE_CODE_OAUTH_TOKEN`.
|
|
1307
|
+
*/
|
|
1308
|
+
oauthToken?: string;
|
|
1309
|
+
/**
|
|
1310
|
+
* Model id or alias (e.g. `haiku`, `sonnet`, `opus`, or a versioned id).
|
|
1311
|
+
* @default 'haiku'
|
|
1312
|
+
*/
|
|
1313
|
+
model?: string;
|
|
1314
|
+
}
|
|
1315
|
+
type AIPromptTarget = 'providerRelease' | 'twitter' | 'slack';
|
|
1316
|
+
type AISystemPromptOverrides = Partial<Record<AIPromptTarget, string>>;
|
|
1317
|
+
interface AITargetConfig {
|
|
1318
|
+
/**
|
|
1319
|
+
* Enable AI for this target
|
|
1320
|
+
* @default false
|
|
1321
|
+
*/
|
|
1322
|
+
enabled?: boolean;
|
|
1323
|
+
}
|
|
1324
|
+
interface AISocialConfig {
|
|
1325
|
+
/**
|
|
1326
|
+
* Twitter-specific AI activation
|
|
1327
|
+
*/
|
|
1328
|
+
twitter?: AITargetConfig;
|
|
1329
|
+
/**
|
|
1330
|
+
* Slack-specific AI activation
|
|
1331
|
+
*/
|
|
1332
|
+
slack?: AITargetConfig;
|
|
1333
|
+
}
|
|
1334
|
+
interface AIConfig {
|
|
1335
|
+
/**
|
|
1336
|
+
* AI provider name
|
|
1337
|
+
* @default 'claude-code'
|
|
1338
|
+
*/
|
|
1339
|
+
provider?: AIProviderName;
|
|
1340
|
+
/**
|
|
1341
|
+
* Provider-specific options, keyed by provider name.
|
|
1342
|
+
*/
|
|
1343
|
+
providers?: {
|
|
1344
|
+
'claude-code'?: ClaudeCodeProviderOptions;
|
|
1345
|
+
};
|
|
1346
|
+
/**
|
|
1347
|
+
* Output language (ISO 639-1 code or plain English name).
|
|
1348
|
+
* @default 'en'
|
|
1349
|
+
*/
|
|
1350
|
+
language?: string;
|
|
1351
|
+
/**
|
|
1352
|
+
* Behavior when the provider call fails.
|
|
1353
|
+
* - `raw`: fall back to the unmodified changelog body.
|
|
1354
|
+
* - `fail`: re-throw the error.
|
|
1355
|
+
* @default 'raw'
|
|
1356
|
+
*/
|
|
1357
|
+
fallback?: 'raw' | 'fail';
|
|
1358
|
+
/**
|
|
1359
|
+
* Extra directives appended to every built-in system prompt.
|
|
1360
|
+
* @example 'Always use emojis in the changelog'
|
|
1361
|
+
*/
|
|
1362
|
+
extraGuidelines?: string;
|
|
1363
|
+
/**
|
|
1364
|
+
* Full replacement of the built-in system prompts.
|
|
1365
|
+
* When set, the extraGuidelines and base prompts are ignored for that target.
|
|
1366
|
+
*/
|
|
1367
|
+
systemPromptOverrides?: AISystemPromptOverrides;
|
|
1368
|
+
/**
|
|
1369
|
+
* Enable AI rewriting for GitHub/GitLab release notes.
|
|
1370
|
+
*/
|
|
1371
|
+
providerRelease?: AITargetConfig;
|
|
1372
|
+
/**
|
|
1373
|
+
* Enable AI rewriting for social media posts.
|
|
1374
|
+
*/
|
|
1375
|
+
social?: AISocialConfig;
|
|
1376
|
+
}
|
|
1241
1377
|
interface SocialConfig {
|
|
1242
1378
|
/**
|
|
1243
1379
|
* Twitter configuration
|
|
@@ -1453,6 +1589,15 @@ interface TokensConfig {
|
|
|
1453
1589
|
* Environment variables: SLACK_TOKEN, RELIZY_SLACK_TOKEN
|
|
1454
1590
|
*/
|
|
1455
1591
|
slack?: string;
|
|
1592
|
+
/**
|
|
1593
|
+
* AI provider credentials
|
|
1594
|
+
*/
|
|
1595
|
+
ai?: {
|
|
1596
|
+
'claude-code'?: {
|
|
1597
|
+
apiKey?: string;
|
|
1598
|
+
oauthToken?: string;
|
|
1599
|
+
};
|
|
1600
|
+
};
|
|
1456
1601
|
}
|
|
1457
1602
|
/**
|
|
1458
1603
|
* Hooks configuration
|
|
@@ -1533,6 +1678,10 @@ interface RelizyConfig extends Partial<Omit<ChangelogConfig$1, 'output' | 'templ
|
|
|
1533
1678
|
* API tokens configuration
|
|
1534
1679
|
*/
|
|
1535
1680
|
tokens?: TokensConfig;
|
|
1681
|
+
/**
|
|
1682
|
+
* AI-powered changelog and release notes configuration
|
|
1683
|
+
*/
|
|
1684
|
+
ai?: AIConfig;
|
|
1536
1685
|
/**
|
|
1537
1686
|
* Hooks config
|
|
1538
1687
|
*/
|
|
@@ -1582,7 +1731,7 @@ declare function prComment(options?: PrCommentOptions): Promise<boolean>;
|
|
|
1582
1731
|
declare function providerReleaseSafetyCheck({ config, provider }: {
|
|
1583
1732
|
config: ResolvedRelizyConfig;
|
|
1584
1733
|
provider?: GitProvider | null;
|
|
1585
|
-
}): void
|
|
1734
|
+
}): Promise<void>;
|
|
1586
1735
|
declare function providerRelease(options?: Partial<ProviderReleaseOptions>): Promise<ProviderReleaseResult>;
|
|
1587
1736
|
|
|
1588
1737
|
declare function publishSafetyCheck({ config }: {
|
|
@@ -1599,5 +1748,5 @@ declare function socialSafetyCheck({ config }: {
|
|
|
1599
1748
|
}): Promise<void>;
|
|
1600
1749
|
declare function social(options?: Partial<SocialOptions>): Promise<SocialResult>;
|
|
1601
1750
|
|
|
1602
|
-
export { NEW_PACKAGE_MARKER, PR_COMMENT_MARKER, buildCommentBody, 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, 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, parseGitRemoteUrl, postPrComment, postReleaseToSlack, postReleaseToTwitter, prComment, providerRelease, providerReleaseSafetyCheck, publish, publishPackage, publishSafetyCheck, pushCommitAndTags, readPackageJson, readPackages, release, resolveTags, rollbackModifiedFiles, shouldFilterPrereleaseTags, social, socialSafetyCheck, topologicalSort, updateLernaVersion, writeChangelogToFile, writeVersion };
|
|
1603
|
-
export type { BumpConfig, BumpOptions, BumpResult, BumpResultFalsy, BumpResultTruthy, ChangelogConfig, ChangelogOptions, ConfigType, GitProvider, GitlabRelease, GitlabReleaseResponse, HookConfig, HookStep, HookType, MonorepoConfig, PackageBase, PackageManager, PostedRelease, PrCommentConfig, PrCommentMode, PrCommentOptions, PrCommentStatus, ProviderReleaseOptions, ProviderReleaseResult, PublishConfig, PublishOptions, PublishResponse, PullRequestInfo, ReadPackage, ReleaseConfig, ReleaseContext, ReleaseOptions, RelizyConfig, RepoConfig, ResolvedConfig, ResolvedRelizyConfig, ResolvedTags, ResolvedTwitterCredentials, RootPackage, SlackCredentials, SlackOptions, SlackSocialConfig, SocialConfig, SocialNetworkResult, SocialOptions, SocialResult, Step, TemplatesConfig, TokensConfig, TwitterCredentials, TwitterOptions, TwitterSocialConfig, VersionMode };
|
|
1751
|
+
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, parseChangelogMarkdown, parseGitRemoteUrl, postPrComment, postReleaseToSlack, postReleaseToTwitter, prComment, providerRelease, providerReleaseSafetyCheck, publish, publishPackage, publishSafetyCheck, pushCommitAndTags, readPackageJson, readPackages, release, resolveTags, rollbackModifiedFiles, shouldFilterPrereleaseTags, social, socialSafetyCheck, topologicalSort, updateLernaVersion, writeChangelogToFile, writeVersion };
|
|
1752
|
+
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 };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { af as NEW_PACKAGE_MARKER, Y as PR_COMMENT_MARKER, L as buildChangelogBody, a as buildCommentBody, K as buildCompareLink, M as buildContributors, b as bump, at as capReleaseTypeForZeroMajor, c as changelog, u as checkGitStatusIfDirty, aH as confirmBump, A as createCommitAndTags, I as createGitlabRelease, k as defineConfig, x as detectGitProvider, P as detectPackageManager, X as detectPullRequest, Q as determinePublishTag, av as determineReleaseType, au as determineSemverChange, ao as executeBuildCmd, an as executeFormatCmd, ak as executeHook, o as expandPackagesToBumpWithDependents, a8 as extractChangelogSummary, az as extractVersionFromPackageTag, aK as extractVersionFromTag, v as fetchGitTags, aq as filterOutPrivatePackages, V as findGitHubPR, W as findGitLabMR, a5 as formatChangelogForSlack, a6 as formatSlackMessage, ai as formatTweetMessage, i as generateChangelog, N as generateMarkDown, T as getAuthCommand, aI as getBumpedIndependentPackages, aG as getBumpedPackageIndependently, am as getCIName, aL as getCanaryVersion, E as getCurrentGitBranch, F as getCurrentGitRef, j as getDefaultConfig, n as getDependentsOf, D as getFirstCommit, q as getGitStatus, aa as getIndependentTag, ae as getLastPackageTag, ad as getLastRepoTag, ab as getLastStableTag, ac as getLastTag, z as getModifiedReleaseFilePatterns, a2 as getPackageCommits, m as getPackageDependencies, ax as getPackageNewVersion, a1 as getPackages, ar as getPackagesOrBumpedPackages, S as getPackagesToPublishInIndependentMode, R as getPackagesToPublishInSelectiveMode, aE as getPreid, a9 as getReleaseUrl, $ as getRootPackage, G as getShortCommitSha, a4 as getSlackToken, ah as getTwitterCredentials, H as github, J as gitlab, a3 as hasLernaJson, ap as isBumpedPackage, aF as isChangedPreid, aD as isGraduating, as as isGraduatingToStableBetweenVersion, al as isInCI, aA as isPrerelease, aC as isPrereleaseReleaseType, aB as isStableReleaseType, aM as isTagVersionCompatibleWithCurrent, l as loadRelizyConfig, O as parseChangelogMarkdown, y as parseGitRemoteUrl, Z as postPrComment, a7 as postReleaseToSlack, aj as postReleaseToTwitter, p as prComment, e as providerRelease, d as providerReleaseSafetyCheck, g as publish, U as publishPackage, f as publishSafetyCheck, B as pushCommitAndTags, _ as readPackageJson, a0 as readPackages, r as release, ag as resolveTags, C as rollbackModifiedFiles, aJ as shouldFilterPrereleaseTags, h as social, s as socialSafetyCheck, t as topologicalSort, ay as updateLernaVersion, w as writeChangelogToFile, aw as writeVersion } from './shared/relizy.BHnDdNQq.mjs';
|
|
2
2
|
import '@maz-ui/node';
|
|
3
3
|
import 'node:process';
|
|
4
4
|
import '@maz-ui/utils';
|
|
@@ -1885,7 +1885,13 @@ function getDefaultConfig() {
|
|
|
1885
1885
|
accessToken: process$1.env.RELIZY_TWITTER_ACCESS_TOKEN || process$1.env.TWITTER_ACCESS_TOKEN,
|
|
1886
1886
|
accessTokenSecret: process$1.env.RELIZY_TWITTER_ACCESS_TOKEN_SECRET || process$1.env.TWITTER_ACCESS_TOKEN_SECRET
|
|
1887
1887
|
},
|
|
1888
|
-
slack: process$1.env.RELIZY_SLACK_TOKEN || process$1.env.SLACK_TOKEN
|
|
1888
|
+
slack: process$1.env.RELIZY_SLACK_TOKEN || process$1.env.SLACK_TOKEN,
|
|
1889
|
+
ai: {
|
|
1890
|
+
"claude-code": {
|
|
1891
|
+
apiKey: process$1.env.RELIZY_ANTHROPIC_API_KEY || process$1.env.ANTHROPIC_API_KEY,
|
|
1892
|
+
oauthToken: process$1.env.RELIZY_CLAUDE_CODE_OAUTH_TOKEN || process$1.env.CLAUDE_CODE_OAUTH_TOKEN
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1889
1895
|
},
|
|
1890
1896
|
scopeMap: {},
|
|
1891
1897
|
release: {
|
|
@@ -1914,6 +1920,21 @@ function getDefaultConfig() {
|
|
|
1914
1920
|
prComment: {
|
|
1915
1921
|
mode: "append"
|
|
1916
1922
|
},
|
|
1923
|
+
ai: {
|
|
1924
|
+
provider: "claude-code",
|
|
1925
|
+
language: "en",
|
|
1926
|
+
fallback: "raw",
|
|
1927
|
+
providers: {
|
|
1928
|
+
"claude-code": {
|
|
1929
|
+
model: "haiku"
|
|
1930
|
+
}
|
|
1931
|
+
},
|
|
1932
|
+
providerRelease: { enabled: false },
|
|
1933
|
+
social: {
|
|
1934
|
+
twitter: { enabled: false },
|
|
1935
|
+
slack: { enabled: false }
|
|
1936
|
+
}
|
|
1937
|
+
},
|
|
1917
1938
|
logLevel: "default",
|
|
1918
1939
|
safetyCheck: true
|
|
1919
1940
|
};
|
|
@@ -2305,45 +2326,35 @@ function getShortCommitSha(cwd, length = 7) {
|
|
|
2305
2326
|
return execSync(`git rev-parse --short=${length} HEAD`, { cwd, encoding: "utf8" }).trim();
|
|
2306
2327
|
}
|
|
2307
2328
|
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
from
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2329
|
+
const CHANGELOG_RELEASE_HEAD_REGEX = /^#{2,}\s+(?:\S.*)?(v?(\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?)).*$/gm;
|
|
2330
|
+
const VERSION_REGEX = /^v?(\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?)$/;
|
|
2331
|
+
function buildCompareLink({ config, from, to, isFirstCommit }) {
|
|
2332
|
+
if (!config.repo || !from || !to) {
|
|
2333
|
+
return "";
|
|
2334
|
+
}
|
|
2335
|
+
return formatCompareChanges(to, {
|
|
2336
|
+
...config,
|
|
2337
|
+
from: isFirstCommit ? getFirstCommit(config.cwd) : from,
|
|
2338
|
+
to
|
|
2339
|
+
});
|
|
2340
|
+
}
|
|
2341
|
+
function buildChangelogBody({ commits, config, minify }) {
|
|
2316
2342
|
const typeGroups = groupBy(commits, "type");
|
|
2317
2343
|
const markdown = [];
|
|
2318
2344
|
const breakingChanges = [];
|
|
2319
|
-
const
|
|
2320
|
-
...config,
|
|
2321
|
-
from,
|
|
2322
|
-
to
|
|
2323
|
-
};
|
|
2324
|
-
const versionTitle = updatedConfig.to;
|
|
2325
|
-
const changelogTitle = (updatedConfig.templates?.changelogTitle || "{{oldVersion}}...{{newVersion}}").replace("{{oldVersion}}", updatedConfig.from).replace("{{newVersion}}", updatedConfig.to).replace("{{date}}", (/* @__PURE__ */ new Date()).toISOString().split("T")[0]);
|
|
2326
|
-
markdown.push("", `## ${changelogTitle}`, "");
|
|
2327
|
-
if (updatedConfig.repo && updatedConfig.from && versionTitle && !minify) {
|
|
2328
|
-
const formattedCompareLink = formatCompareChanges(versionTitle, {
|
|
2329
|
-
...updatedConfig,
|
|
2330
|
-
from: isFirstCommit ? getFirstCommit(updatedConfig.cwd) : updatedConfig.from
|
|
2331
|
-
});
|
|
2332
|
-
markdown.push(formattedCompareLink);
|
|
2333
|
-
}
|
|
2334
|
-
for (const type in updatedConfig.types) {
|
|
2345
|
+
for (const type in config.types) {
|
|
2335
2346
|
const group = typeGroups[type];
|
|
2336
2347
|
if (!group || group.length === 0) {
|
|
2337
2348
|
continue;
|
|
2338
2349
|
}
|
|
2339
|
-
if (typeof
|
|
2350
|
+
if (typeof config.types[type] === "boolean") {
|
|
2340
2351
|
continue;
|
|
2341
2352
|
}
|
|
2342
|
-
markdown.push("", `### ${
|
|
2353
|
+
markdown.push("", `### ${config.types[type]?.title}`, "");
|
|
2343
2354
|
for (const commit of group.reverse()) {
|
|
2344
2355
|
const line = formatCommit({
|
|
2345
2356
|
commit,
|
|
2346
|
-
config
|
|
2357
|
+
config,
|
|
2347
2358
|
minify
|
|
2348
2359
|
});
|
|
2349
2360
|
markdown.push(line);
|
|
@@ -2355,16 +2366,22 @@ async function generateMarkDown({
|
|
|
2355
2366
|
if (breakingChanges.length > 0) {
|
|
2356
2367
|
markdown.push("", "#### \u26A0\uFE0F Breaking Changes", "", ...breakingChanges);
|
|
2357
2368
|
}
|
|
2369
|
+
return convert(markdown.join("\n").trim(), true);
|
|
2370
|
+
}
|
|
2371
|
+
async function buildContributors({ commits, config }) {
|
|
2372
|
+
if (config.noAuthors) {
|
|
2373
|
+
return "";
|
|
2374
|
+
}
|
|
2358
2375
|
const _authors = /* @__PURE__ */ new Map();
|
|
2359
2376
|
for (const commit of commits) {
|
|
2360
|
-
if (!commit.author
|
|
2377
|
+
if (!commit.author) {
|
|
2361
2378
|
continue;
|
|
2362
2379
|
}
|
|
2363
2380
|
const name = formatName(commit.author.name);
|
|
2364
2381
|
if (!name || name.includes("[bot]")) {
|
|
2365
2382
|
continue;
|
|
2366
2383
|
}
|
|
2367
|
-
if (
|
|
2384
|
+
if (config.excludeAuthors && config.excludeAuthors.some(
|
|
2368
2385
|
(v) => name.includes(v) || commit.author.email?.includes(v)
|
|
2369
2386
|
)) {
|
|
2370
2387
|
continue;
|
|
@@ -2376,7 +2393,7 @@ async function generateMarkDown({
|
|
|
2376
2393
|
_authors.set(name, { email: /* @__PURE__ */ new Set([commit.author.email]), name });
|
|
2377
2394
|
}
|
|
2378
2395
|
}
|
|
2379
|
-
if (
|
|
2396
|
+
if (config.repo?.provider === "github") {
|
|
2380
2397
|
await Promise.all(
|
|
2381
2398
|
Array.from(_authors.keys(), async (authorName) => {
|
|
2382
2399
|
const meta = _authors.get(authorName);
|
|
@@ -2397,22 +2414,63 @@ async function generateMarkDown({
|
|
|
2397
2414
|
name: e[0],
|
|
2398
2415
|
...e[1]
|
|
2399
2416
|
}));
|
|
2400
|
-
if (authors.length
|
|
2401
|
-
|
|
2402
|
-
"",
|
|
2403
|
-
"### \u2764\uFE0F Contributors",
|
|
2404
|
-
"",
|
|
2405
|
-
...authors.map((i) => {
|
|
2406
|
-
const _email = [...i.email].find(
|
|
2407
|
-
(e) => !e.includes("noreply.github.com")
|
|
2408
|
-
);
|
|
2409
|
-
const email = updatedConfig.hideAuthorEmail !== true && _email ? ` <${_email}>` : "";
|
|
2410
|
-
const github = i.github ? ` ([@${i.github}](https://github.com/${i.github}))` : "";
|
|
2411
|
-
return `- ${i.name}${github || email || ""}`;
|
|
2412
|
-
})
|
|
2413
|
-
);
|
|
2417
|
+
if (authors.length === 0) {
|
|
2418
|
+
return "";
|
|
2414
2419
|
}
|
|
2415
|
-
|
|
2420
|
+
const lines = [
|
|
2421
|
+
"### \u2764\uFE0F Contributors",
|
|
2422
|
+
"",
|
|
2423
|
+
...authors.map((i) => {
|
|
2424
|
+
const _email = [...i.email].find(
|
|
2425
|
+
(e) => !e.includes("noreply.github.com")
|
|
2426
|
+
);
|
|
2427
|
+
const email = config.hideAuthorEmail !== true && _email ? ` <${_email}>` : "";
|
|
2428
|
+
const github = i.github ? ` ([@${i.github}](https://github.com/${i.github}))` : "";
|
|
2429
|
+
return `- ${i.name}${github || email || ""}`;
|
|
2430
|
+
})
|
|
2431
|
+
];
|
|
2432
|
+
return lines.join("\n");
|
|
2433
|
+
}
|
|
2434
|
+
async function generateMarkDown({
|
|
2435
|
+
commits,
|
|
2436
|
+
config,
|
|
2437
|
+
from,
|
|
2438
|
+
to,
|
|
2439
|
+
isFirstCommit,
|
|
2440
|
+
minify
|
|
2441
|
+
}) {
|
|
2442
|
+
const updatedConfig = {
|
|
2443
|
+
...config,
|
|
2444
|
+
from,
|
|
2445
|
+
to
|
|
2446
|
+
};
|
|
2447
|
+
const changelogTitle = (updatedConfig.templates?.changelogTitle || "{{oldVersion}}...{{newVersion}}").replace("{{oldVersion}}", updatedConfig.from).replace("{{newVersion}}", updatedConfig.to).replace("{{date}}", (/* @__PURE__ */ new Date()).toISOString().split("T")[0]);
|
|
2448
|
+
const title = `## ${changelogTitle}`;
|
|
2449
|
+
const compareLink = minify ? "" : buildCompareLink({ config: updatedConfig, from, to, isFirstCommit });
|
|
2450
|
+
const body = buildChangelogBody({ commits, config: updatedConfig, minify });
|
|
2451
|
+
const contributors = minify ? "" : await buildContributors({ commits, config: updatedConfig });
|
|
2452
|
+
return [title, compareLink, body, contributors].filter(Boolean).join("\n\n").trim();
|
|
2453
|
+
}
|
|
2454
|
+
function parseChangelogMarkdown(contents) {
|
|
2455
|
+
const headings = [...contents.matchAll(CHANGELOG_RELEASE_HEAD_REGEX)];
|
|
2456
|
+
const releases = [];
|
|
2457
|
+
for (let i = 0; i < headings.length; i++) {
|
|
2458
|
+
const heading = headings[i];
|
|
2459
|
+
const nextHeading = headings[i + 1];
|
|
2460
|
+
const [, title] = heading;
|
|
2461
|
+
const version = title?.match(VERSION_REGEX);
|
|
2462
|
+
const release = {
|
|
2463
|
+
version: version ? version[1] : void 0,
|
|
2464
|
+
body: contents.slice(
|
|
2465
|
+
heading?.index + (heading?.[0]?.length || 0),
|
|
2466
|
+
nextHeading?.index ?? contents.length
|
|
2467
|
+
).trim()
|
|
2468
|
+
};
|
|
2469
|
+
releases.push(release);
|
|
2470
|
+
}
|
|
2471
|
+
return {
|
|
2472
|
+
releases
|
|
2473
|
+
};
|
|
2416
2474
|
}
|
|
2417
2475
|
function getCommitBody(commit) {
|
|
2418
2476
|
if (!commit.body) {
|
|
@@ -2561,6 +2619,205 @@ ${existingChangelog}`;
|
|
|
2561
2619
|
}
|
|
2562
2620
|
}
|
|
2563
2621
|
|
|
2622
|
+
const BASE_PROMPT = `You are a release-notes rewriter.
|
|
2623
|
+
The user message contains a markdown changelog built from conventional commits, wrapped in a <changelog> tag. Your job: rewrite the content inside that tag.
|
|
2624
|
+
Never ask for clarification. Never reply with questions, greetings, or meta-commentary. Your only output is the rewritten changelog content.
|
|
2625
|
+
Never invent changes that are not in the input \u2014 if something is not mentioned, it does not exist.
|
|
2626
|
+
Never include compare links, contributor lists, or release metadata \u2014 only the content provided.
|
|
2627
|
+
Preserve exactly as given: PR and issue references like #123, commit hashes, commit scopes like **auth:**, and all markdown links.
|
|
2628
|
+
Respond with the rewritten content only \u2014 no preamble, no explanation, no surrounding code fence, no <changelog> tag.
|
|
2629
|
+
Output language: {{language}}.`;
|
|
2630
|
+
const PROVIDER_RELEASE_PROMPT = `Format the output as markdown with "### <Type>" sections matching the input (Features, Bug Fixes, etc.).
|
|
2631
|
+
Merge redundant items that describe the same change.
|
|
2632
|
+
Rewrite each bullet for end-user clarity \u2014 not "fix: typo in var name" but "Fixed X".
|
|
2633
|
+
Preserve the \u26A0\uFE0F marker on breaking items and keep the "#### \u26A0\uFE0F Breaking Changes" section if present.
|
|
2634
|
+
Purely internal commits (chore, refactor with no user-visible impact) may be dropped unless they carry meaningful information.
|
|
2635
|
+
Tone: professional, concise, public-facing release notes.`;
|
|
2636
|
+
const TWITTER_PROMPT = `Output plain text \u2014 no markdown. A leading "#" becomes a hashtag on Twitter, so avoid it.
|
|
2637
|
+
Hard maximum: {{maxLength}} characters. Never exceed it. Don't count characters \u2014 just stay concise.
|
|
2638
|
+
If the input has one change, write one substantive sentence about it (ground it in the input, never invent).
|
|
2639
|
+
If the input has multiple changes, surface 2 to 4 highlights.
|
|
2640
|
+
You produce ONLY the changelog content \u2014 the outer template will add the project name, version, and URLs around it.
|
|
2641
|
+
Tone: enthusiastic but not cringy. At most 1-2 emojis total.
|
|
2642
|
+
Do not add hashtags unless the user explicitly supplies them.`;
|
|
2643
|
+
const SLACK_PROMPT = `Format with Slack-compatible markdown: *bold*, _italic_, \`code\`, and "-" bullet lists.
|
|
2644
|
+
Keep it synthetic \u2014 3 to 8 bullets maximum.
|
|
2645
|
+
If any breaking changes are present, lead with them.
|
|
2646
|
+
Tone: factual, oriented toward an internal team audience.`;
|
|
2647
|
+
|
|
2648
|
+
function resolveAuth(config) {
|
|
2649
|
+
const providerOpts = config.ai?.providers?.["claude-code"];
|
|
2650
|
+
const tokenOpts = config.tokens?.ai?.["claude-code"];
|
|
2651
|
+
return {
|
|
2652
|
+
apiKey: providerOpts?.apiKey ?? tokenOpts?.apiKey,
|
|
2653
|
+
oauthToken: providerOpts?.oauthToken ?? tokenOpts?.oauthToken
|
|
2654
|
+
};
|
|
2655
|
+
}
|
|
2656
|
+
const claudeCodeProvider = {
|
|
2657
|
+
name: "claude-code",
|
|
2658
|
+
async safetyCheck(config) {
|
|
2659
|
+
const { apiKey, oauthToken } = resolveAuth(config);
|
|
2660
|
+
if (!apiKey && !oauthToken) {
|
|
2661
|
+
throw new Error(
|
|
2662
|
+
"No authentication credential found for claude-code provider. Set one of: ANTHROPIC_API_KEY, RELIZY_ANTHROPIC_API_KEY, CLAUDE_CODE_OAUTH_TOKEN, RELIZY_CLAUDE_CODE_OAUTH_TOKEN, or configure ai.providers['claude-code'].apiKey / oauthToken."
|
|
2663
|
+
);
|
|
2664
|
+
}
|
|
2665
|
+
try {
|
|
2666
|
+
await import('@yoloship/claude-sdk');
|
|
2667
|
+
} catch {
|
|
2668
|
+
throw new Error(
|
|
2669
|
+
"@yoloship/claude-sdk is not installed. Install it with: pnpm add -D @yoloship/claude-sdk"
|
|
2670
|
+
);
|
|
2671
|
+
}
|
|
2672
|
+
},
|
|
2673
|
+
async generate(config, request) {
|
|
2674
|
+
const { claudeRun } = await import('@yoloship/claude-sdk');
|
|
2675
|
+
const auth = resolveAuth(config);
|
|
2676
|
+
const model = config.ai?.providers?.["claude-code"]?.model;
|
|
2677
|
+
const wrappedPrompt = `<changelog>
|
|
2678
|
+
${request.prompt}
|
|
2679
|
+
</changelog>
|
|
2680
|
+
|
|
2681
|
+
Rewrite the content inside the <changelog> tag per the rules in the system prompt. Output ONLY the rewritten content, with no preamble, no explanation, no surrounding tags.`;
|
|
2682
|
+
const hasAuth = !!(auth.apiKey || auth.oauthToken);
|
|
2683
|
+
const result = await claudeRun(
|
|
2684
|
+
{
|
|
2685
|
+
systemPrompt: request.systemPrompt,
|
|
2686
|
+
prompt: wrappedPrompt,
|
|
2687
|
+
maxTurns: 1,
|
|
2688
|
+
effort: "low",
|
|
2689
|
+
disableSlashCommands: true,
|
|
2690
|
+
noSessionPersistence: true,
|
|
2691
|
+
allowedTools: [],
|
|
2692
|
+
settingSources: ["project"],
|
|
2693
|
+
...model && { model }
|
|
2694
|
+
},
|
|
2695
|
+
hasAuth ? auth : void 0
|
|
2696
|
+
);
|
|
2697
|
+
logger.verbose("Claude SDK events:", result.events?.map((e) => e.type).join(", "));
|
|
2698
|
+
return (result.output ?? "").trim();
|
|
2699
|
+
}
|
|
2700
|
+
};
|
|
2701
|
+
|
|
2702
|
+
const providers = {
|
|
2703
|
+
"claude-code": claudeCodeProvider
|
|
2704
|
+
};
|
|
2705
|
+
function getAIProvider(config) {
|
|
2706
|
+
const name = config.ai?.provider ?? "claude-code";
|
|
2707
|
+
const provider = providers[name];
|
|
2708
|
+
if (!provider) {
|
|
2709
|
+
const available = Object.keys(providers).join(", ");
|
|
2710
|
+
throw new Error(`Unknown AI provider "${name}". Available providers: ${available}`);
|
|
2711
|
+
}
|
|
2712
|
+
return provider;
|
|
2713
|
+
}
|
|
2714
|
+
|
|
2715
|
+
const PLATFORM_PROMPTS = {
|
|
2716
|
+
providerRelease: PROVIDER_RELEASE_PROMPT,
|
|
2717
|
+
twitter: TWITTER_PROMPT,
|
|
2718
|
+
slack: SLACK_PROMPT
|
|
2719
|
+
};
|
|
2720
|
+
function substitutePlaceholders(prompt, vars) {
|
|
2721
|
+
let result = prompt;
|
|
2722
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
2723
|
+
if (value !== void 0) {
|
|
2724
|
+
result = result.replaceAll(`{{${key}}}`, value);
|
|
2725
|
+
}
|
|
2726
|
+
}
|
|
2727
|
+
return result;
|
|
2728
|
+
}
|
|
2729
|
+
function assemblePrompt(config, target, maxLength) {
|
|
2730
|
+
const vars = {
|
|
2731
|
+
language: config.ai?.language ?? "en",
|
|
2732
|
+
maxLength: maxLength?.toString()
|
|
2733
|
+
};
|
|
2734
|
+
const override = config.ai?.systemPromptOverrides?.[target];
|
|
2735
|
+
if (override) {
|
|
2736
|
+
return substitutePlaceholders(override, vars);
|
|
2737
|
+
}
|
|
2738
|
+
const parts = [BASE_PROMPT, PLATFORM_PROMPTS[target]];
|
|
2739
|
+
if (config.ai?.extraGuidelines) {
|
|
2740
|
+
parts.push(config.ai.extraGuidelines);
|
|
2741
|
+
}
|
|
2742
|
+
return substitutePlaceholders(parts.join("\n\n"), vars);
|
|
2743
|
+
}
|
|
2744
|
+
function applyAIOverride(config, ai) {
|
|
2745
|
+
if (ai === void 0)
|
|
2746
|
+
return;
|
|
2747
|
+
if (!config.ai) {
|
|
2748
|
+
config.ai = {};
|
|
2749
|
+
}
|
|
2750
|
+
const aiConfig = config.ai;
|
|
2751
|
+
aiConfig.providerRelease = { enabled: ai };
|
|
2752
|
+
aiConfig.social = {
|
|
2753
|
+
twitter: { enabled: ai },
|
|
2754
|
+
slack: { enabled: ai }
|
|
2755
|
+
};
|
|
2756
|
+
}
|
|
2757
|
+
function isAIProviderReleaseEnabled(config) {
|
|
2758
|
+
return !!config.ai?.providerRelease?.enabled;
|
|
2759
|
+
}
|
|
2760
|
+
function isAISocialEnabled(config, platform) {
|
|
2761
|
+
return !!config.ai?.social?.[platform]?.enabled;
|
|
2762
|
+
}
|
|
2763
|
+
async function aiSafetyCheck({ config }) {
|
|
2764
|
+
const provider = getAIProvider(config);
|
|
2765
|
+
await provider.safetyCheck(config);
|
|
2766
|
+
}
|
|
2767
|
+
async function generateAIProviderReleaseBody({ config, rawBody }) {
|
|
2768
|
+
if (!rawBody.trim()) {
|
|
2769
|
+
logger.debug("AI skipped: empty changelog body");
|
|
2770
|
+
return rawBody;
|
|
2771
|
+
}
|
|
2772
|
+
const provider = getAIProvider(config);
|
|
2773
|
+
const systemPrompt = assemblePrompt(config, "providerRelease");
|
|
2774
|
+
logger.info(`\u2728 Rewriting release notes with AI (provider: ${provider.name})`);
|
|
2775
|
+
logger.verbose("AI system prompt:", systemPrompt);
|
|
2776
|
+
logger.verbose("AI input body:", rawBody);
|
|
2777
|
+
try {
|
|
2778
|
+
const started = Date.now();
|
|
2779
|
+
const output = await provider.generate(config, { systemPrompt, prompt: rawBody });
|
|
2780
|
+
const elapsed = Date.now() - started;
|
|
2781
|
+
logger.info(`\u2705 AI rewrite done in ${elapsed}ms (${rawBody.length} \u2192 ${output.length} chars)`);
|
|
2782
|
+
logger.verbose("AI output body:", output);
|
|
2783
|
+
return output;
|
|
2784
|
+
} catch (error) {
|
|
2785
|
+
return handleFallback(config, rawBody, error);
|
|
2786
|
+
}
|
|
2787
|
+
}
|
|
2788
|
+
async function generateAISocialChangelog({ config, rawBody, fallbackBody, platform, maxLength }) {
|
|
2789
|
+
const fallbackValue = fallbackBody ?? rawBody;
|
|
2790
|
+
if (!rawBody.trim()) {
|
|
2791
|
+
logger.debug(`AI skipped for ${platform}: empty changelog body`);
|
|
2792
|
+
return fallbackValue;
|
|
2793
|
+
}
|
|
2794
|
+
const provider = getAIProvider(config);
|
|
2795
|
+
const systemPrompt = assemblePrompt(config, platform, maxLength);
|
|
2796
|
+
const maxLengthHint = maxLength ? `, max ${maxLength} chars` : "";
|
|
2797
|
+
logger.info(`\u2728 Rewriting ${platform} post with AI (provider: ${provider.name}${maxLengthHint})`);
|
|
2798
|
+
logger.verbose(`AI system prompt (${platform}):`, systemPrompt);
|
|
2799
|
+
logger.verbose(`AI input body (${platform}):`, rawBody);
|
|
2800
|
+
try {
|
|
2801
|
+
const started = Date.now();
|
|
2802
|
+
const output = await provider.generate(config, { systemPrompt, prompt: rawBody, maxLength });
|
|
2803
|
+
const elapsed = Date.now() - started;
|
|
2804
|
+
logger.info(`\u2705 AI rewrite done for ${platform} in ${elapsed}ms (${rawBody.length} \u2192 ${output.length} chars)`);
|
|
2805
|
+
logger.verbose(`AI output body (${platform}):`, output);
|
|
2806
|
+
return output;
|
|
2807
|
+
} catch (error) {
|
|
2808
|
+
return handleFallback(config, fallbackValue, error);
|
|
2809
|
+
}
|
|
2810
|
+
}
|
|
2811
|
+
function handleFallback(config, rawBody, error) {
|
|
2812
|
+
const fallback = config.ai?.fallback ?? "raw";
|
|
2813
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2814
|
+
if (fallback === "fail") {
|
|
2815
|
+
throw new Error(`AI generation failed: ${message}`, { cause: error });
|
|
2816
|
+
}
|
|
2817
|
+
logger.warn(`AI generation failed, falling back to raw body: ${message}`);
|
|
2818
|
+
return rawBody;
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2564
2821
|
async function githubIndependentMode({
|
|
2565
2822
|
config,
|
|
2566
2823
|
dryRun,
|
|
@@ -2594,13 +2851,14 @@ async function githubIndependentMode({
|
|
|
2594
2851
|
}
|
|
2595
2852
|
const toTag = dryRun ? "HEAD" : to;
|
|
2596
2853
|
logger.debug(`Processing ${pkg.name}: ${from} \u2192 ${toTag}`);
|
|
2597
|
-
const
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2854
|
+
const isFirstCommit = from === getFirstCommit(config.cwd);
|
|
2855
|
+
const compareLink = buildCompareLink({ config, from, to, isFirstCommit });
|
|
2856
|
+
let body = buildChangelogBody({ commits: pkg.commits, config });
|
|
2857
|
+
const contributors = await buildContributors({ commits: pkg.commits, config });
|
|
2858
|
+
if (isAIProviderReleaseEnabled(config)) {
|
|
2859
|
+
body = await generateAIProviderReleaseBody({ config, rawBody: body });
|
|
2860
|
+
}
|
|
2861
|
+
const releaseBody = [compareLink, body, contributors].filter(Boolean).join("\n\n").trim();
|
|
2604
2862
|
const release = {
|
|
2605
2863
|
tag_name: to,
|
|
2606
2864
|
name: to,
|
|
@@ -2658,13 +2916,16 @@ async function githubUnified({
|
|
|
2658
2916
|
}
|
|
2659
2917
|
const newVersion = bumpResult?.newVersion || rootPackage.version;
|
|
2660
2918
|
const to = config.to || config.templates.tagBody.replace("{{newVersion}}", newVersion);
|
|
2661
|
-
const
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
});
|
|
2667
|
-
|
|
2919
|
+
const firstCommit = getFirstCommit(config.cwd);
|
|
2920
|
+
const from = config.from || rootPackage.fromTag || firstCommit;
|
|
2921
|
+
const isFirstCommit = from === firstCommit;
|
|
2922
|
+
const compareLink = buildCompareLink({ config, from, to, isFirstCommit });
|
|
2923
|
+
let body = buildChangelogBody({ commits: rootPackage.commits, config });
|
|
2924
|
+
const contributors = await buildContributors({ commits: rootPackage.commits, config });
|
|
2925
|
+
if (isAIProviderReleaseEnabled(config)) {
|
|
2926
|
+
body = await generateAIProviderReleaseBody({ config, rawBody: body });
|
|
2927
|
+
}
|
|
2928
|
+
const releaseBody = [compareLink, body, contributors].filter(Boolean).join("\n\n").trim();
|
|
2668
2929
|
const release = {
|
|
2669
2930
|
tag_name: to,
|
|
2670
2931
|
name: to,
|
|
@@ -2850,17 +3111,18 @@ async function gitlabIndependentMode({
|
|
|
2850
3111
|
continue;
|
|
2851
3112
|
}
|
|
2852
3113
|
logger.debug(`Processing ${pkg.name}: ${from} \u2192 ${to}`);
|
|
2853
|
-
const
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
});
|
|
2859
|
-
if (!changelog) {
|
|
3114
|
+
const isFirstCommit = from === getFirstCommit(config.cwd);
|
|
3115
|
+
const compareLink = buildCompareLink({ config, from, to, isFirstCommit });
|
|
3116
|
+
let body = buildChangelogBody({ commits: pkg.commits, config });
|
|
3117
|
+
const contributors = await buildContributors({ commits: pkg.commits, config });
|
|
3118
|
+
if (!body) {
|
|
2860
3119
|
logger.warn(`No changelog found for ${pkg.name}`);
|
|
2861
3120
|
continue;
|
|
2862
3121
|
}
|
|
2863
|
-
|
|
3122
|
+
if (isAIProviderReleaseEnabled(config)) {
|
|
3123
|
+
body = await generateAIProviderReleaseBody({ config, rawBody: body });
|
|
3124
|
+
}
|
|
3125
|
+
const releaseBody = [compareLink, body, contributors].filter(Boolean).join("\n\n").trim();
|
|
2864
3126
|
const release = {
|
|
2865
3127
|
tag_name: to,
|
|
2866
3128
|
name: to,
|
|
@@ -2904,13 +3166,16 @@ async function gitlabUnified({
|
|
|
2904
3166
|
logger.debug(`GitLab token: ${config.tokens.gitlab || config.repo?.token ? "\u2713 provided" : "\u2717 missing"}`);
|
|
2905
3167
|
const newVersion = bumpResult?.newVersion || rootPackage.newVersion || rootPackage.version;
|
|
2906
3168
|
const to = config.templates.tagBody.replace("{{newVersion}}", newVersion);
|
|
2907
|
-
const
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
});
|
|
2913
|
-
|
|
3169
|
+
const firstCommit = getFirstCommit(config.cwd);
|
|
3170
|
+
const from = config.from || rootPackage.fromTag || firstCommit;
|
|
3171
|
+
const isFirstCommit = from === firstCommit;
|
|
3172
|
+
const compareLink = buildCompareLink({ config, from, to, isFirstCommit });
|
|
3173
|
+
let body = buildChangelogBody({ commits: rootPackage.commits, config });
|
|
3174
|
+
const contributors = await buildContributors({ commits: rootPackage.commits, config });
|
|
3175
|
+
if (isAIProviderReleaseEnabled(config)) {
|
|
3176
|
+
body = await generateAIProviderReleaseBody({ config, rawBody: body });
|
|
3177
|
+
}
|
|
3178
|
+
const releaseBody = [compareLink, body, contributors].filter(Boolean).join("\n\n").trim();
|
|
2914
3179
|
logger.debug("Getting current branch...");
|
|
2915
3180
|
const { stdout: currentBranch } = await execPromise("git rev-parse --abbrev-ref HEAD", {
|
|
2916
3181
|
noSuccess: true,
|
|
@@ -4591,7 +4856,7 @@ ${body}`
|
|
|
4591
4856
|
return await postPrComment({ config, pr, body });
|
|
4592
4857
|
}
|
|
4593
4858
|
|
|
4594
|
-
function providerReleaseSafetyCheck({ config, provider }) {
|
|
4859
|
+
async function providerReleaseSafetyCheck({ config, provider }) {
|
|
4595
4860
|
if (!config.safetyCheck || !config.release.providerRelease) {
|
|
4596
4861
|
logger.debug("Safety check disabled or provider release disabled");
|
|
4597
4862
|
return;
|
|
@@ -4614,6 +4879,9 @@ function providerReleaseSafetyCheck({ config, provider }) {
|
|
|
4614
4879
|
if (!token) {
|
|
4615
4880
|
throw new Error(`No token provided for ${internalProvider} - The release will not be published - Please refer to the documentation: https://louismazel.github.io/relizy/guide/installation#environment-setup`);
|
|
4616
4881
|
}
|
|
4882
|
+
if (isAIProviderReleaseEnabled(config)) {
|
|
4883
|
+
await aiSafetyCheck({ config });
|
|
4884
|
+
}
|
|
4617
4885
|
logger.info("provider release config checked successfully");
|
|
4618
4886
|
}
|
|
4619
4887
|
async function providerRelease(options = {}) {
|
|
@@ -4631,13 +4899,14 @@ async function providerRelease(options = {}) {
|
|
|
4631
4899
|
safetyCheck: options.safetyCheck
|
|
4632
4900
|
}
|
|
4633
4901
|
});
|
|
4902
|
+
applyAIOverride(config, options.ai);
|
|
4634
4903
|
const dryRun = options.dryRun ?? false;
|
|
4635
4904
|
logger.debug(`Dry run: ${dryRun}`);
|
|
4636
4905
|
logger.debug(`Version mode: ${config.monorepo?.versionMode || "standalone"}`);
|
|
4637
4906
|
let detectedProvider = null;
|
|
4638
4907
|
try {
|
|
4639
4908
|
detectedProvider = options.provider || detectGitProvider();
|
|
4640
|
-
providerReleaseSafetyCheck({ config, provider: detectedProvider });
|
|
4909
|
+
await providerReleaseSafetyCheck({ config, provider: detectedProvider });
|
|
4641
4910
|
await executeHook("before:provider-release", config, dryRun);
|
|
4642
4911
|
logger.start("Start provider release");
|
|
4643
4912
|
if (!detectedProvider) {
|
|
@@ -4824,6 +5093,17 @@ async function publish(options = {}) {
|
|
|
4824
5093
|
}
|
|
4825
5094
|
}
|
|
4826
5095
|
|
|
5096
|
+
function computeTwitterChangelogBudget({
|
|
5097
|
+
template,
|
|
5098
|
+
projectName,
|
|
5099
|
+
version,
|
|
5100
|
+
releaseUrl,
|
|
5101
|
+
changelogUrl,
|
|
5102
|
+
postMaxLength
|
|
5103
|
+
}) {
|
|
5104
|
+
const overhead = template.replace("{{projectName}}", projectName).replace("{{newVersion}}", version).replace("{{releaseUrl}}", releaseUrl ?? "").replace("{{changelogUrl}}", changelogUrl ?? "").replace("{{changelog}}", "").length;
|
|
5105
|
+
return Math.max(0, postMaxLength - overhead);
|
|
5106
|
+
}
|
|
4827
5107
|
async function socialSafetyCheck({ config }) {
|
|
4828
5108
|
try {
|
|
4829
5109
|
const socialMediaDisabled = !config.release.social && !config.social.twitter.enabled && !config.social.slack.enabled;
|
|
@@ -4873,6 +5153,9 @@ async function socialSafetyCheck({ config }) {
|
|
|
4873
5153
|
throw new Error("Slack channel not found");
|
|
4874
5154
|
}
|
|
4875
5155
|
}
|
|
5156
|
+
if (isAISocialEnabled(config, "twitter") || isAISocialEnabled(config, "slack")) {
|
|
5157
|
+
await aiSafetyCheck({ config });
|
|
5158
|
+
}
|
|
4876
5159
|
logger.info("Social config checked successfully");
|
|
4877
5160
|
} catch (error) {
|
|
4878
5161
|
logger.error("Error during social safety check:", getErrorMessage(error));
|
|
@@ -5031,6 +5314,7 @@ async function social(options = {}) {
|
|
|
5031
5314
|
logLevel: options.logLevel
|
|
5032
5315
|
}
|
|
5033
5316
|
});
|
|
5317
|
+
applyAIOverride(config, options.ai);
|
|
5034
5318
|
logger.debug(`Version mode: ${config.monorepo?.versionMode || "standalone"}`);
|
|
5035
5319
|
await socialSafetyCheck({ config });
|
|
5036
5320
|
if (!config.release.social && !config.social?.twitter?.enabled && !config.social?.slack?.enabled) {
|
|
@@ -5059,23 +5343,60 @@ async function social(options = {}) {
|
|
|
5059
5343
|
from: fromTag,
|
|
5060
5344
|
to
|
|
5061
5345
|
});
|
|
5062
|
-
const
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5346
|
+
const minifiedBody = buildChangelogBody({ commits: rootPackage.commits, config, minify: true });
|
|
5347
|
+
const richBody = buildChangelogBody({ commits: rootPackage.commits, config, minify: false });
|
|
5348
|
+
const hasContent = !!minifiedBody.trim();
|
|
5349
|
+
const twitterReleaseUrl = getReleaseUrl(config, to);
|
|
5350
|
+
const twitterChangelogUrl = config.social?.changelogUrl;
|
|
5351
|
+
const prerelease = isPrerelease(newVersion);
|
|
5352
|
+
const twitterWillPost = !!config.social?.twitter?.enabled && !(config.social.twitter.onlyStable && prerelease);
|
|
5353
|
+
const slackWillPost = !!config.social?.slack?.enabled && !((config.social.slack.onlyStable ?? true) && prerelease);
|
|
5354
|
+
let twitterChangelog = minifiedBody;
|
|
5355
|
+
if (hasContent && twitterWillPost && isAISocialEnabled(config, "twitter")) {
|
|
5356
|
+
const twitterTemplate = config.social.twitter.template || config.templates.twitterMessage;
|
|
5357
|
+
const twitterBudget = computeTwitterChangelogBudget({
|
|
5358
|
+
template: twitterTemplate,
|
|
5359
|
+
projectName: config.projectName || rootPackageRead.name,
|
|
5360
|
+
version: newVersion,
|
|
5361
|
+
releaseUrl: twitterReleaseUrl,
|
|
5362
|
+
changelogUrl: twitterChangelogUrl,
|
|
5363
|
+
postMaxLength: config.social.twitter.postMaxLength
|
|
5364
|
+
});
|
|
5365
|
+
twitterChangelog = await generateAISocialChangelog({
|
|
5366
|
+
config,
|
|
5367
|
+
rawBody: richBody,
|
|
5368
|
+
fallbackBody: minifiedBody,
|
|
5369
|
+
platform: "twitter",
|
|
5370
|
+
maxLength: twitterBudget
|
|
5371
|
+
});
|
|
5372
|
+
if (dryRun) {
|
|
5373
|
+
logger.box("[dry-run] AI Twitter preview", `
|
|
5374
|
+
|
|
5375
|
+
${twitterChangelog}`);
|
|
5376
|
+
}
|
|
5377
|
+
}
|
|
5378
|
+
let slackChangelog = minifiedBody;
|
|
5379
|
+
if (hasContent && slackWillPost && isAISocialEnabled(config, "slack")) {
|
|
5380
|
+
slackChangelog = await generateAISocialChangelog({
|
|
5381
|
+
config,
|
|
5382
|
+
rawBody: richBody,
|
|
5383
|
+
fallbackBody: minifiedBody,
|
|
5384
|
+
platform: "slack"
|
|
5385
|
+
});
|
|
5386
|
+
if (dryRun) {
|
|
5387
|
+
logger.box("[dry-run] AI Slack preview", slackChangelog);
|
|
5388
|
+
}
|
|
5389
|
+
}
|
|
5069
5390
|
const twitterResponse = await handleTwitterPost({
|
|
5070
5391
|
config,
|
|
5071
|
-
changelog,
|
|
5392
|
+
changelog: twitterChangelog,
|
|
5072
5393
|
dryRun,
|
|
5073
5394
|
newVersion,
|
|
5074
5395
|
tag: to
|
|
5075
5396
|
});
|
|
5076
5397
|
const slackResponse = await handleSlackPost({
|
|
5077
5398
|
config,
|
|
5078
|
-
changelog,
|
|
5399
|
+
changelog: slackChangelog,
|
|
5079
5400
|
dryRun,
|
|
5080
5401
|
newVersion,
|
|
5081
5402
|
tag: to
|
|
@@ -5226,6 +5547,7 @@ async function release(options = {}) {
|
|
|
5226
5547
|
const force = options.force ?? false;
|
|
5227
5548
|
logger.debug(`Force bump: ${force}`);
|
|
5228
5549
|
const config = await getReleaseConfig(options);
|
|
5550
|
+
applyAIOverride(config, options.ai);
|
|
5229
5551
|
logger.debug(`Version mode: ${config.monorepo?.versionMode || "standalone"}`);
|
|
5230
5552
|
logger.debug(`Push: ${config.release.push}, Publish: ${config.release.publish}, Provider Release: ${config.release.providerRelease}`);
|
|
5231
5553
|
await releaseSafetyCheck({ config, provider: options.provider });
|
|
@@ -5447,4 +5769,4 @@ Git provider: ${provider}`);
|
|
|
5447
5769
|
}
|
|
5448
5770
|
}
|
|
5449
5771
|
|
|
5450
|
-
export {
|
|
5772
|
+
export { getRootPackage as $, createCommitAndTags as A, pushCommitAndTags as B, rollbackModifiedFiles as C, getFirstCommit as D, getCurrentGitBranch as E, getCurrentGitRef as F, getShortCommitSha as G, github as H, createGitlabRelease as I, gitlab as J, buildCompareLink as K, buildChangelogBody as L, buildContributors as M, generateMarkDown as N, parseChangelogMarkdown as O, detectPackageManager as P, determinePublishTag as Q, getPackagesToPublishInSelectiveMode as R, getPackagesToPublishInIndependentMode as S, getAuthCommand as T, publishPackage as U, findGitHubPR as V, findGitLabMR as W, detectPullRequest as X, PR_COMMENT_MARKER as Y, postPrComment as Z, readPackageJson as _, buildCommentBody as a, readPackages as a0, getPackages as a1, getPackageCommits as a2, hasLernaJson as a3, getSlackToken as a4, formatChangelogForSlack as a5, formatSlackMessage as a6, postReleaseToSlack as a7, extractChangelogSummary as a8, getReleaseUrl as a9, isPrerelease as aA, isStableReleaseType as aB, isPrereleaseReleaseType as aC, isGraduating as aD, getPreid as aE, isChangedPreid as aF, getBumpedPackageIndependently as aG, confirmBump as aH, getBumpedIndependentPackages as aI, shouldFilterPrereleaseTags as aJ, extractVersionFromTag as aK, getCanaryVersion as aL, isTagVersionCompatibleWithCurrent as aM, getIndependentTag as aa, getLastStableTag as ab, getLastTag as ac, getLastRepoTag as ad, getLastPackageTag as ae, NEW_PACKAGE_MARKER as af, resolveTags as ag, getTwitterCredentials as ah, formatTweetMessage as ai, postReleaseToTwitter as aj, executeHook as ak, isInCI as al, getCIName as am, executeFormatCmd as an, executeBuildCmd as ao, isBumpedPackage as ap, filterOutPrivatePackages as aq, getPackagesOrBumpedPackages as ar, isGraduatingToStableBetweenVersion as as, capReleaseTypeForZeroMajor as at, determineSemverChange as au, determineReleaseType as av, writeVersion as aw, getPackageNewVersion as ax, updateLernaVersion as ay, extractVersionFromPackageTag 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, getPackageDependencies as m, getDependentsOf as n, expandPackagesToBumpWithDependents as o, prComment as p, getGitStatus as q, release as r, socialSafetyCheck as s, topologicalSort as t, checkGitStatusIfDirty as u, fetchGitTags as v, writeChangelogToFile as w, detectGitProvider as x, parseGitRemoteUrl as y, getModifiedReleaseFilePatterns as z };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "relizy",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.3.0-beta.
|
|
4
|
+
"version": "1.3.0-beta.3",
|
|
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",
|
|
@@ -56,12 +56,16 @@
|
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
58
|
"@slack/web-api": "^7.0.0",
|
|
59
|
+
"@yoloship/claude-sdk": "^0.1.0",
|
|
59
60
|
"twitter-api-v2": "^1.20.0"
|
|
60
61
|
},
|
|
61
62
|
"peerDependenciesMeta": {
|
|
62
63
|
"@slack/web-api": {
|
|
63
64
|
"optional": true
|
|
64
65
|
},
|
|
66
|
+
"@yoloship/claude-sdk": {
|
|
67
|
+
"optional": true
|
|
68
|
+
},
|
|
65
69
|
"twitter-api-v2": {
|
|
66
70
|
"optional": true
|
|
67
71
|
}
|
|
@@ -89,6 +93,7 @@
|
|
|
89
93
|
"@types/node": "^25.6.0",
|
|
90
94
|
"@types/semver": "^7.7.1",
|
|
91
95
|
"@vitest/coverage-v8": "^4.1.4",
|
|
96
|
+
"@yoloship/claude-sdk": "0.1.0-beta.3",
|
|
92
97
|
"cross-env": "10.1.0",
|
|
93
98
|
"eslint": "^10.2.0",
|
|
94
99
|
"husky": "9.1.7",
|
|
@@ -121,7 +126,7 @@
|
|
|
121
126
|
"test:unit": "vitest run",
|
|
122
127
|
"test:unit:watch": "vitest watch",
|
|
123
128
|
"test:unit:coverage": "vitest run --coverage",
|
|
124
|
-
"health": "pnpm typecheck && pnpm lint && pnpm test:unit:coverage",
|
|
129
|
+
"health": "pnpm typecheck && pnpm lint:all && pnpm test:unit:coverage && pnpm build && pnpm -F docs build",
|
|
125
130
|
"pre-commit": "lint-staged"
|
|
126
131
|
}
|
|
127
132
|
}
|