@releasekit/notes 0.2.0 → 0.3.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/aggregator-BDTUZWOA.js +13 -0
- package/dist/chunk-H7G2HRHI.js +134 -0
- package/dist/{chunk-DGZ6TM5J.js → chunk-LKJLUB7X.js} +133 -356
- package/dist/chunk-O4VCGEZT.js +147 -0
- package/dist/cli.cjs +383 -328
- package/dist/cli.js +6 -27
- package/dist/index.cjs +385 -309
- package/dist/index.d.cts +11 -4
- package/dist/index.d.ts +11 -4
- package/dist/index.js +12 -6
- package/package.json +2 -2
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
formatVersion,
|
|
3
|
+
renderMarkdown,
|
|
4
|
+
writeMarkdown
|
|
5
|
+
} from "./chunk-H7G2HRHI.js";
|
|
6
|
+
|
|
1
7
|
// src/core/config.ts
|
|
2
8
|
import {
|
|
3
9
|
loadAuth,
|
|
@@ -145,138 +151,10 @@ async function parsePackageVersionerStdin() {
|
|
|
145
151
|
return parsePackageVersioner(content);
|
|
146
152
|
}
|
|
147
153
|
|
|
148
|
-
// src/output/
|
|
154
|
+
// src/output/json.ts
|
|
149
155
|
import * as fs2 from "fs";
|
|
150
156
|
import * as path from "path";
|
|
151
157
|
import { debug, info, success } from "@releasekit/core";
|
|
152
|
-
var TYPE_ORDER = ["added", "changed", "deprecated", "removed", "fixed", "security"];
|
|
153
|
-
var TYPE_LABELS = {
|
|
154
|
-
added: "Added",
|
|
155
|
-
changed: "Changed",
|
|
156
|
-
deprecated: "Deprecated",
|
|
157
|
-
removed: "Removed",
|
|
158
|
-
fixed: "Fixed",
|
|
159
|
-
security: "Security"
|
|
160
|
-
};
|
|
161
|
-
function groupEntriesByType(entries) {
|
|
162
|
-
const grouped = /* @__PURE__ */ new Map();
|
|
163
|
-
for (const type of TYPE_ORDER) {
|
|
164
|
-
grouped.set(type, []);
|
|
165
|
-
}
|
|
166
|
-
for (const entry of entries) {
|
|
167
|
-
const existing = grouped.get(entry.type) ?? [];
|
|
168
|
-
existing.push(entry);
|
|
169
|
-
grouped.set(entry.type, existing);
|
|
170
|
-
}
|
|
171
|
-
return grouped;
|
|
172
|
-
}
|
|
173
|
-
function formatEntry(entry) {
|
|
174
|
-
let line;
|
|
175
|
-
if (entry.breaking && entry.scope) {
|
|
176
|
-
line = `- **BREAKING** **${entry.scope}**: ${entry.description}`;
|
|
177
|
-
} else if (entry.breaking) {
|
|
178
|
-
line = `- **BREAKING** ${entry.description}`;
|
|
179
|
-
} else if (entry.scope) {
|
|
180
|
-
line = `- **${entry.scope}**: ${entry.description}`;
|
|
181
|
-
} else {
|
|
182
|
-
line = `- ${entry.description}`;
|
|
183
|
-
}
|
|
184
|
-
if (entry.issueIds && entry.issueIds.length > 0) {
|
|
185
|
-
line += ` (${entry.issueIds.join(", ")})`;
|
|
186
|
-
}
|
|
187
|
-
return line;
|
|
188
|
-
}
|
|
189
|
-
function formatVersion(context) {
|
|
190
|
-
const lines = [];
|
|
191
|
-
const versionHeader = context.previousVersion ? `## [${context.version}]` : `## ${context.version}`;
|
|
192
|
-
lines.push(`${versionHeader} - ${context.date}`);
|
|
193
|
-
lines.push("");
|
|
194
|
-
if (context.compareUrl) {
|
|
195
|
-
lines.push(`[Full Changelog](${context.compareUrl})`);
|
|
196
|
-
lines.push("");
|
|
197
|
-
}
|
|
198
|
-
if (context.enhanced?.summary) {
|
|
199
|
-
lines.push(context.enhanced.summary);
|
|
200
|
-
lines.push("");
|
|
201
|
-
}
|
|
202
|
-
const grouped = groupEntriesByType(context.entries);
|
|
203
|
-
for (const [type, entries] of grouped) {
|
|
204
|
-
if (entries.length === 0) continue;
|
|
205
|
-
lines.push(`### ${TYPE_LABELS[type]}`);
|
|
206
|
-
for (const entry of entries) {
|
|
207
|
-
lines.push(formatEntry(entry));
|
|
208
|
-
}
|
|
209
|
-
lines.push("");
|
|
210
|
-
}
|
|
211
|
-
return lines.join("\n");
|
|
212
|
-
}
|
|
213
|
-
function formatHeader() {
|
|
214
|
-
return `# Changelog
|
|
215
|
-
|
|
216
|
-
All notable changes to this project will be documented in this file.
|
|
217
|
-
|
|
218
|
-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
219
|
-
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
220
|
-
|
|
221
|
-
`;
|
|
222
|
-
}
|
|
223
|
-
function renderMarkdown(contexts) {
|
|
224
|
-
const sections = [formatHeader()];
|
|
225
|
-
for (const context of contexts) {
|
|
226
|
-
sections.push(formatVersion(context));
|
|
227
|
-
}
|
|
228
|
-
return sections.join("\n");
|
|
229
|
-
}
|
|
230
|
-
function prependVersion(existingPath, context) {
|
|
231
|
-
let existing = "";
|
|
232
|
-
if (fs2.existsSync(existingPath)) {
|
|
233
|
-
existing = fs2.readFileSync(existingPath, "utf-8");
|
|
234
|
-
const headerEnd = existing.indexOf("\n## ");
|
|
235
|
-
if (headerEnd >= 0) {
|
|
236
|
-
const header = existing.slice(0, headerEnd);
|
|
237
|
-
const body = existing.slice(headerEnd + 1);
|
|
238
|
-
const newVersion = formatVersion(context);
|
|
239
|
-
return `${header}
|
|
240
|
-
|
|
241
|
-
${newVersion}
|
|
242
|
-
${body}`;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
return renderMarkdown([context]);
|
|
246
|
-
}
|
|
247
|
-
function writeMarkdown(outputPath, contexts, config, dryRun) {
|
|
248
|
-
const content = renderMarkdown(contexts);
|
|
249
|
-
if (dryRun) {
|
|
250
|
-
info(`Would write changelog to ${outputPath}`);
|
|
251
|
-
debug("--- Changelog Preview ---");
|
|
252
|
-
debug(content);
|
|
253
|
-
debug("--- End Preview ---");
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
|
-
const dir = path.dirname(outputPath);
|
|
257
|
-
if (!fs2.existsSync(dir)) {
|
|
258
|
-
fs2.mkdirSync(dir, { recursive: true });
|
|
259
|
-
}
|
|
260
|
-
if (outputPath === "-") {
|
|
261
|
-
process.stdout.write(content);
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
if (config.updateStrategy === "prepend" && fs2.existsSync(outputPath) && contexts.length === 1) {
|
|
265
|
-
const firstContext = contexts[0];
|
|
266
|
-
if (firstContext) {
|
|
267
|
-
const updated = prependVersion(outputPath, firstContext);
|
|
268
|
-
fs2.writeFileSync(outputPath, updated, "utf-8");
|
|
269
|
-
}
|
|
270
|
-
} else {
|
|
271
|
-
fs2.writeFileSync(outputPath, content, "utf-8");
|
|
272
|
-
}
|
|
273
|
-
success(`Changelog written to ${outputPath}`);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
// src/output/json.ts
|
|
277
|
-
import * as fs3 from "fs";
|
|
278
|
-
import * as path2 from "path";
|
|
279
|
-
import { debug as debug2, info as info2, success as success2 } from "@releasekit/core";
|
|
280
158
|
function renderJson(contexts) {
|
|
281
159
|
return JSON.stringify(
|
|
282
160
|
{
|
|
@@ -296,24 +174,24 @@ function renderJson(contexts) {
|
|
|
296
174
|
function writeJson(outputPath, contexts, dryRun) {
|
|
297
175
|
const content = renderJson(contexts);
|
|
298
176
|
if (dryRun) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
177
|
+
info(`Would write JSON output to ${outputPath}`);
|
|
178
|
+
debug("--- JSON Output Preview ---");
|
|
179
|
+
debug(content);
|
|
180
|
+
debug("--- End Preview ---");
|
|
303
181
|
return;
|
|
304
182
|
}
|
|
305
|
-
const dir =
|
|
306
|
-
if (!
|
|
307
|
-
|
|
183
|
+
const dir = path.dirname(outputPath);
|
|
184
|
+
if (!fs2.existsSync(dir)) {
|
|
185
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
308
186
|
}
|
|
309
|
-
|
|
310
|
-
|
|
187
|
+
fs2.writeFileSync(outputPath, content, "utf-8");
|
|
188
|
+
success(`JSON output written to ${outputPath}`);
|
|
311
189
|
}
|
|
312
190
|
|
|
313
191
|
// src/core/pipeline.ts
|
|
314
|
-
import * as
|
|
315
|
-
import * as
|
|
316
|
-
import { debug as
|
|
192
|
+
import * as fs7 from "fs";
|
|
193
|
+
import * as path5 from "path";
|
|
194
|
+
import { debug as debug2, info as info3, success as success3, warn as warn3 } from "@releasekit/core";
|
|
317
195
|
|
|
318
196
|
// src/llm/defaults.ts
|
|
319
197
|
var LLM_DEFAULTS = {
|
|
@@ -411,7 +289,7 @@ var OllamaProvider = class extends BaseLLMProvider {
|
|
|
411
289
|
"Content-Type": "application/json"
|
|
412
290
|
};
|
|
413
291
|
if (this.apiKey) {
|
|
414
|
-
headers
|
|
292
|
+
headers.Authorization = `Bearer ${this.apiKey}`;
|
|
415
293
|
}
|
|
416
294
|
const baseUrl = this.baseURL.endsWith("/api") ? this.baseURL.slice(0, -4) : this.baseURL;
|
|
417
295
|
const response = await fetch(`${baseUrl}/api/chat`, {
|
|
@@ -572,7 +450,6 @@ function validateScope(scope, allowedScopes, rules) {
|
|
|
572
450
|
return scope;
|
|
573
451
|
case "fallback":
|
|
574
452
|
return rules?.fallbackScope;
|
|
575
|
-
case "remove":
|
|
576
453
|
default:
|
|
577
454
|
return void 0;
|
|
578
455
|
}
|
|
@@ -949,7 +826,7 @@ function createProvider(config) {
|
|
|
949
826
|
|
|
950
827
|
// src/output/github-release.ts
|
|
951
828
|
import { Octokit } from "@octokit/rest";
|
|
952
|
-
import { info as
|
|
829
|
+
import { info as info2, success as success2 } from "@releasekit/core";
|
|
953
830
|
var GitHubClient = class {
|
|
954
831
|
octokit;
|
|
955
832
|
owner;
|
|
@@ -971,7 +848,7 @@ var GitHubClient = class {
|
|
|
971
848
|
} else {
|
|
972
849
|
body = renderMarkdown([context]);
|
|
973
850
|
}
|
|
974
|
-
|
|
851
|
+
info2(`Creating GitHub release for ${tagName}`);
|
|
975
852
|
try {
|
|
976
853
|
const response = await this.octokit.repos.createRelease({
|
|
977
854
|
owner: this.owner,
|
|
@@ -983,7 +860,7 @@ var GitHubClient = class {
|
|
|
983
860
|
prerelease: options.prerelease ?? false,
|
|
984
861
|
generate_release_notes: options.generateNotes ?? false
|
|
985
862
|
});
|
|
986
|
-
|
|
863
|
+
success2(`Release created: ${response.data.html_url}`);
|
|
987
864
|
return {
|
|
988
865
|
id: response.data.id,
|
|
989
866
|
htmlUrl: response.data.html_url,
|
|
@@ -1001,7 +878,7 @@ var GitHubClient = class {
|
|
|
1001
878
|
} else {
|
|
1002
879
|
body = renderMarkdown([context]);
|
|
1003
880
|
}
|
|
1004
|
-
|
|
881
|
+
info2(`Updating GitHub release ${releaseId}`);
|
|
1005
882
|
try {
|
|
1006
883
|
const response = await this.octokit.repos.updateRelease({
|
|
1007
884
|
owner: this.owner,
|
|
@@ -1013,7 +890,7 @@ var GitHubClient = class {
|
|
|
1013
890
|
draft: options.draft ?? false,
|
|
1014
891
|
prerelease: options.prerelease ?? false
|
|
1015
892
|
});
|
|
1016
|
-
|
|
893
|
+
success2(`Release updated: ${response.data.html_url}`);
|
|
1017
894
|
return {
|
|
1018
895
|
id: response.data.id,
|
|
1019
896
|
htmlUrl: response.data.html_url,
|
|
@@ -1063,7 +940,7 @@ async function createGitHubRelease(context, options) {
|
|
|
1063
940
|
}
|
|
1064
941
|
|
|
1065
942
|
// src/templates/ejs.ts
|
|
1066
|
-
import * as
|
|
943
|
+
import * as fs3 from "fs";
|
|
1067
944
|
import ejs from "ejs";
|
|
1068
945
|
function renderEjs(template, context) {
|
|
1069
946
|
try {
|
|
@@ -1073,16 +950,16 @@ function renderEjs(template, context) {
|
|
|
1073
950
|
}
|
|
1074
951
|
}
|
|
1075
952
|
function renderEjsFile(filePath, context) {
|
|
1076
|
-
if (!
|
|
953
|
+
if (!fs3.existsSync(filePath)) {
|
|
1077
954
|
throw new TemplateError(`Template file not found: ${filePath}`);
|
|
1078
955
|
}
|
|
1079
|
-
const template =
|
|
956
|
+
const template = fs3.readFileSync(filePath, "utf-8");
|
|
1080
957
|
return renderEjs(template, context);
|
|
1081
958
|
}
|
|
1082
959
|
|
|
1083
960
|
// src/templates/handlebars.ts
|
|
1084
|
-
import * as
|
|
1085
|
-
import * as
|
|
961
|
+
import * as fs4 from "fs";
|
|
962
|
+
import * as path2 from "path";
|
|
1086
963
|
import Handlebars from "handlebars";
|
|
1087
964
|
function registerHandlebarsHelpers() {
|
|
1088
965
|
Handlebars.registerHelper("capitalize", (str) => {
|
|
@@ -1108,28 +985,28 @@ function renderHandlebars(template, context) {
|
|
|
1108
985
|
}
|
|
1109
986
|
}
|
|
1110
987
|
function renderHandlebarsFile(filePath, context) {
|
|
1111
|
-
if (!
|
|
988
|
+
if (!fs4.existsSync(filePath)) {
|
|
1112
989
|
throw new TemplateError(`Template file not found: ${filePath}`);
|
|
1113
990
|
}
|
|
1114
|
-
const template =
|
|
991
|
+
const template = fs4.readFileSync(filePath, "utf-8");
|
|
1115
992
|
return renderHandlebars(template, context);
|
|
1116
993
|
}
|
|
1117
994
|
function renderHandlebarsComposable(templateDir, context) {
|
|
1118
995
|
registerHandlebarsHelpers();
|
|
1119
|
-
const versionPath =
|
|
1120
|
-
const entryPath =
|
|
1121
|
-
const documentPath =
|
|
1122
|
-
if (!
|
|
996
|
+
const versionPath = path2.join(templateDir, "version.hbs");
|
|
997
|
+
const entryPath = path2.join(templateDir, "entry.hbs");
|
|
998
|
+
const documentPath = path2.join(templateDir, "document.hbs");
|
|
999
|
+
if (!fs4.existsSync(documentPath)) {
|
|
1123
1000
|
throw new TemplateError(`Document template not found: ${documentPath}`);
|
|
1124
1001
|
}
|
|
1125
|
-
if (
|
|
1126
|
-
Handlebars.registerPartial("version",
|
|
1002
|
+
if (fs4.existsSync(versionPath)) {
|
|
1003
|
+
Handlebars.registerPartial("version", fs4.readFileSync(versionPath, "utf-8"));
|
|
1127
1004
|
}
|
|
1128
|
-
if (
|
|
1129
|
-
Handlebars.registerPartial("entry",
|
|
1005
|
+
if (fs4.existsSync(entryPath)) {
|
|
1006
|
+
Handlebars.registerPartial("entry", fs4.readFileSync(entryPath, "utf-8"));
|
|
1130
1007
|
}
|
|
1131
1008
|
try {
|
|
1132
|
-
const compiled = Handlebars.compile(
|
|
1009
|
+
const compiled = Handlebars.compile(fs4.readFileSync(documentPath, "utf-8"));
|
|
1133
1010
|
return compiled(context);
|
|
1134
1011
|
} catch (error) {
|
|
1135
1012
|
throw new TemplateError(`Handlebars render error: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -1137,8 +1014,8 @@ function renderHandlebarsComposable(templateDir, context) {
|
|
|
1137
1014
|
}
|
|
1138
1015
|
|
|
1139
1016
|
// src/templates/liquid.ts
|
|
1140
|
-
import * as
|
|
1141
|
-
import * as
|
|
1017
|
+
import * as fs5 from "fs";
|
|
1018
|
+
import * as path3 from "path";
|
|
1142
1019
|
import { Liquid } from "liquidjs";
|
|
1143
1020
|
function createLiquidEngine(root) {
|
|
1144
1021
|
return new Liquid({
|
|
@@ -1156,15 +1033,15 @@ function renderLiquid(template, context) {
|
|
|
1156
1033
|
}
|
|
1157
1034
|
}
|
|
1158
1035
|
function renderLiquidFile(filePath, context) {
|
|
1159
|
-
if (!
|
|
1036
|
+
if (!fs5.existsSync(filePath)) {
|
|
1160
1037
|
throw new TemplateError(`Template file not found: ${filePath}`);
|
|
1161
1038
|
}
|
|
1162
|
-
const template =
|
|
1039
|
+
const template = fs5.readFileSync(filePath, "utf-8");
|
|
1163
1040
|
return renderLiquid(template, context);
|
|
1164
1041
|
}
|
|
1165
1042
|
function renderLiquidComposable(templateDir, context) {
|
|
1166
|
-
const documentPath =
|
|
1167
|
-
if (!
|
|
1043
|
+
const documentPath = path3.join(templateDir, "document.liquid");
|
|
1044
|
+
if (!fs5.existsSync(documentPath)) {
|
|
1168
1045
|
throw new TemplateError(`Document template not found: ${documentPath}`);
|
|
1169
1046
|
}
|
|
1170
1047
|
const engine = createLiquidEngine(templateDir);
|
|
@@ -1176,10 +1053,10 @@ function renderLiquidComposable(templateDir, context) {
|
|
|
1176
1053
|
}
|
|
1177
1054
|
|
|
1178
1055
|
// src/templates/loader.ts
|
|
1179
|
-
import * as
|
|
1180
|
-
import * as
|
|
1056
|
+
import * as fs6 from "fs";
|
|
1057
|
+
import * as path4 from "path";
|
|
1181
1058
|
function getEngineFromFile(filePath) {
|
|
1182
|
-
const ext =
|
|
1059
|
+
const ext = path4.extname(filePath).toLowerCase();
|
|
1183
1060
|
switch (ext) {
|
|
1184
1061
|
case ".liquid":
|
|
1185
1062
|
return "liquid";
|
|
@@ -1213,10 +1090,10 @@ function getRenderFileFn(engine) {
|
|
|
1213
1090
|
}
|
|
1214
1091
|
}
|
|
1215
1092
|
function detectTemplateMode(templatePath) {
|
|
1216
|
-
if (!
|
|
1093
|
+
if (!fs6.existsSync(templatePath)) {
|
|
1217
1094
|
throw new TemplateError(`Template path not found: ${templatePath}`);
|
|
1218
1095
|
}
|
|
1219
|
-
const stat =
|
|
1096
|
+
const stat = fs6.statSync(templatePath);
|
|
1220
1097
|
if (stat.isFile()) {
|
|
1221
1098
|
return "single";
|
|
1222
1099
|
}
|
|
@@ -1234,7 +1111,7 @@ function renderSingleFile(templatePath, context, engine) {
|
|
|
1234
1111
|
};
|
|
1235
1112
|
}
|
|
1236
1113
|
function renderComposable(templateDir, context, engine) {
|
|
1237
|
-
const files =
|
|
1114
|
+
const files = fs6.readdirSync(templateDir);
|
|
1238
1115
|
const engineMap = {
|
|
1239
1116
|
liquid: { document: "document.liquid", version: "version.liquid", entry: "entry.liquid" },
|
|
1240
1117
|
handlebars: { document: "document.hbs", version: "version.hbs", entry: "entry.hbs" },
|
|
@@ -1257,15 +1134,15 @@ function renderComposable(templateDir, context, engine) {
|
|
|
1257
1134
|
return { content: renderHandlebarsComposable(templateDir, context), engine: resolvedEngine };
|
|
1258
1135
|
}
|
|
1259
1136
|
const expectedFiles = engineMap[resolvedEngine];
|
|
1260
|
-
const documentPath =
|
|
1261
|
-
if (!
|
|
1137
|
+
const documentPath = path4.join(templateDir, expectedFiles.document);
|
|
1138
|
+
if (!fs6.existsSync(documentPath)) {
|
|
1262
1139
|
throw new TemplateError(`Document template not found: ${expectedFiles.document}`);
|
|
1263
1140
|
}
|
|
1264
|
-
const versionPath =
|
|
1265
|
-
const entryPath =
|
|
1141
|
+
const versionPath = path4.join(templateDir, expectedFiles.version);
|
|
1142
|
+
const entryPath = path4.join(templateDir, expectedFiles.entry);
|
|
1266
1143
|
const render = getRenderFn(resolvedEngine);
|
|
1267
|
-
const entryTemplate =
|
|
1268
|
-
const versionTemplate =
|
|
1144
|
+
const entryTemplate = fs6.existsSync(entryPath) ? fs6.readFileSync(entryPath, "utf-8") : null;
|
|
1145
|
+
const versionTemplate = fs6.existsSync(versionPath) ? fs6.readFileSync(versionPath, "utf-8") : null;
|
|
1269
1146
|
if (entryTemplate && versionTemplate) {
|
|
1270
1147
|
const versionsWithEntries = context.versions.map((versionCtx) => {
|
|
1271
1148
|
const entries = versionCtx.entries.map((entry) => {
|
|
@@ -1276,7 +1153,7 @@ function renderComposable(templateDir, context, engine) {
|
|
|
1276
1153
|
});
|
|
1277
1154
|
const docContext = { ...context, renderedVersions: versionsWithEntries };
|
|
1278
1155
|
return {
|
|
1279
|
-
content: render(
|
|
1156
|
+
content: render(fs6.readFileSync(documentPath, "utf-8"), docContext),
|
|
1280
1157
|
engine: resolvedEngine
|
|
1281
1158
|
};
|
|
1282
1159
|
}
|
|
@@ -1383,9 +1260,9 @@ async function processWithLLM(context, config) {
|
|
|
1383
1260
|
entries: context.entries
|
|
1384
1261
|
};
|
|
1385
1262
|
try {
|
|
1386
|
-
|
|
1263
|
+
info3(`Using LLM provider: ${config.llm.provider}${config.llm.model ? ` (${config.llm.model})` : ""}`);
|
|
1387
1264
|
if (config.llm.baseURL) {
|
|
1388
|
-
|
|
1265
|
+
info3(`LLM base URL: ${config.llm.baseURL}`);
|
|
1389
1266
|
}
|
|
1390
1267
|
const rawProvider = createProvider(config.llm);
|
|
1391
1268
|
const retryOpts = config.llm.retry ?? LLM_DEFAULTS.retry;
|
|
@@ -1394,47 +1271,47 @@ async function processWithLLM(context, config) {
|
|
|
1394
1271
|
complete: (prompt, opts) => withRetry(() => rawProvider.complete(prompt, opts), retryOpts)
|
|
1395
1272
|
};
|
|
1396
1273
|
const activeTasks = Object.entries(tasks).filter(([, enabled]) => enabled).map(([name]) => name);
|
|
1397
|
-
|
|
1274
|
+
info3(`Running LLM tasks: ${activeTasks.join(", ")}`);
|
|
1398
1275
|
if (tasks.enhance && tasks.categorize) {
|
|
1399
|
-
|
|
1276
|
+
info3("Enhancing and categorizing entries with LLM...");
|
|
1400
1277
|
const result = await enhanceAndCategorize(provider, context.entries, llmContext);
|
|
1401
1278
|
enhanced.entries = result.enhancedEntries;
|
|
1402
1279
|
enhanced.categories = {};
|
|
1403
1280
|
for (const cat of result.categories) {
|
|
1404
1281
|
enhanced.categories[cat.category] = cat.entries;
|
|
1405
1282
|
}
|
|
1406
|
-
|
|
1283
|
+
info3(`Enhanced ${enhanced.entries.length} entries into ${result.categories.length} categories`);
|
|
1407
1284
|
} else {
|
|
1408
1285
|
if (tasks.enhance) {
|
|
1409
|
-
|
|
1286
|
+
info3("Enhancing entries with LLM...");
|
|
1410
1287
|
enhanced.entries = await enhanceEntries(provider, context.entries, llmContext, config.llm.concurrency);
|
|
1411
|
-
|
|
1288
|
+
info3(`Enhanced ${enhanced.entries.length} entries`);
|
|
1412
1289
|
}
|
|
1413
1290
|
if (tasks.categorize) {
|
|
1414
|
-
|
|
1291
|
+
info3("Categorizing entries with LLM...");
|
|
1415
1292
|
const categorized = await categorizeEntries(provider, enhanced.entries, llmContext);
|
|
1416
1293
|
enhanced.categories = {};
|
|
1417
1294
|
for (const cat of categorized) {
|
|
1418
1295
|
enhanced.categories[cat.category] = cat.entries;
|
|
1419
1296
|
}
|
|
1420
|
-
|
|
1297
|
+
info3(`Created ${categorized.length} categories`);
|
|
1421
1298
|
}
|
|
1422
1299
|
}
|
|
1423
1300
|
if (tasks.summarize) {
|
|
1424
|
-
|
|
1301
|
+
info3("Summarizing entries with LLM...");
|
|
1425
1302
|
enhanced.summary = await summarizeEntries(provider, enhanced.entries, llmContext);
|
|
1426
1303
|
if (enhanced.summary) {
|
|
1427
|
-
|
|
1428
|
-
|
|
1304
|
+
info3("Summary generated successfully");
|
|
1305
|
+
debug2(`Summary: ${enhanced.summary.substring(0, 100)}...`);
|
|
1429
1306
|
} else {
|
|
1430
1307
|
warn3("Summary generation returned empty result");
|
|
1431
1308
|
}
|
|
1432
1309
|
}
|
|
1433
1310
|
if (tasks.releaseNotes) {
|
|
1434
|
-
|
|
1311
|
+
info3("Generating release notes with LLM...");
|
|
1435
1312
|
enhanced.releaseNotes = await generateReleaseNotes(provider, enhanced.entries, llmContext);
|
|
1436
1313
|
if (enhanced.releaseNotes) {
|
|
1437
|
-
|
|
1314
|
+
info3("Release notes generated successfully");
|
|
1438
1315
|
} else {
|
|
1439
1316
|
warn3("Release notes generation returned empty result");
|
|
1440
1317
|
}
|
|
@@ -1453,17 +1330,17 @@ function getBuiltinTemplatePath(style) {
|
|
|
1453
1330
|
let packageRoot;
|
|
1454
1331
|
try {
|
|
1455
1332
|
const currentUrl = import.meta.url;
|
|
1456
|
-
packageRoot =
|
|
1457
|
-
packageRoot =
|
|
1333
|
+
packageRoot = path5.dirname(new URL(currentUrl).pathname);
|
|
1334
|
+
packageRoot = path5.join(packageRoot, "..", "..");
|
|
1458
1335
|
} catch {
|
|
1459
1336
|
packageRoot = __dirname;
|
|
1460
1337
|
}
|
|
1461
|
-
return
|
|
1338
|
+
return path5.join(packageRoot, "templates", style);
|
|
1462
1339
|
}
|
|
1463
1340
|
async function generateWithTemplate(contexts, config, outputPath, dryRun) {
|
|
1464
1341
|
let templatePath;
|
|
1465
1342
|
if (config.templates?.path) {
|
|
1466
|
-
templatePath =
|
|
1343
|
+
templatePath = path5.resolve(config.templates.path);
|
|
1467
1344
|
} else {
|
|
1468
1345
|
templatePath = getBuiltinTemplatePath("keep-a-changelog");
|
|
1469
1346
|
}
|
|
@@ -1473,52 +1350,63 @@ async function generateWithTemplate(contexts, config, outputPath, dryRun) {
|
|
|
1473
1350
|
);
|
|
1474
1351
|
const result = renderTemplate(templatePath, documentContext, config.templates?.engine);
|
|
1475
1352
|
if (dryRun) {
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1353
|
+
info3(`Would write templated output to ${outputPath}`);
|
|
1354
|
+
debug2("--- Changelog Preview ---");
|
|
1355
|
+
debug2(result.content);
|
|
1356
|
+
debug2("--- End Preview ---");
|
|
1480
1357
|
return;
|
|
1481
1358
|
}
|
|
1482
1359
|
if (outputPath === "-") {
|
|
1483
1360
|
process.stdout.write(result.content);
|
|
1484
1361
|
return;
|
|
1485
1362
|
}
|
|
1486
|
-
const dir =
|
|
1487
|
-
if (!
|
|
1488
|
-
|
|
1363
|
+
const dir = path5.dirname(outputPath);
|
|
1364
|
+
if (!fs7.existsSync(dir)) {
|
|
1365
|
+
fs7.mkdirSync(dir, { recursive: true });
|
|
1489
1366
|
}
|
|
1490
|
-
|
|
1491
|
-
|
|
1367
|
+
fs7.writeFileSync(outputPath, result.content, "utf-8");
|
|
1368
|
+
success3(`Changelog written to ${outputPath} (using ${result.engine} template)`);
|
|
1492
1369
|
}
|
|
1493
1370
|
async function runPipeline(input, config, dryRun) {
|
|
1494
|
-
|
|
1371
|
+
debug2(`Processing ${input.packages.length} package(s)`);
|
|
1495
1372
|
let contexts = input.packages.map(createTemplateContext);
|
|
1496
1373
|
if (config.llm && !process.env.CHANGELOG_NO_LLM) {
|
|
1497
|
-
|
|
1374
|
+
info3("Processing with LLM enhancement");
|
|
1498
1375
|
contexts = await Promise.all(contexts.map((ctx) => processWithLLM(ctx, config)));
|
|
1499
1376
|
}
|
|
1377
|
+
const files = [];
|
|
1500
1378
|
for (const output of config.output) {
|
|
1501
|
-
|
|
1379
|
+
info3(`Generating ${output.format} output`);
|
|
1502
1380
|
switch (output.format) {
|
|
1503
1381
|
case "markdown": {
|
|
1504
1382
|
const file = output.file ?? "CHANGELOG.md";
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1383
|
+
try {
|
|
1384
|
+
const effectiveTemplateConfig = output.templates ?? config.templates;
|
|
1385
|
+
if (effectiveTemplateConfig?.path || output.options?.template) {
|
|
1386
|
+
const configWithTemplate = { ...config, templates: effectiveTemplateConfig };
|
|
1387
|
+
await generateWithTemplate(contexts, configWithTemplate, file, dryRun);
|
|
1388
|
+
} else {
|
|
1389
|
+
writeMarkdown(file, contexts, config, dryRun);
|
|
1390
|
+
}
|
|
1391
|
+
if (!dryRun) files.push(file);
|
|
1392
|
+
} catch (error) {
|
|
1393
|
+
warn3(`Failed to write ${file}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1511
1394
|
}
|
|
1512
1395
|
break;
|
|
1513
1396
|
}
|
|
1514
1397
|
case "json": {
|
|
1515
1398
|
const file = output.file ?? "changelog.json";
|
|
1516
|
-
|
|
1399
|
+
try {
|
|
1400
|
+
writeJson(file, contexts, dryRun);
|
|
1401
|
+
if (!dryRun) files.push(file);
|
|
1402
|
+
} catch (error) {
|
|
1403
|
+
warn3(`Failed to write ${file}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1404
|
+
}
|
|
1517
1405
|
break;
|
|
1518
1406
|
}
|
|
1519
1407
|
case "github-release": {
|
|
1520
1408
|
if (dryRun) {
|
|
1521
|
-
|
|
1409
|
+
info3("[DRY RUN] Would create GitHub release");
|
|
1522
1410
|
break;
|
|
1523
1411
|
}
|
|
1524
1412
|
const firstContext = contexts[0];
|
|
@@ -1546,139 +1434,33 @@ async function runPipeline(input, config, dryRun) {
|
|
|
1546
1434
|
}
|
|
1547
1435
|
}
|
|
1548
1436
|
}
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
}
|
|
1566
|
-
return byPackage;
|
|
1567
|
-
}
|
|
1568
|
-
|
|
1569
|
-
// src/monorepo/aggregator.ts
|
|
1570
|
-
function writeFile(outputPath, content, dryRun) {
|
|
1571
|
-
if (dryRun) {
|
|
1572
|
-
info5(`Would write to ${outputPath}`);
|
|
1573
|
-
debug4(content);
|
|
1574
|
-
return;
|
|
1575
|
-
}
|
|
1576
|
-
const dir = path7.dirname(outputPath);
|
|
1577
|
-
if (!fs9.existsSync(dir)) {
|
|
1578
|
-
fs9.mkdirSync(dir, { recursive: true });
|
|
1579
|
-
}
|
|
1580
|
-
fs9.writeFileSync(outputPath, content, "utf-8");
|
|
1581
|
-
success5(`Changelog written to ${outputPath}`);
|
|
1582
|
-
}
|
|
1583
|
-
function aggregateToRoot(contexts) {
|
|
1584
|
-
const aggregated = {
|
|
1585
|
-
packageName: "monorepo",
|
|
1586
|
-
version: contexts[0]?.version ?? "0.0.0",
|
|
1587
|
-
previousVersion: contexts[0]?.previousVersion ?? null,
|
|
1588
|
-
date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0] ?? "",
|
|
1589
|
-
repoUrl: contexts[0]?.repoUrl ?? null,
|
|
1590
|
-
entries: []
|
|
1591
|
-
};
|
|
1592
|
-
for (const ctx of contexts) {
|
|
1593
|
-
for (const entry of ctx.entries) {
|
|
1594
|
-
aggregated.entries.push({
|
|
1595
|
-
...entry,
|
|
1596
|
-
scope: entry.scope ? `${ctx.packageName}/${entry.scope}` : ctx.packageName
|
|
1597
|
-
});
|
|
1598
|
-
}
|
|
1599
|
-
}
|
|
1600
|
-
return aggregated;
|
|
1601
|
-
}
|
|
1602
|
-
function writeMonorepoChangelogs(contexts, options, config, dryRun) {
|
|
1603
|
-
if (options.mode === "root" || options.mode === "both") {
|
|
1604
|
-
const aggregated = aggregateToRoot(contexts);
|
|
1605
|
-
const rootPath = path7.join(options.rootPath, "CHANGELOG.md");
|
|
1606
|
-
info5(`Writing root changelog to ${rootPath}`);
|
|
1607
|
-
const rootContent = config.updateStrategy === "prepend" && fs9.existsSync(rootPath) ? prependVersion(rootPath, aggregated) : renderMarkdown([aggregated]);
|
|
1608
|
-
writeFile(rootPath, rootContent, dryRun);
|
|
1609
|
-
}
|
|
1610
|
-
if (options.mode === "packages" || options.mode === "both") {
|
|
1611
|
-
const byPackage = splitByPackage(contexts);
|
|
1612
|
-
const packageDirMap = buildPackageDirMap(options.rootPath, options.packagesPath);
|
|
1613
|
-
for (const [packageName, ctx] of byPackage) {
|
|
1614
|
-
const simpleName = packageName.split("/").pop();
|
|
1615
|
-
const packageDir = packageDirMap.get(packageName) ?? (simpleName ? packageDirMap.get(simpleName) : void 0) ?? null;
|
|
1616
|
-
if (packageDir) {
|
|
1617
|
-
const changelogPath = path7.join(packageDir, "CHANGELOG.md");
|
|
1618
|
-
info5(`Writing changelog for ${packageName} to ${changelogPath}`);
|
|
1619
|
-
const pkgContent = config.updateStrategy === "prepend" && fs9.existsSync(changelogPath) ? prependVersion(changelogPath, ctx) : renderMarkdown([ctx]);
|
|
1620
|
-
writeFile(changelogPath, pkgContent, dryRun);
|
|
1621
|
-
} else {
|
|
1622
|
-
info5(`Could not find directory for package ${packageName}, skipping`);
|
|
1623
|
-
}
|
|
1437
|
+
if (config.monorepo?.mode) {
|
|
1438
|
+
const { detectMonorepo, writeMonorepoChangelogs } = await import("./aggregator-BDTUZWOA.js");
|
|
1439
|
+
const cwd = process.cwd();
|
|
1440
|
+
const detected = detectMonorepo(cwd);
|
|
1441
|
+
if (detected.isMonorepo) {
|
|
1442
|
+
const monoFiles = writeMonorepoChangelogs(
|
|
1443
|
+
contexts,
|
|
1444
|
+
{
|
|
1445
|
+
rootPath: config.monorepo.rootPath ?? cwd,
|
|
1446
|
+
packagesPath: config.monorepo.packagesPath ?? detected.packagesPath,
|
|
1447
|
+
mode: config.monorepo.mode
|
|
1448
|
+
},
|
|
1449
|
+
config,
|
|
1450
|
+
dryRun
|
|
1451
|
+
);
|
|
1452
|
+
files.push(...monoFiles);
|
|
1624
1453
|
}
|
|
1625
1454
|
}
|
|
1626
|
-
}
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
const packagesDir = path7.join(rootPath, packagesPath);
|
|
1630
|
-
if (!fs9.existsSync(packagesDir)) {
|
|
1631
|
-
return map;
|
|
1632
|
-
}
|
|
1633
|
-
for (const entry of fs9.readdirSync(packagesDir, { withFileTypes: true })) {
|
|
1634
|
-
if (!entry.isDirectory()) continue;
|
|
1635
|
-
const dirPath = path7.join(packagesDir, entry.name);
|
|
1636
|
-
map.set(entry.name, dirPath);
|
|
1637
|
-
const packageJsonPath = path7.join(dirPath, "package.json");
|
|
1638
|
-
if (fs9.existsSync(packageJsonPath)) {
|
|
1639
|
-
try {
|
|
1640
|
-
const pkg = JSON.parse(fs9.readFileSync(packageJsonPath, "utf-8"));
|
|
1641
|
-
if (pkg.name) {
|
|
1642
|
-
map.set(pkg.name, dirPath);
|
|
1643
|
-
}
|
|
1644
|
-
} catch {
|
|
1645
|
-
}
|
|
1646
|
-
}
|
|
1455
|
+
const packageNotes = {};
|
|
1456
|
+
for (const ctx of contexts) {
|
|
1457
|
+
packageNotes[ctx.packageName] = formatVersion(ctx);
|
|
1647
1458
|
}
|
|
1648
|
-
return
|
|
1459
|
+
return { packageNotes, files };
|
|
1649
1460
|
}
|
|
1650
|
-
function
|
|
1651
|
-
const
|
|
1652
|
-
|
|
1653
|
-
if (fs9.existsSync(pnpmWorkspacesPath)) {
|
|
1654
|
-
const content = fs9.readFileSync(pnpmWorkspacesPath, "utf-8");
|
|
1655
|
-
const packagesMatch = content.match(/packages:\s*\n\s*-\s*['"]([^'"]+)['"]/);
|
|
1656
|
-
if (packagesMatch?.[1]) {
|
|
1657
|
-
const packagesGlob = packagesMatch[1];
|
|
1658
|
-
const packagesPath = packagesGlob.replace(/\/?\*$/, "").replace(/\/\*\*$/, "");
|
|
1659
|
-
return { isMonorepo: true, packagesPath: packagesPath || "packages" };
|
|
1660
|
-
}
|
|
1661
|
-
return { isMonorepo: true, packagesPath: "packages" };
|
|
1662
|
-
}
|
|
1663
|
-
if (fs9.existsSync(packageJsonPath)) {
|
|
1664
|
-
try {
|
|
1665
|
-
const content = fs9.readFileSync(packageJsonPath, "utf-8");
|
|
1666
|
-
const pkg = JSON.parse(content);
|
|
1667
|
-
if (pkg.workspaces) {
|
|
1668
|
-
const workspaces = Array.isArray(pkg.workspaces) ? pkg.workspaces : pkg.workspaces.packages;
|
|
1669
|
-
if (workspaces?.length) {
|
|
1670
|
-
const firstWorkspace = workspaces[0];
|
|
1671
|
-
if (firstWorkspace) {
|
|
1672
|
-
const packagesPath = firstWorkspace.replace(/\/?\*$/, "").replace(/\/\*\*$/, "");
|
|
1673
|
-
return { isMonorepo: true, packagesPath: packagesPath || "packages" };
|
|
1674
|
-
}
|
|
1675
|
-
}
|
|
1676
|
-
}
|
|
1677
|
-
} catch {
|
|
1678
|
-
return { isMonorepo: false, packagesPath: "" };
|
|
1679
|
-
}
|
|
1680
|
-
}
|
|
1681
|
-
return { isMonorepo: false, packagesPath: "" };
|
|
1461
|
+
async function processInput(inputJson, config, dryRun) {
|
|
1462
|
+
const input = parsePackageVersioner(inputJson);
|
|
1463
|
+
return runPipeline(input, config, dryRun);
|
|
1682
1464
|
}
|
|
1683
1465
|
|
|
1684
1466
|
export {
|
|
@@ -1697,14 +1479,9 @@ export {
|
|
|
1697
1479
|
parsePackageVersioner,
|
|
1698
1480
|
parsePackageVersionerFile,
|
|
1699
1481
|
parsePackageVersionerStdin,
|
|
1700
|
-
renderMarkdown,
|
|
1701
|
-
writeMarkdown,
|
|
1702
1482
|
renderJson,
|
|
1703
1483
|
writeJson,
|
|
1704
1484
|
createTemplateContext,
|
|
1705
1485
|
runPipeline,
|
|
1706
|
-
processInput
|
|
1707
|
-
aggregateToRoot,
|
|
1708
|
-
writeMonorepoChangelogs,
|
|
1709
|
-
detectMonorepo
|
|
1486
|
+
processInput
|
|
1710
1487
|
};
|