@releasekit/notes 0.2.0 → 0.3.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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/markdown.ts
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
- info2(`Would write JSON output to ${outputPath}`);
300
- debug2("--- JSON Output Preview ---");
301
- debug2(content);
302
- debug2("--- End Preview ---");
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 = path2.dirname(outputPath);
306
- if (!fs3.existsSync(dir)) {
307
- fs3.mkdirSync(dir, { recursive: true });
183
+ const dir = path.dirname(outputPath);
184
+ if (!fs2.existsSync(dir)) {
185
+ fs2.mkdirSync(dir, { recursive: true });
308
186
  }
309
- fs3.writeFileSync(outputPath, content, "utf-8");
310
- success2(`JSON output written to ${outputPath}`);
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 fs8 from "fs";
315
- import * as path6 from "path";
316
- import { debug as debug3, info as info4, success as success4, warn as warn3 } from "@releasekit/core";
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 = {
@@ -949,7 +827,7 @@ function createProvider(config) {
949
827
 
950
828
  // src/output/github-release.ts
951
829
  import { Octokit } from "@octokit/rest";
952
- import { info as info3, success as success3 } from "@releasekit/core";
830
+ import { info as info2, success as success2 } from "@releasekit/core";
953
831
  var GitHubClient = class {
954
832
  octokit;
955
833
  owner;
@@ -971,7 +849,7 @@ var GitHubClient = class {
971
849
  } else {
972
850
  body = renderMarkdown([context]);
973
851
  }
974
- info3(`Creating GitHub release for ${tagName}`);
852
+ info2(`Creating GitHub release for ${tagName}`);
975
853
  try {
976
854
  const response = await this.octokit.repos.createRelease({
977
855
  owner: this.owner,
@@ -983,7 +861,7 @@ var GitHubClient = class {
983
861
  prerelease: options.prerelease ?? false,
984
862
  generate_release_notes: options.generateNotes ?? false
985
863
  });
986
- success3(`Release created: ${response.data.html_url}`);
864
+ success2(`Release created: ${response.data.html_url}`);
987
865
  return {
988
866
  id: response.data.id,
989
867
  htmlUrl: response.data.html_url,
@@ -1001,7 +879,7 @@ var GitHubClient = class {
1001
879
  } else {
1002
880
  body = renderMarkdown([context]);
1003
881
  }
1004
- info3(`Updating GitHub release ${releaseId}`);
882
+ info2(`Updating GitHub release ${releaseId}`);
1005
883
  try {
1006
884
  const response = await this.octokit.repos.updateRelease({
1007
885
  owner: this.owner,
@@ -1013,7 +891,7 @@ var GitHubClient = class {
1013
891
  draft: options.draft ?? false,
1014
892
  prerelease: options.prerelease ?? false
1015
893
  });
1016
- success3(`Release updated: ${response.data.html_url}`);
894
+ success2(`Release updated: ${response.data.html_url}`);
1017
895
  return {
1018
896
  id: response.data.id,
1019
897
  htmlUrl: response.data.html_url,
@@ -1063,7 +941,7 @@ async function createGitHubRelease(context, options) {
1063
941
  }
1064
942
 
1065
943
  // src/templates/ejs.ts
1066
- import * as fs4 from "fs";
944
+ import * as fs3 from "fs";
1067
945
  import ejs from "ejs";
1068
946
  function renderEjs(template, context) {
1069
947
  try {
@@ -1073,16 +951,16 @@ function renderEjs(template, context) {
1073
951
  }
1074
952
  }
1075
953
  function renderEjsFile(filePath, context) {
1076
- if (!fs4.existsSync(filePath)) {
954
+ if (!fs3.existsSync(filePath)) {
1077
955
  throw new TemplateError(`Template file not found: ${filePath}`);
1078
956
  }
1079
- const template = fs4.readFileSync(filePath, "utf-8");
957
+ const template = fs3.readFileSync(filePath, "utf-8");
1080
958
  return renderEjs(template, context);
1081
959
  }
1082
960
 
1083
961
  // src/templates/handlebars.ts
1084
- import * as fs5 from "fs";
1085
- import * as path3 from "path";
962
+ import * as fs4 from "fs";
963
+ import * as path2 from "path";
1086
964
  import Handlebars from "handlebars";
1087
965
  function registerHandlebarsHelpers() {
1088
966
  Handlebars.registerHelper("capitalize", (str) => {
@@ -1108,28 +986,28 @@ function renderHandlebars(template, context) {
1108
986
  }
1109
987
  }
1110
988
  function renderHandlebarsFile(filePath, context) {
1111
- if (!fs5.existsSync(filePath)) {
989
+ if (!fs4.existsSync(filePath)) {
1112
990
  throw new TemplateError(`Template file not found: ${filePath}`);
1113
991
  }
1114
- const template = fs5.readFileSync(filePath, "utf-8");
992
+ const template = fs4.readFileSync(filePath, "utf-8");
1115
993
  return renderHandlebars(template, context);
1116
994
  }
1117
995
  function renderHandlebarsComposable(templateDir, context) {
1118
996
  registerHandlebarsHelpers();
1119
- const versionPath = path3.join(templateDir, "version.hbs");
1120
- const entryPath = path3.join(templateDir, "entry.hbs");
1121
- const documentPath = path3.join(templateDir, "document.hbs");
1122
- if (!fs5.existsSync(documentPath)) {
997
+ const versionPath = path2.join(templateDir, "version.hbs");
998
+ const entryPath = path2.join(templateDir, "entry.hbs");
999
+ const documentPath = path2.join(templateDir, "document.hbs");
1000
+ if (!fs4.existsSync(documentPath)) {
1123
1001
  throw new TemplateError(`Document template not found: ${documentPath}`);
1124
1002
  }
1125
- if (fs5.existsSync(versionPath)) {
1126
- Handlebars.registerPartial("version", fs5.readFileSync(versionPath, "utf-8"));
1003
+ if (fs4.existsSync(versionPath)) {
1004
+ Handlebars.registerPartial("version", fs4.readFileSync(versionPath, "utf-8"));
1127
1005
  }
1128
- if (fs5.existsSync(entryPath)) {
1129
- Handlebars.registerPartial("entry", fs5.readFileSync(entryPath, "utf-8"));
1006
+ if (fs4.existsSync(entryPath)) {
1007
+ Handlebars.registerPartial("entry", fs4.readFileSync(entryPath, "utf-8"));
1130
1008
  }
1131
1009
  try {
1132
- const compiled = Handlebars.compile(fs5.readFileSync(documentPath, "utf-8"));
1010
+ const compiled = Handlebars.compile(fs4.readFileSync(documentPath, "utf-8"));
1133
1011
  return compiled(context);
1134
1012
  } catch (error) {
1135
1013
  throw new TemplateError(`Handlebars render error: ${error instanceof Error ? error.message : String(error)}`);
@@ -1137,8 +1015,8 @@ function renderHandlebarsComposable(templateDir, context) {
1137
1015
  }
1138
1016
 
1139
1017
  // src/templates/liquid.ts
1140
- import * as fs6 from "fs";
1141
- import * as path4 from "path";
1018
+ import * as fs5 from "fs";
1019
+ import * as path3 from "path";
1142
1020
  import { Liquid } from "liquidjs";
1143
1021
  function createLiquidEngine(root) {
1144
1022
  return new Liquid({
@@ -1156,15 +1034,15 @@ function renderLiquid(template, context) {
1156
1034
  }
1157
1035
  }
1158
1036
  function renderLiquidFile(filePath, context) {
1159
- if (!fs6.existsSync(filePath)) {
1037
+ if (!fs5.existsSync(filePath)) {
1160
1038
  throw new TemplateError(`Template file not found: ${filePath}`);
1161
1039
  }
1162
- const template = fs6.readFileSync(filePath, "utf-8");
1040
+ const template = fs5.readFileSync(filePath, "utf-8");
1163
1041
  return renderLiquid(template, context);
1164
1042
  }
1165
1043
  function renderLiquidComposable(templateDir, context) {
1166
- const documentPath = path4.join(templateDir, "document.liquid");
1167
- if (!fs6.existsSync(documentPath)) {
1044
+ const documentPath = path3.join(templateDir, "document.liquid");
1045
+ if (!fs5.existsSync(documentPath)) {
1168
1046
  throw new TemplateError(`Document template not found: ${documentPath}`);
1169
1047
  }
1170
1048
  const engine = createLiquidEngine(templateDir);
@@ -1176,10 +1054,10 @@ function renderLiquidComposable(templateDir, context) {
1176
1054
  }
1177
1055
 
1178
1056
  // src/templates/loader.ts
1179
- import * as fs7 from "fs";
1180
- import * as path5 from "path";
1057
+ import * as fs6 from "fs";
1058
+ import * as path4 from "path";
1181
1059
  function getEngineFromFile(filePath) {
1182
- const ext = path5.extname(filePath).toLowerCase();
1060
+ const ext = path4.extname(filePath).toLowerCase();
1183
1061
  switch (ext) {
1184
1062
  case ".liquid":
1185
1063
  return "liquid";
@@ -1213,10 +1091,10 @@ function getRenderFileFn(engine) {
1213
1091
  }
1214
1092
  }
1215
1093
  function detectTemplateMode(templatePath) {
1216
- if (!fs7.existsSync(templatePath)) {
1094
+ if (!fs6.existsSync(templatePath)) {
1217
1095
  throw new TemplateError(`Template path not found: ${templatePath}`);
1218
1096
  }
1219
- const stat = fs7.statSync(templatePath);
1097
+ const stat = fs6.statSync(templatePath);
1220
1098
  if (stat.isFile()) {
1221
1099
  return "single";
1222
1100
  }
@@ -1234,7 +1112,7 @@ function renderSingleFile(templatePath, context, engine) {
1234
1112
  };
1235
1113
  }
1236
1114
  function renderComposable(templateDir, context, engine) {
1237
- const files = fs7.readdirSync(templateDir);
1115
+ const files = fs6.readdirSync(templateDir);
1238
1116
  const engineMap = {
1239
1117
  liquid: { document: "document.liquid", version: "version.liquid", entry: "entry.liquid" },
1240
1118
  handlebars: { document: "document.hbs", version: "version.hbs", entry: "entry.hbs" },
@@ -1257,15 +1135,15 @@ function renderComposable(templateDir, context, engine) {
1257
1135
  return { content: renderHandlebarsComposable(templateDir, context), engine: resolvedEngine };
1258
1136
  }
1259
1137
  const expectedFiles = engineMap[resolvedEngine];
1260
- const documentPath = path5.join(templateDir, expectedFiles.document);
1261
- if (!fs7.existsSync(documentPath)) {
1138
+ const documentPath = path4.join(templateDir, expectedFiles.document);
1139
+ if (!fs6.existsSync(documentPath)) {
1262
1140
  throw new TemplateError(`Document template not found: ${expectedFiles.document}`);
1263
1141
  }
1264
- const versionPath = path5.join(templateDir, expectedFiles.version);
1265
- const entryPath = path5.join(templateDir, expectedFiles.entry);
1142
+ const versionPath = path4.join(templateDir, expectedFiles.version);
1143
+ const entryPath = path4.join(templateDir, expectedFiles.entry);
1266
1144
  const render = getRenderFn(resolvedEngine);
1267
- const entryTemplate = fs7.existsSync(entryPath) ? fs7.readFileSync(entryPath, "utf-8") : null;
1268
- const versionTemplate = fs7.existsSync(versionPath) ? fs7.readFileSync(versionPath, "utf-8") : null;
1145
+ const entryTemplate = fs6.existsSync(entryPath) ? fs6.readFileSync(entryPath, "utf-8") : null;
1146
+ const versionTemplate = fs6.existsSync(versionPath) ? fs6.readFileSync(versionPath, "utf-8") : null;
1269
1147
  if (entryTemplate && versionTemplate) {
1270
1148
  const versionsWithEntries = context.versions.map((versionCtx) => {
1271
1149
  const entries = versionCtx.entries.map((entry) => {
@@ -1276,7 +1154,7 @@ function renderComposable(templateDir, context, engine) {
1276
1154
  });
1277
1155
  const docContext = { ...context, renderedVersions: versionsWithEntries };
1278
1156
  return {
1279
- content: render(fs7.readFileSync(documentPath, "utf-8"), docContext),
1157
+ content: render(fs6.readFileSync(documentPath, "utf-8"), docContext),
1280
1158
  engine: resolvedEngine
1281
1159
  };
1282
1160
  }
@@ -1383,9 +1261,9 @@ async function processWithLLM(context, config) {
1383
1261
  entries: context.entries
1384
1262
  };
1385
1263
  try {
1386
- info4(`Using LLM provider: ${config.llm.provider}${config.llm.model ? ` (${config.llm.model})` : ""}`);
1264
+ info3(`Using LLM provider: ${config.llm.provider}${config.llm.model ? ` (${config.llm.model})` : ""}`);
1387
1265
  if (config.llm.baseURL) {
1388
- info4(`LLM base URL: ${config.llm.baseURL}`);
1266
+ info3(`LLM base URL: ${config.llm.baseURL}`);
1389
1267
  }
1390
1268
  const rawProvider = createProvider(config.llm);
1391
1269
  const retryOpts = config.llm.retry ?? LLM_DEFAULTS.retry;
@@ -1394,47 +1272,47 @@ async function processWithLLM(context, config) {
1394
1272
  complete: (prompt, opts) => withRetry(() => rawProvider.complete(prompt, opts), retryOpts)
1395
1273
  };
1396
1274
  const activeTasks = Object.entries(tasks).filter(([, enabled]) => enabled).map(([name]) => name);
1397
- info4(`Running LLM tasks: ${activeTasks.join(", ")}`);
1275
+ info3(`Running LLM tasks: ${activeTasks.join(", ")}`);
1398
1276
  if (tasks.enhance && tasks.categorize) {
1399
- info4("Enhancing and categorizing entries with LLM...");
1277
+ info3("Enhancing and categorizing entries with LLM...");
1400
1278
  const result = await enhanceAndCategorize(provider, context.entries, llmContext);
1401
1279
  enhanced.entries = result.enhancedEntries;
1402
1280
  enhanced.categories = {};
1403
1281
  for (const cat of result.categories) {
1404
1282
  enhanced.categories[cat.category] = cat.entries;
1405
1283
  }
1406
- info4(`Enhanced ${enhanced.entries.length} entries into ${result.categories.length} categories`);
1284
+ info3(`Enhanced ${enhanced.entries.length} entries into ${result.categories.length} categories`);
1407
1285
  } else {
1408
1286
  if (tasks.enhance) {
1409
- info4("Enhancing entries with LLM...");
1287
+ info3("Enhancing entries with LLM...");
1410
1288
  enhanced.entries = await enhanceEntries(provider, context.entries, llmContext, config.llm.concurrency);
1411
- info4(`Enhanced ${enhanced.entries.length} entries`);
1289
+ info3(`Enhanced ${enhanced.entries.length} entries`);
1412
1290
  }
1413
1291
  if (tasks.categorize) {
1414
- info4("Categorizing entries with LLM...");
1292
+ info3("Categorizing entries with LLM...");
1415
1293
  const categorized = await categorizeEntries(provider, enhanced.entries, llmContext);
1416
1294
  enhanced.categories = {};
1417
1295
  for (const cat of categorized) {
1418
1296
  enhanced.categories[cat.category] = cat.entries;
1419
1297
  }
1420
- info4(`Created ${categorized.length} categories`);
1298
+ info3(`Created ${categorized.length} categories`);
1421
1299
  }
1422
1300
  }
1423
1301
  if (tasks.summarize) {
1424
- info4("Summarizing entries with LLM...");
1302
+ info3("Summarizing entries with LLM...");
1425
1303
  enhanced.summary = await summarizeEntries(provider, enhanced.entries, llmContext);
1426
1304
  if (enhanced.summary) {
1427
- info4("Summary generated successfully");
1428
- debug3(`Summary: ${enhanced.summary.substring(0, 100)}...`);
1305
+ info3("Summary generated successfully");
1306
+ debug2(`Summary: ${enhanced.summary.substring(0, 100)}...`);
1429
1307
  } else {
1430
1308
  warn3("Summary generation returned empty result");
1431
1309
  }
1432
1310
  }
1433
1311
  if (tasks.releaseNotes) {
1434
- info4("Generating release notes with LLM...");
1312
+ info3("Generating release notes with LLM...");
1435
1313
  enhanced.releaseNotes = await generateReleaseNotes(provider, enhanced.entries, llmContext);
1436
1314
  if (enhanced.releaseNotes) {
1437
- info4("Release notes generated successfully");
1315
+ info3("Release notes generated successfully");
1438
1316
  } else {
1439
1317
  warn3("Release notes generation returned empty result");
1440
1318
  }
@@ -1453,17 +1331,17 @@ function getBuiltinTemplatePath(style) {
1453
1331
  let packageRoot;
1454
1332
  try {
1455
1333
  const currentUrl = import.meta.url;
1456
- packageRoot = path6.dirname(new URL(currentUrl).pathname);
1457
- packageRoot = path6.join(packageRoot, "..", "..");
1334
+ packageRoot = path5.dirname(new URL(currentUrl).pathname);
1335
+ packageRoot = path5.join(packageRoot, "..", "..");
1458
1336
  } catch {
1459
1337
  packageRoot = __dirname;
1460
1338
  }
1461
- return path6.join(packageRoot, "templates", style);
1339
+ return path5.join(packageRoot, "templates", style);
1462
1340
  }
1463
1341
  async function generateWithTemplate(contexts, config, outputPath, dryRun) {
1464
1342
  let templatePath;
1465
1343
  if (config.templates?.path) {
1466
- templatePath = path6.resolve(config.templates.path);
1344
+ templatePath = path5.resolve(config.templates.path);
1467
1345
  } else {
1468
1346
  templatePath = getBuiltinTemplatePath("keep-a-changelog");
1469
1347
  }
@@ -1473,52 +1351,63 @@ async function generateWithTemplate(contexts, config, outputPath, dryRun) {
1473
1351
  );
1474
1352
  const result = renderTemplate(templatePath, documentContext, config.templates?.engine);
1475
1353
  if (dryRun) {
1476
- info4(`Would write templated output to ${outputPath}`);
1477
- debug3("--- Changelog Preview ---");
1478
- debug3(result.content);
1479
- debug3("--- End Preview ---");
1354
+ info3(`Would write templated output to ${outputPath}`);
1355
+ debug2("--- Changelog Preview ---");
1356
+ debug2(result.content);
1357
+ debug2("--- End Preview ---");
1480
1358
  return;
1481
1359
  }
1482
1360
  if (outputPath === "-") {
1483
1361
  process.stdout.write(result.content);
1484
1362
  return;
1485
1363
  }
1486
- const dir = path6.dirname(outputPath);
1487
- if (!fs8.existsSync(dir)) {
1488
- fs8.mkdirSync(dir, { recursive: true });
1364
+ const dir = path5.dirname(outputPath);
1365
+ if (!fs7.existsSync(dir)) {
1366
+ fs7.mkdirSync(dir, { recursive: true });
1489
1367
  }
1490
- fs8.writeFileSync(outputPath, result.content, "utf-8");
1491
- success4(`Changelog written to ${outputPath} (using ${result.engine} template)`);
1368
+ fs7.writeFileSync(outputPath, result.content, "utf-8");
1369
+ success3(`Changelog written to ${outputPath} (using ${result.engine} template)`);
1492
1370
  }
1493
1371
  async function runPipeline(input, config, dryRun) {
1494
- debug3(`Processing ${input.packages.length} package(s)`);
1372
+ debug2(`Processing ${input.packages.length} package(s)`);
1495
1373
  let contexts = input.packages.map(createTemplateContext);
1496
1374
  if (config.llm && !process.env.CHANGELOG_NO_LLM) {
1497
- info4("Processing with LLM enhancement");
1375
+ info3("Processing with LLM enhancement");
1498
1376
  contexts = await Promise.all(contexts.map((ctx) => processWithLLM(ctx, config)));
1499
1377
  }
1378
+ const files = [];
1500
1379
  for (const output of config.output) {
1501
- info4(`Generating ${output.format} output`);
1380
+ info3(`Generating ${output.format} output`);
1502
1381
  switch (output.format) {
1503
1382
  case "markdown": {
1504
1383
  const file = output.file ?? "CHANGELOG.md";
1505
- const effectiveTemplateConfig = output.templates ?? config.templates;
1506
- if (effectiveTemplateConfig?.path || output.options?.template) {
1507
- const configWithTemplate = { ...config, templates: effectiveTemplateConfig };
1508
- await generateWithTemplate(contexts, configWithTemplate, file, dryRun);
1509
- } else {
1510
- writeMarkdown(file, contexts, config, dryRun);
1384
+ try {
1385
+ const effectiveTemplateConfig = output.templates ?? config.templates;
1386
+ if (effectiveTemplateConfig?.path || output.options?.template) {
1387
+ const configWithTemplate = { ...config, templates: effectiveTemplateConfig };
1388
+ await generateWithTemplate(contexts, configWithTemplate, file, dryRun);
1389
+ } else {
1390
+ writeMarkdown(file, contexts, config, dryRun);
1391
+ }
1392
+ if (!dryRun) files.push(file);
1393
+ } catch (error) {
1394
+ warn3(`Failed to write ${file}: ${error instanceof Error ? error.message : String(error)}`);
1511
1395
  }
1512
1396
  break;
1513
1397
  }
1514
1398
  case "json": {
1515
1399
  const file = output.file ?? "changelog.json";
1516
- writeJson(file, contexts, dryRun);
1400
+ try {
1401
+ writeJson(file, contexts, dryRun);
1402
+ if (!dryRun) files.push(file);
1403
+ } catch (error) {
1404
+ warn3(`Failed to write ${file}: ${error instanceof Error ? error.message : String(error)}`);
1405
+ }
1517
1406
  break;
1518
1407
  }
1519
1408
  case "github-release": {
1520
1409
  if (dryRun) {
1521
- info4("[DRY RUN] Would create GitHub release");
1410
+ info3("[DRY RUN] Would create GitHub release");
1522
1411
  break;
1523
1412
  }
1524
1413
  const firstContext = contexts[0];
@@ -1546,139 +1435,33 @@ async function runPipeline(input, config, dryRun) {
1546
1435
  }
1547
1436
  }
1548
1437
  }
1549
- }
1550
- async function processInput(inputJson, config, dryRun) {
1551
- const input = parsePackageVersioner(inputJson);
1552
- await runPipeline(input, config, dryRun);
1553
- }
1554
-
1555
- // src/monorepo/aggregator.ts
1556
- import * as fs9 from "fs";
1557
- import * as path7 from "path";
1558
- import { debug as debug4, info as info5, success as success5 } from "@releasekit/core";
1559
-
1560
- // src/monorepo/splitter.ts
1561
- function splitByPackage(contexts) {
1562
- const byPackage = /* @__PURE__ */ new Map();
1563
- for (const ctx of contexts) {
1564
- byPackage.set(ctx.packageName, ctx);
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
- }
1438
+ if (config.monorepo?.mode) {
1439
+ const { detectMonorepo, writeMonorepoChangelogs } = await import("./aggregator-BDTUZWOA.js");
1440
+ const cwd = process.cwd();
1441
+ const detected = detectMonorepo(cwd);
1442
+ if (detected.isMonorepo) {
1443
+ const monoFiles = writeMonorepoChangelogs(
1444
+ contexts,
1445
+ {
1446
+ rootPath: config.monorepo.rootPath ?? cwd,
1447
+ packagesPath: config.monorepo.packagesPath ?? detected.packagesPath,
1448
+ mode: config.monorepo.mode
1449
+ },
1450
+ config,
1451
+ dryRun
1452
+ );
1453
+ files.push(...monoFiles);
1624
1454
  }
1625
1455
  }
1626
- }
1627
- function buildPackageDirMap(rootPath, packagesPath) {
1628
- const map = /* @__PURE__ */ new Map();
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
- }
1456
+ const packageNotes = {};
1457
+ for (const ctx of contexts) {
1458
+ packageNotes[ctx.packageName] = formatVersion(ctx);
1647
1459
  }
1648
- return map;
1460
+ return { packageNotes, files };
1649
1461
  }
1650
- function detectMonorepo(cwd) {
1651
- const pnpmWorkspacesPath = path7.join(cwd, "pnpm-workspace.yaml");
1652
- const packageJsonPath = path7.join(cwd, "package.json");
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: "" };
1462
+ async function processInput(inputJson, config, dryRun) {
1463
+ const input = parsePackageVersioner(inputJson);
1464
+ return runPipeline(input, config, dryRun);
1682
1465
  }
1683
1466
 
1684
1467
  export {
@@ -1697,14 +1480,9 @@ export {
1697
1480
  parsePackageVersioner,
1698
1481
  parsePackageVersionerFile,
1699
1482
  parsePackageVersionerStdin,
1700
- renderMarkdown,
1701
- writeMarkdown,
1702
1483
  renderJson,
1703
1484
  writeJson,
1704
1485
  createTemplateContext,
1705
1486
  runPipeline,
1706
- processInput,
1707
- aggregateToRoot,
1708
- writeMonorepoChangelogs,
1709
- detectMonorepo
1487
+ processInput
1710
1488
  };