@releasekit/notes 0.2.0-next.1 → 0.2.0-next.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/{chunk-W7DVGQ7D.js → chunk-H44KSHFJ.js} +107 -21
- package/dist/cli.cjs +168 -73
- package/dist/cli.js +11 -2
- package/dist/index.cjs +141 -55
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -307,7 +307,7 @@ function writeJson(outputPath, contexts, dryRun) {
|
|
|
307
307
|
// src/core/pipeline.ts
|
|
308
308
|
import * as fs8 from "fs";
|
|
309
309
|
import * as path6 from "path";
|
|
310
|
-
import { debug, info as info4, success as success4, warn as
|
|
310
|
+
import { debug, info as info4, success as success4, warn as warn3 } from "@releasekit/core";
|
|
311
311
|
|
|
312
312
|
// src/llm/defaults.ts
|
|
313
313
|
var LLM_DEFAULTS = {
|
|
@@ -624,6 +624,81 @@ async function enhanceEntries(provider, entries, context, concurrency = LLM_DEFA
|
|
|
624
624
|
return results;
|
|
625
625
|
}
|
|
626
626
|
|
|
627
|
+
// src/llm/tasks/enhance-and-categorize.ts
|
|
628
|
+
import { warn as warn2 } from "@releasekit/core";
|
|
629
|
+
function buildPrompt(entries, categories, style) {
|
|
630
|
+
const entriesText = entries.map((e, i) => `${i}. [${e.type}]${e.scope ? ` (${e.scope})` : ""}: ${e.description}`).join("\n");
|
|
631
|
+
const styleText = style || 'Use present tense ("Add feature" not "Added feature"). Be concise.';
|
|
632
|
+
const categorySection = categories ? `Categories (use ONLY these):
|
|
633
|
+
${categories.map((c) => `- "${c.name}": ${c.description}`).join("\n")}` : `Categories: Group into meaningful categories (e.g., "New", "Fixed", "Changed", "Removed").`;
|
|
634
|
+
return `You are generating release notes for a software project. Given the following changelog entries, do two things:
|
|
635
|
+
|
|
636
|
+
1. **Rewrite** each entry as a clear, user-friendly description
|
|
637
|
+
2. **Categorize** each entry into the appropriate category
|
|
638
|
+
|
|
639
|
+
Style guidelines:
|
|
640
|
+
- ${styleText}
|
|
641
|
+
- Be concise (1 short sentence per entry)
|
|
642
|
+
- Focus on what changed, not implementation details
|
|
643
|
+
|
|
644
|
+
${categorySection}
|
|
645
|
+
|
|
646
|
+
${categories ? 'For entries in categories involving internal/developer changes, set a "scope" field with a short subcategory label (e.g., "CI", "Dependencies", "Testing").' : ""}
|
|
647
|
+
|
|
648
|
+
Entries:
|
|
649
|
+
${entriesText}
|
|
650
|
+
|
|
651
|
+
Output a JSON object with:
|
|
652
|
+
- "entries": array of objects, one per input entry (same order), each with: { "description": "rewritten text", "category": "CategoryName", "scope": "optional subcategory label or null" }
|
|
653
|
+
|
|
654
|
+
Output only valid JSON, nothing else:`;
|
|
655
|
+
}
|
|
656
|
+
async function enhanceAndCategorize(provider, entries, context) {
|
|
657
|
+
if (entries.length === 0) {
|
|
658
|
+
return { enhancedEntries: [], categories: [] };
|
|
659
|
+
}
|
|
660
|
+
const prompt = buildPrompt(entries, context.categories, context.style);
|
|
661
|
+
try {
|
|
662
|
+
const response = await provider.complete(prompt);
|
|
663
|
+
const cleaned = response.replace(/^```(?:json)?\n?/, "").replace(/\n?```$/, "").trim();
|
|
664
|
+
const parsed = JSON.parse(cleaned);
|
|
665
|
+
if (!Array.isArray(parsed.entries)) {
|
|
666
|
+
throw new Error('Response missing "entries" array');
|
|
667
|
+
}
|
|
668
|
+
const enhancedEntries = entries.map((original, i) => {
|
|
669
|
+
const result = parsed.entries[i];
|
|
670
|
+
if (!result) return original;
|
|
671
|
+
return {
|
|
672
|
+
...original,
|
|
673
|
+
description: result.description || original.description,
|
|
674
|
+
scope: result.scope || original.scope
|
|
675
|
+
};
|
|
676
|
+
});
|
|
677
|
+
const categoryMap = /* @__PURE__ */ new Map();
|
|
678
|
+
for (let i = 0; i < parsed.entries.length; i++) {
|
|
679
|
+
const result = parsed.entries[i];
|
|
680
|
+
const category = result?.category || "General";
|
|
681
|
+
const entry = enhancedEntries[i];
|
|
682
|
+
if (!entry) continue;
|
|
683
|
+
if (!categoryMap.has(category)) {
|
|
684
|
+
categoryMap.set(category, []);
|
|
685
|
+
}
|
|
686
|
+
categoryMap.get(category).push(entry);
|
|
687
|
+
}
|
|
688
|
+
const categories = [];
|
|
689
|
+
for (const [category, catEntries] of categoryMap) {
|
|
690
|
+
categories.push({ category, entries: catEntries });
|
|
691
|
+
}
|
|
692
|
+
return { enhancedEntries, categories };
|
|
693
|
+
} catch (error) {
|
|
694
|
+
warn2(`Combined enhance+categorize failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
695
|
+
return {
|
|
696
|
+
enhancedEntries: entries,
|
|
697
|
+
categories: [{ category: "General", entries }]
|
|
698
|
+
};
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
|
|
627
702
|
// src/llm/tasks/release-notes.ts
|
|
628
703
|
var RELEASE_NOTES_PROMPT = `You are writing release notes for a software project.
|
|
629
704
|
|
|
@@ -1183,10 +1258,30 @@ async function processWithLLM(context, config) {
|
|
|
1183
1258
|
};
|
|
1184
1259
|
const activeTasks = Object.entries(tasks).filter(([, enabled]) => enabled).map(([name]) => name);
|
|
1185
1260
|
info4(`Running LLM tasks: ${activeTasks.join(", ")}`);
|
|
1186
|
-
if (tasks.enhance) {
|
|
1187
|
-
info4("Enhancing entries with LLM...");
|
|
1188
|
-
|
|
1189
|
-
|
|
1261
|
+
if (tasks.enhance && tasks.categorize) {
|
|
1262
|
+
info4("Enhancing and categorizing entries with LLM (single call)...");
|
|
1263
|
+
const result = await enhanceAndCategorize(provider, context.entries, llmContext);
|
|
1264
|
+
enhanced.entries = result.enhancedEntries;
|
|
1265
|
+
enhanced.categories = {};
|
|
1266
|
+
for (const cat of result.categories) {
|
|
1267
|
+
enhanced.categories[cat.category] = cat.entries;
|
|
1268
|
+
}
|
|
1269
|
+
info4(`Enhanced ${enhanced.entries.length} entries into ${result.categories.length} categories`);
|
|
1270
|
+
} else {
|
|
1271
|
+
if (tasks.enhance) {
|
|
1272
|
+
info4("Enhancing entries with LLM...");
|
|
1273
|
+
enhanced.entries = await enhanceEntries(provider, context.entries, llmContext, config.llm.concurrency);
|
|
1274
|
+
info4(`Enhanced ${enhanced.entries.length} entries`);
|
|
1275
|
+
}
|
|
1276
|
+
if (tasks.categorize) {
|
|
1277
|
+
info4("Categorizing entries with LLM...");
|
|
1278
|
+
const categorized = await categorizeEntries(provider, enhanced.entries, llmContext);
|
|
1279
|
+
enhanced.categories = {};
|
|
1280
|
+
for (const cat of categorized) {
|
|
1281
|
+
enhanced.categories[cat.category] = cat.entries;
|
|
1282
|
+
}
|
|
1283
|
+
info4(`Created ${categorized.length} categories`);
|
|
1284
|
+
}
|
|
1190
1285
|
}
|
|
1191
1286
|
if (tasks.summarize) {
|
|
1192
1287
|
info4("Summarizing entries with LLM...");
|
|
@@ -1195,17 +1290,8 @@ async function processWithLLM(context, config) {
|
|
|
1195
1290
|
info4("Summary generated successfully");
|
|
1196
1291
|
debug(`Summary: ${enhanced.summary.substring(0, 100)}...`);
|
|
1197
1292
|
} else {
|
|
1198
|
-
|
|
1199
|
-
}
|
|
1200
|
-
}
|
|
1201
|
-
if (tasks.categorize) {
|
|
1202
|
-
info4("Categorizing entries with LLM...");
|
|
1203
|
-
const categorized = await categorizeEntries(provider, enhanced.entries, llmContext);
|
|
1204
|
-
enhanced.categories = {};
|
|
1205
|
-
for (const cat of categorized) {
|
|
1206
|
-
enhanced.categories[cat.category] = cat.entries;
|
|
1293
|
+
warn3("Summary generation returned empty result");
|
|
1207
1294
|
}
|
|
1208
|
-
info4(`Created ${categorized.length} categories`);
|
|
1209
1295
|
}
|
|
1210
1296
|
if (tasks.releaseNotes) {
|
|
1211
1297
|
info4("Generating release notes with LLM...");
|
|
@@ -1213,7 +1299,7 @@ async function processWithLLM(context, config) {
|
|
|
1213
1299
|
if (enhanced.releaseNotes) {
|
|
1214
1300
|
info4("Release notes generated successfully");
|
|
1215
1301
|
} else {
|
|
1216
|
-
|
|
1302
|
+
warn3("Release notes generation returned empty result");
|
|
1217
1303
|
}
|
|
1218
1304
|
}
|
|
1219
1305
|
return {
|
|
@@ -1222,8 +1308,8 @@ async function processWithLLM(context, config) {
|
|
|
1222
1308
|
enhanced
|
|
1223
1309
|
};
|
|
1224
1310
|
} catch (error) {
|
|
1225
|
-
|
|
1226
|
-
|
|
1311
|
+
warn3(`LLM processing failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
1312
|
+
warn3("Falling back to raw entries");
|
|
1227
1313
|
return context;
|
|
1228
1314
|
}
|
|
1229
1315
|
}
|
|
@@ -1294,17 +1380,17 @@ async function runPipeline(input, config, dryRun) {
|
|
|
1294
1380
|
}
|
|
1295
1381
|
const firstContext = contexts[0];
|
|
1296
1382
|
if (!firstContext) {
|
|
1297
|
-
|
|
1383
|
+
warn3("No context available for GitHub release");
|
|
1298
1384
|
break;
|
|
1299
1385
|
}
|
|
1300
1386
|
const repoUrl = firstContext.repoUrl;
|
|
1301
1387
|
if (!repoUrl) {
|
|
1302
|
-
|
|
1388
|
+
warn3("No repo URL available, cannot create GitHub release");
|
|
1303
1389
|
break;
|
|
1304
1390
|
}
|
|
1305
1391
|
const parsed = parseRepoUrl(repoUrl);
|
|
1306
1392
|
if (!parsed) {
|
|
1307
|
-
|
|
1393
|
+
warn3(`Could not parse repo URL: ${repoUrl}`);
|
|
1308
1394
|
break;
|
|
1309
1395
|
}
|
|
1310
1396
|
await createGitHubRelease(firstContext, {
|
package/dist/cli.cjs
CHANGED
|
@@ -26,7 +26,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
// src/cli.ts
|
|
27
27
|
var fs10 = __toESM(require("fs"), 1);
|
|
28
28
|
var readline = __toESM(require("readline"), 1);
|
|
29
|
-
var
|
|
29
|
+
var import_core10 = require("@releasekit/core");
|
|
30
30
|
var import_commander = require("commander");
|
|
31
31
|
|
|
32
32
|
// src/core/config.ts
|
|
@@ -45,7 +45,7 @@ function getDefaultConfig() {
|
|
|
45
45
|
// src/core/pipeline.ts
|
|
46
46
|
var fs8 = __toESM(require("fs"), 1);
|
|
47
47
|
var path6 = __toESM(require("path"), 1);
|
|
48
|
-
var
|
|
48
|
+
var import_core8 = require("@releasekit/core");
|
|
49
49
|
|
|
50
50
|
// src/input/package-versioner.ts
|
|
51
51
|
var fs = __toESM(require("fs"), 1);
|
|
@@ -474,6 +474,81 @@ async function enhanceEntries(provider, entries, context, concurrency = LLM_DEFA
|
|
|
474
474
|
return results;
|
|
475
475
|
}
|
|
476
476
|
|
|
477
|
+
// src/llm/tasks/enhance-and-categorize.ts
|
|
478
|
+
var import_core4 = require("@releasekit/core");
|
|
479
|
+
function buildPrompt(entries, categories, style) {
|
|
480
|
+
const entriesText = entries.map((e, i) => `${i}. [${e.type}]${e.scope ? ` (${e.scope})` : ""}: ${e.description}`).join("\n");
|
|
481
|
+
const styleText = style || 'Use present tense ("Add feature" not "Added feature"). Be concise.';
|
|
482
|
+
const categorySection = categories ? `Categories (use ONLY these):
|
|
483
|
+
${categories.map((c) => `- "${c.name}": ${c.description}`).join("\n")}` : `Categories: Group into meaningful categories (e.g., "New", "Fixed", "Changed", "Removed").`;
|
|
484
|
+
return `You are generating release notes for a software project. Given the following changelog entries, do two things:
|
|
485
|
+
|
|
486
|
+
1. **Rewrite** each entry as a clear, user-friendly description
|
|
487
|
+
2. **Categorize** each entry into the appropriate category
|
|
488
|
+
|
|
489
|
+
Style guidelines:
|
|
490
|
+
- ${styleText}
|
|
491
|
+
- Be concise (1 short sentence per entry)
|
|
492
|
+
- Focus on what changed, not implementation details
|
|
493
|
+
|
|
494
|
+
${categorySection}
|
|
495
|
+
|
|
496
|
+
${categories ? 'For entries in categories involving internal/developer changes, set a "scope" field with a short subcategory label (e.g., "CI", "Dependencies", "Testing").' : ""}
|
|
497
|
+
|
|
498
|
+
Entries:
|
|
499
|
+
${entriesText}
|
|
500
|
+
|
|
501
|
+
Output a JSON object with:
|
|
502
|
+
- "entries": array of objects, one per input entry (same order), each with: { "description": "rewritten text", "category": "CategoryName", "scope": "optional subcategory label or null" }
|
|
503
|
+
|
|
504
|
+
Output only valid JSON, nothing else:`;
|
|
505
|
+
}
|
|
506
|
+
async function enhanceAndCategorize(provider, entries, context) {
|
|
507
|
+
if (entries.length === 0) {
|
|
508
|
+
return { enhancedEntries: [], categories: [] };
|
|
509
|
+
}
|
|
510
|
+
const prompt = buildPrompt(entries, context.categories, context.style);
|
|
511
|
+
try {
|
|
512
|
+
const response = await provider.complete(prompt);
|
|
513
|
+
const cleaned = response.replace(/^```(?:json)?\n?/, "").replace(/\n?```$/, "").trim();
|
|
514
|
+
const parsed = JSON.parse(cleaned);
|
|
515
|
+
if (!Array.isArray(parsed.entries)) {
|
|
516
|
+
throw new Error('Response missing "entries" array');
|
|
517
|
+
}
|
|
518
|
+
const enhancedEntries = entries.map((original, i) => {
|
|
519
|
+
const result = parsed.entries[i];
|
|
520
|
+
if (!result) return original;
|
|
521
|
+
return {
|
|
522
|
+
...original,
|
|
523
|
+
description: result.description || original.description,
|
|
524
|
+
scope: result.scope || original.scope
|
|
525
|
+
};
|
|
526
|
+
});
|
|
527
|
+
const categoryMap = /* @__PURE__ */ new Map();
|
|
528
|
+
for (let i = 0; i < parsed.entries.length; i++) {
|
|
529
|
+
const result = parsed.entries[i];
|
|
530
|
+
const category = result?.category || "General";
|
|
531
|
+
const entry = enhancedEntries[i];
|
|
532
|
+
if (!entry) continue;
|
|
533
|
+
if (!categoryMap.has(category)) {
|
|
534
|
+
categoryMap.set(category, []);
|
|
535
|
+
}
|
|
536
|
+
categoryMap.get(category).push(entry);
|
|
537
|
+
}
|
|
538
|
+
const categories = [];
|
|
539
|
+
for (const [category, catEntries] of categoryMap) {
|
|
540
|
+
categories.push({ category, entries: catEntries });
|
|
541
|
+
}
|
|
542
|
+
return { enhancedEntries, categories };
|
|
543
|
+
} catch (error2) {
|
|
544
|
+
(0, import_core4.warn)(`Combined enhance+categorize failed: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
545
|
+
return {
|
|
546
|
+
enhancedEntries: entries,
|
|
547
|
+
categories: [{ category: "General", entries }]
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
477
552
|
// src/llm/tasks/release-notes.ts
|
|
478
553
|
var RELEASE_NOTES_PROMPT = `You are writing release notes for a software project.
|
|
479
554
|
|
|
@@ -574,12 +649,12 @@ function createProvider(config) {
|
|
|
574
649
|
|
|
575
650
|
// src/output/github-release.ts
|
|
576
651
|
var import_rest = require("@octokit/rest");
|
|
577
|
-
var
|
|
652
|
+
var import_core6 = require("@releasekit/core");
|
|
578
653
|
|
|
579
654
|
// src/output/markdown.ts
|
|
580
655
|
var fs2 = __toESM(require("fs"), 1);
|
|
581
656
|
var path = __toESM(require("path"), 1);
|
|
582
|
-
var
|
|
657
|
+
var import_core5 = require("@releasekit/core");
|
|
583
658
|
var TYPE_ORDER = ["added", "changed", "deprecated", "removed", "fixed", "security"];
|
|
584
659
|
var TYPE_LABELS = {
|
|
585
660
|
added: "Added",
|
|
@@ -678,9 +753,9 @@ ${body}`;
|
|
|
678
753
|
function writeMarkdown(outputPath, contexts, config, dryRun) {
|
|
679
754
|
const content = renderMarkdown(contexts);
|
|
680
755
|
if (dryRun) {
|
|
681
|
-
(0,
|
|
756
|
+
(0, import_core5.info)("--- Changelog Preview ---");
|
|
682
757
|
console.log(content);
|
|
683
|
-
(0,
|
|
758
|
+
(0, import_core5.info)("--- End Preview ---");
|
|
684
759
|
return;
|
|
685
760
|
}
|
|
686
761
|
const dir = path.dirname(outputPath);
|
|
@@ -696,7 +771,7 @@ function writeMarkdown(outputPath, contexts, config, dryRun) {
|
|
|
696
771
|
} else {
|
|
697
772
|
fs2.writeFileSync(outputPath, content, "utf-8");
|
|
698
773
|
}
|
|
699
|
-
(0,
|
|
774
|
+
(0, import_core5.success)(`Changelog written to ${outputPath}`);
|
|
700
775
|
}
|
|
701
776
|
|
|
702
777
|
// src/output/github-release.ts
|
|
@@ -721,7 +796,7 @@ var GitHubClient = class {
|
|
|
721
796
|
} else {
|
|
722
797
|
body = renderMarkdown([context]);
|
|
723
798
|
}
|
|
724
|
-
(0,
|
|
799
|
+
(0, import_core6.info)(`Creating GitHub release for ${tagName}`);
|
|
725
800
|
try {
|
|
726
801
|
const response = await this.octokit.repos.createRelease({
|
|
727
802
|
owner: this.owner,
|
|
@@ -733,7 +808,7 @@ var GitHubClient = class {
|
|
|
733
808
|
prerelease: options.prerelease ?? false,
|
|
734
809
|
generate_release_notes: options.generateNotes ?? false
|
|
735
810
|
});
|
|
736
|
-
(0,
|
|
811
|
+
(0, import_core6.success)(`Release created: ${response.data.html_url}`);
|
|
737
812
|
return {
|
|
738
813
|
id: response.data.id,
|
|
739
814
|
htmlUrl: response.data.html_url,
|
|
@@ -751,7 +826,7 @@ var GitHubClient = class {
|
|
|
751
826
|
} else {
|
|
752
827
|
body = renderMarkdown([context]);
|
|
753
828
|
}
|
|
754
|
-
(0,
|
|
829
|
+
(0, import_core6.info)(`Updating GitHub release ${releaseId}`);
|
|
755
830
|
try {
|
|
756
831
|
const response = await this.octokit.repos.updateRelease({
|
|
757
832
|
owner: this.owner,
|
|
@@ -763,7 +838,7 @@ var GitHubClient = class {
|
|
|
763
838
|
draft: options.draft ?? false,
|
|
764
839
|
prerelease: options.prerelease ?? false
|
|
765
840
|
});
|
|
766
|
-
(0,
|
|
841
|
+
(0, import_core6.success)(`Release updated: ${response.data.html_url}`);
|
|
767
842
|
return {
|
|
768
843
|
id: response.data.id,
|
|
769
844
|
htmlUrl: response.data.html_url,
|
|
@@ -815,7 +890,7 @@ async function createGitHubRelease(context, options) {
|
|
|
815
890
|
// src/output/json.ts
|
|
816
891
|
var fs3 = __toESM(require("fs"), 1);
|
|
817
892
|
var path2 = __toESM(require("path"), 1);
|
|
818
|
-
var
|
|
893
|
+
var import_core7 = require("@releasekit/core");
|
|
819
894
|
function renderJson(contexts) {
|
|
820
895
|
return JSON.stringify(
|
|
821
896
|
{
|
|
@@ -835,9 +910,9 @@ function renderJson(contexts) {
|
|
|
835
910
|
function writeJson(outputPath, contexts, dryRun) {
|
|
836
911
|
const content = renderJson(contexts);
|
|
837
912
|
if (dryRun) {
|
|
838
|
-
(0,
|
|
913
|
+
(0, import_core7.info)("--- JSON Output Preview ---");
|
|
839
914
|
console.log(content);
|
|
840
|
-
(0,
|
|
915
|
+
(0, import_core7.info)("--- End Preview ---");
|
|
841
916
|
return;
|
|
842
917
|
}
|
|
843
918
|
const dir = path2.dirname(outputPath);
|
|
@@ -845,7 +920,7 @@ function writeJson(outputPath, contexts, dryRun) {
|
|
|
845
920
|
fs3.mkdirSync(dir, { recursive: true });
|
|
846
921
|
}
|
|
847
922
|
fs3.writeFileSync(outputPath, content, "utf-8");
|
|
848
|
-
(0,
|
|
923
|
+
(0, import_core7.success)(`JSON output written to ${outputPath}`);
|
|
849
924
|
}
|
|
850
925
|
|
|
851
926
|
// src/templates/ejs.ts
|
|
@@ -1183,9 +1258,9 @@ async function processWithLLM(context, config) {
|
|
|
1183
1258
|
entries: context.entries
|
|
1184
1259
|
};
|
|
1185
1260
|
try {
|
|
1186
|
-
(0,
|
|
1261
|
+
(0, import_core8.info)(`Using LLM provider: ${config.llm.provider}${config.llm.model ? ` (${config.llm.model})` : ""}`);
|
|
1187
1262
|
if (config.llm.baseURL) {
|
|
1188
|
-
(0,
|
|
1263
|
+
(0, import_core8.info)(`LLM base URL: ${config.llm.baseURL}`);
|
|
1189
1264
|
}
|
|
1190
1265
|
const rawProvider = createProvider(config.llm);
|
|
1191
1266
|
const retryOpts = config.llm.retry ?? LLM_DEFAULTS.retry;
|
|
@@ -1194,38 +1269,49 @@ async function processWithLLM(context, config) {
|
|
|
1194
1269
|
complete: (prompt, opts) => withRetry(() => rawProvider.complete(prompt, opts), retryOpts)
|
|
1195
1270
|
};
|
|
1196
1271
|
const activeTasks = Object.entries(tasks).filter(([, enabled]) => enabled).map(([name]) => name);
|
|
1197
|
-
(0,
|
|
1198
|
-
if (tasks.enhance) {
|
|
1199
|
-
(0,
|
|
1200
|
-
|
|
1201
|
-
|
|
1272
|
+
(0, import_core8.info)(`Running LLM tasks: ${activeTasks.join(", ")}`);
|
|
1273
|
+
if (tasks.enhance && tasks.categorize) {
|
|
1274
|
+
(0, import_core8.info)("Enhancing and categorizing entries with LLM (single call)...");
|
|
1275
|
+
const result = await enhanceAndCategorize(provider, context.entries, llmContext);
|
|
1276
|
+
enhanced.entries = result.enhancedEntries;
|
|
1277
|
+
enhanced.categories = {};
|
|
1278
|
+
for (const cat of result.categories) {
|
|
1279
|
+
enhanced.categories[cat.category] = cat.entries;
|
|
1280
|
+
}
|
|
1281
|
+
(0, import_core8.info)(`Enhanced ${enhanced.entries.length} entries into ${result.categories.length} categories`);
|
|
1282
|
+
} else {
|
|
1283
|
+
if (tasks.enhance) {
|
|
1284
|
+
(0, import_core8.info)("Enhancing entries with LLM...");
|
|
1285
|
+
enhanced.entries = await enhanceEntries(provider, context.entries, llmContext, config.llm.concurrency);
|
|
1286
|
+
(0, import_core8.info)(`Enhanced ${enhanced.entries.length} entries`);
|
|
1287
|
+
}
|
|
1288
|
+
if (tasks.categorize) {
|
|
1289
|
+
(0, import_core8.info)("Categorizing entries with LLM...");
|
|
1290
|
+
const categorized = await categorizeEntries(provider, enhanced.entries, llmContext);
|
|
1291
|
+
enhanced.categories = {};
|
|
1292
|
+
for (const cat of categorized) {
|
|
1293
|
+
enhanced.categories[cat.category] = cat.entries;
|
|
1294
|
+
}
|
|
1295
|
+
(0, import_core8.info)(`Created ${categorized.length} categories`);
|
|
1296
|
+
}
|
|
1202
1297
|
}
|
|
1203
1298
|
if (tasks.summarize) {
|
|
1204
|
-
(0,
|
|
1299
|
+
(0, import_core8.info)("Summarizing entries with LLM...");
|
|
1205
1300
|
enhanced.summary = await summarizeEntries(provider, enhanced.entries, llmContext);
|
|
1206
1301
|
if (enhanced.summary) {
|
|
1207
|
-
(0,
|
|
1208
|
-
(0,
|
|
1302
|
+
(0, import_core8.info)("Summary generated successfully");
|
|
1303
|
+
(0, import_core8.debug)(`Summary: ${enhanced.summary.substring(0, 100)}...`);
|
|
1209
1304
|
} else {
|
|
1210
|
-
(0,
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
if (tasks.categorize) {
|
|
1214
|
-
(0, import_core7.info)("Categorizing entries with LLM...");
|
|
1215
|
-
const categorized = await categorizeEntries(provider, enhanced.entries, llmContext);
|
|
1216
|
-
enhanced.categories = {};
|
|
1217
|
-
for (const cat of categorized) {
|
|
1218
|
-
enhanced.categories[cat.category] = cat.entries;
|
|
1305
|
+
(0, import_core8.warn)("Summary generation returned empty result");
|
|
1219
1306
|
}
|
|
1220
|
-
(0, import_core7.info)(`Created ${categorized.length} categories`);
|
|
1221
1307
|
}
|
|
1222
1308
|
if (tasks.releaseNotes) {
|
|
1223
|
-
(0,
|
|
1309
|
+
(0, import_core8.info)("Generating release notes with LLM...");
|
|
1224
1310
|
enhanced.releaseNotes = await generateReleaseNotes(provider, enhanced.entries, llmContext);
|
|
1225
1311
|
if (enhanced.releaseNotes) {
|
|
1226
|
-
(0,
|
|
1312
|
+
(0, import_core8.info)("Release notes generated successfully");
|
|
1227
1313
|
} else {
|
|
1228
|
-
(0,
|
|
1314
|
+
(0, import_core8.warn)("Release notes generation returned empty result");
|
|
1229
1315
|
}
|
|
1230
1316
|
}
|
|
1231
1317
|
return {
|
|
@@ -1234,8 +1320,8 @@ async function processWithLLM(context, config) {
|
|
|
1234
1320
|
enhanced
|
|
1235
1321
|
};
|
|
1236
1322
|
} catch (error2) {
|
|
1237
|
-
(0,
|
|
1238
|
-
(0,
|
|
1323
|
+
(0, import_core8.warn)(`LLM processing failed: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
1324
|
+
(0, import_core8.warn)("Falling back to raw entries");
|
|
1239
1325
|
return context;
|
|
1240
1326
|
}
|
|
1241
1327
|
}
|
|
@@ -1263,9 +1349,9 @@ async function generateWithTemplate(contexts, config, outputPath, dryRun) {
|
|
|
1263
1349
|
);
|
|
1264
1350
|
const result = renderTemplate(templatePath, documentContext, config.templates?.engine);
|
|
1265
1351
|
if (dryRun) {
|
|
1266
|
-
(0,
|
|
1352
|
+
(0, import_core8.info)("--- Changelog Preview ---");
|
|
1267
1353
|
console.log(result.content);
|
|
1268
|
-
(0,
|
|
1354
|
+
(0, import_core8.info)("--- End Preview ---");
|
|
1269
1355
|
return;
|
|
1270
1356
|
}
|
|
1271
1357
|
const dir = path6.dirname(outputPath);
|
|
@@ -1273,17 +1359,17 @@ async function generateWithTemplate(contexts, config, outputPath, dryRun) {
|
|
|
1273
1359
|
fs8.mkdirSync(dir, { recursive: true });
|
|
1274
1360
|
}
|
|
1275
1361
|
fs8.writeFileSync(outputPath, result.content, "utf-8");
|
|
1276
|
-
(0,
|
|
1362
|
+
(0, import_core8.success)(`Changelog written to ${outputPath} (using ${result.engine} template)`);
|
|
1277
1363
|
}
|
|
1278
1364
|
async function runPipeline(input, config, dryRun) {
|
|
1279
|
-
(0,
|
|
1365
|
+
(0, import_core8.debug)(`Processing ${input.packages.length} package(s)`);
|
|
1280
1366
|
let contexts = input.packages.map(createTemplateContext);
|
|
1281
1367
|
if (config.llm && !process.env.CHANGELOG_NO_LLM) {
|
|
1282
|
-
(0,
|
|
1368
|
+
(0, import_core8.info)("Processing with LLM enhancement");
|
|
1283
1369
|
contexts = await Promise.all(contexts.map((ctx) => processWithLLM(ctx, config)));
|
|
1284
1370
|
}
|
|
1285
1371
|
for (const output of config.output) {
|
|
1286
|
-
(0,
|
|
1372
|
+
(0, import_core8.info)(`Generating ${output.format} output`);
|
|
1287
1373
|
switch (output.format) {
|
|
1288
1374
|
case "markdown": {
|
|
1289
1375
|
const file = output.file ?? "CHANGELOG.md";
|
|
@@ -1301,22 +1387,22 @@ async function runPipeline(input, config, dryRun) {
|
|
|
1301
1387
|
}
|
|
1302
1388
|
case "github-release": {
|
|
1303
1389
|
if (dryRun) {
|
|
1304
|
-
(0,
|
|
1390
|
+
(0, import_core8.info)("[DRY RUN] Would create GitHub release");
|
|
1305
1391
|
break;
|
|
1306
1392
|
}
|
|
1307
1393
|
const firstContext = contexts[0];
|
|
1308
1394
|
if (!firstContext) {
|
|
1309
|
-
(0,
|
|
1395
|
+
(0, import_core8.warn)("No context available for GitHub release");
|
|
1310
1396
|
break;
|
|
1311
1397
|
}
|
|
1312
1398
|
const repoUrl = firstContext.repoUrl;
|
|
1313
1399
|
if (!repoUrl) {
|
|
1314
|
-
(0,
|
|
1400
|
+
(0, import_core8.warn)("No repo URL available, cannot create GitHub release");
|
|
1315
1401
|
break;
|
|
1316
1402
|
}
|
|
1317
1403
|
const parsed = parseRepoUrl(repoUrl);
|
|
1318
1404
|
if (!parsed) {
|
|
1319
|
-
(0,
|
|
1405
|
+
(0, import_core8.warn)(`Could not parse repo URL: ${repoUrl}`);
|
|
1320
1406
|
break;
|
|
1321
1407
|
}
|
|
1322
1408
|
await createGitHubRelease(firstContext, {
|
|
@@ -1334,7 +1420,7 @@ async function runPipeline(input, config, dryRun) {
|
|
|
1334
1420
|
// src/monorepo/aggregator.ts
|
|
1335
1421
|
var fs9 = __toESM(require("fs"), 1);
|
|
1336
1422
|
var path7 = __toESM(require("path"), 1);
|
|
1337
|
-
var
|
|
1423
|
+
var import_core9 = require("@releasekit/core");
|
|
1338
1424
|
|
|
1339
1425
|
// src/monorepo/splitter.ts
|
|
1340
1426
|
function splitByPackage(contexts) {
|
|
@@ -1348,7 +1434,7 @@ function splitByPackage(contexts) {
|
|
|
1348
1434
|
// src/monorepo/aggregator.ts
|
|
1349
1435
|
function writeFile(outputPath, content, dryRun) {
|
|
1350
1436
|
if (dryRun) {
|
|
1351
|
-
(0,
|
|
1437
|
+
(0, import_core9.info)(`[DRY RUN] Would write to ${outputPath}`);
|
|
1352
1438
|
console.log(content);
|
|
1353
1439
|
return;
|
|
1354
1440
|
}
|
|
@@ -1357,7 +1443,7 @@ function writeFile(outputPath, content, dryRun) {
|
|
|
1357
1443
|
fs9.mkdirSync(dir, { recursive: true });
|
|
1358
1444
|
}
|
|
1359
1445
|
fs9.writeFileSync(outputPath, content, "utf-8");
|
|
1360
|
-
(0,
|
|
1446
|
+
(0, import_core9.success)(`Changelog written to ${outputPath}`);
|
|
1361
1447
|
}
|
|
1362
1448
|
function aggregateToRoot(contexts) {
|
|
1363
1449
|
const aggregated = {
|
|
@@ -1382,7 +1468,7 @@ function writeMonorepoChangelogs(contexts, options, config, dryRun) {
|
|
|
1382
1468
|
if (options.mode === "root" || options.mode === "both") {
|
|
1383
1469
|
const aggregated = aggregateToRoot(contexts);
|
|
1384
1470
|
const rootPath = path7.join(options.rootPath, "CHANGELOG.md");
|
|
1385
|
-
(0,
|
|
1471
|
+
(0, import_core9.info)(`Writing root changelog to ${rootPath}`);
|
|
1386
1472
|
const rootContent = config.updateStrategy === "prepend" && fs9.existsSync(rootPath) ? prependVersion(rootPath, aggregated) : renderMarkdown([aggregated]);
|
|
1387
1473
|
writeFile(rootPath, rootContent, dryRun);
|
|
1388
1474
|
}
|
|
@@ -1394,11 +1480,11 @@ function writeMonorepoChangelogs(contexts, options, config, dryRun) {
|
|
|
1394
1480
|
const packageDir = packageDirMap.get(packageName) ?? (simpleName ? packageDirMap.get(simpleName) : void 0) ?? null;
|
|
1395
1481
|
if (packageDir) {
|
|
1396
1482
|
const changelogPath = path7.join(packageDir, "CHANGELOG.md");
|
|
1397
|
-
(0,
|
|
1483
|
+
(0, import_core9.info)(`Writing changelog for ${packageName} to ${changelogPath}`);
|
|
1398
1484
|
const pkgContent = config.updateStrategy === "prepend" && fs9.existsSync(changelogPath) ? prependVersion(changelogPath, ctx) : renderMarkdown([ctx]);
|
|
1399
1485
|
writeFile(changelogPath, pkgContent, dryRun);
|
|
1400
1486
|
} else {
|
|
1401
|
-
(0,
|
|
1487
|
+
(0, import_core9.info)(`Could not find directory for package ${packageName}, skipping`);
|
|
1402
1488
|
}
|
|
1403
1489
|
}
|
|
1404
1490
|
}
|
|
@@ -1463,9 +1549,9 @@ function detectMonorepo(cwd) {
|
|
|
1463
1549
|
// src/cli.ts
|
|
1464
1550
|
var program = new import_commander.Command();
|
|
1465
1551
|
program.name("releasekit-notes").description("Generate changelogs with LLM-powered enhancement and flexible templating").version("0.1.0");
|
|
1466
|
-
program.command("generate", { isDefault: true }).description("Generate changelog from input data").option("-i, --input <file>", "Input file (default: stdin)").option("-o, --output <spec>", "Output spec (format:file)", collectOutputs, []).option("-t, --template <path>", "Template file or directory").option("-e, --engine <engine>", "Template engine (handlebars|liquid|ejs)").option("--monorepo <mode>", "Monorepo mode (root|packages|both)").option("--llm-provider <provider>", "LLM provider").option("--llm-model <model>", "LLM model").option("--llm-base-url <url>", "LLM base URL (for openai-compatible provider)").option("--llm-tasks <tasks>", "Comma-separated LLM tasks").option("--no-llm", "Disable LLM processing").option("--config <path>", "Config file path").option("--dry-run", "Preview without writing").option("--regenerate", "Regenerate entire changelog").option("-v, --verbose", "Increase verbosity", increaseVerbosity, 0).option("-q, --quiet", "Suppress non-error output").action(async (options) => {
|
|
1552
|
+
program.command("generate", { isDefault: true }).description("Generate changelog from input data").option("-i, --input <file>", "Input file (default: stdin)").option("-o, --output <spec>", "Output spec (format:file)", collectOutputs, []).option("-t, --template <path>", "Template file or directory").option("-e, --engine <engine>", "Template engine (handlebars|liquid|ejs)").option("--monorepo <mode>", "Monorepo mode (root|packages|both)").option("--llm-provider <provider>", "LLM provider").option("--llm-model <model>", "LLM model").option("--llm-base-url <url>", "LLM base URL (for openai-compatible provider)").option("--llm-tasks <tasks>", "Comma-separated LLM tasks").option("--no-llm", "Disable LLM processing").option("--target <package>", "Filter to a specific package name").option("--config <path>", "Config file path").option("--dry-run", "Preview without writing").option("--regenerate", "Regenerate entire changelog").option("-v, --verbose", "Increase verbosity", increaseVerbosity, 0).option("-q, --quiet", "Suppress non-error output").action(async (options) => {
|
|
1467
1553
|
setVerbosity(options.verbose);
|
|
1468
|
-
if (options.quiet) (0,
|
|
1554
|
+
if (options.quiet) (0, import_core10.setQuietMode)(true);
|
|
1469
1555
|
try {
|
|
1470
1556
|
const config = loadConfig(process.cwd(), options.config);
|
|
1471
1557
|
if (options.output.length > 0) {
|
|
@@ -1484,7 +1570,7 @@ program.command("generate", { isDefault: true }).description("Generate changelog
|
|
|
1484
1570
|
config.templates = { ...config.templates, engine: options.engine };
|
|
1485
1571
|
}
|
|
1486
1572
|
if (options.llm === false) {
|
|
1487
|
-
(0,
|
|
1573
|
+
(0, import_core10.info)("LLM processing disabled via --no-llm flag");
|
|
1488
1574
|
delete config.llm;
|
|
1489
1575
|
} else if (options.llmProvider || options.llmModel || options.llmBaseUrl || options.llmTasks) {
|
|
1490
1576
|
config.llm = config.llm ?? { provider: "openai-compatible", model: "" };
|
|
@@ -1500,13 +1586,13 @@ program.command("generate", { isDefault: true }).description("Generate changelog
|
|
|
1500
1586
|
releaseNotes: taskNames.includes("release-notes") || taskNames.includes("releaseNotes")
|
|
1501
1587
|
};
|
|
1502
1588
|
}
|
|
1503
|
-
(0,
|
|
1589
|
+
(0, import_core10.info)(`LLM configured: ${config.llm.provider}${config.llm.model ? ` (${config.llm.model})` : ""}`);
|
|
1504
1590
|
if (config.llm.baseURL) {
|
|
1505
|
-
(0,
|
|
1591
|
+
(0, import_core10.info)(`LLM base URL: ${config.llm.baseURL}`);
|
|
1506
1592
|
}
|
|
1507
1593
|
const taskList = Object.entries(config.llm.tasks || {}).filter(([, enabled]) => enabled).map(([name]) => name).join(", ");
|
|
1508
1594
|
if (taskList) {
|
|
1509
|
-
(0,
|
|
1595
|
+
(0, import_core10.info)(`LLM tasks: ${taskList}`);
|
|
1510
1596
|
}
|
|
1511
1597
|
}
|
|
1512
1598
|
let inputJson;
|
|
@@ -1516,14 +1602,23 @@ program.command("generate", { isDefault: true }).description("Generate changelog
|
|
|
1516
1602
|
inputJson = await readStdin();
|
|
1517
1603
|
}
|
|
1518
1604
|
const input = parsePackageVersioner(inputJson);
|
|
1605
|
+
if (options.target) {
|
|
1606
|
+
const before = input.packages.length;
|
|
1607
|
+
input.packages = input.packages.filter((p) => p.packageName === options.target);
|
|
1608
|
+
if (input.packages.length === 0) {
|
|
1609
|
+
(0, import_core10.info)(`No changelog found for package "${options.target}" (had ${before} package(s))`);
|
|
1610
|
+
return;
|
|
1611
|
+
}
|
|
1612
|
+
(0, import_core10.info)(`Filtered to package: ${options.target}`);
|
|
1613
|
+
}
|
|
1519
1614
|
if (options.monorepo || config.monorepo) {
|
|
1520
1615
|
const monorepoMode = options.monorepo ?? config.monorepo?.mode ?? "both";
|
|
1521
1616
|
const detected = detectMonorepo(process.cwd());
|
|
1522
1617
|
if (!detected.isMonorepo) {
|
|
1523
|
-
(0,
|
|
1618
|
+
(0, import_core10.info)("No monorepo detected, using single package mode");
|
|
1524
1619
|
await runPipeline(input, config, options.dryRun ?? false);
|
|
1525
1620
|
} else {
|
|
1526
|
-
(0,
|
|
1621
|
+
(0, import_core10.info)(`Monorepo detected with packages at ${detected.packagesPath}`);
|
|
1527
1622
|
const contexts = input.packages.map(createTemplateContext);
|
|
1528
1623
|
writeMonorepoChangelogs(
|
|
1529
1624
|
contexts,
|
|
@@ -1540,9 +1635,9 @@ program.command("generate", { isDefault: true }).description("Generate changelog
|
|
|
1540
1635
|
await runPipeline(input, config, options.dryRun ?? false);
|
|
1541
1636
|
}
|
|
1542
1637
|
if (options.dryRun) {
|
|
1543
|
-
(0,
|
|
1638
|
+
(0, import_core10.info)("Dry run complete - no files were written");
|
|
1544
1639
|
} else {
|
|
1545
|
-
(0,
|
|
1640
|
+
(0, import_core10.success)("Changelog generation complete");
|
|
1546
1641
|
}
|
|
1547
1642
|
} catch (err) {
|
|
1548
1643
|
handleError(err);
|
|
@@ -1551,7 +1646,7 @@ program.command("generate", { isDefault: true }).description("Generate changelog
|
|
|
1551
1646
|
program.command("init").description("Create default configuration file").option("-f, --force", "Overwrite existing config").action((options) => {
|
|
1552
1647
|
const configPath = "releasekit.config.json";
|
|
1553
1648
|
if (fs10.existsSync(configPath) && !options.force) {
|
|
1554
|
-
(0,
|
|
1649
|
+
(0, import_core10.error)(`Config file already exists at ${configPath}. Use --force to overwrite.`);
|
|
1555
1650
|
process.exit(import_core2.EXIT_CODES.GENERAL_ERROR);
|
|
1556
1651
|
}
|
|
1557
1652
|
const defaultConfig = {
|
|
@@ -1562,7 +1657,7 @@ program.command("init").description("Create default configuration file").option(
|
|
|
1562
1657
|
}
|
|
1563
1658
|
};
|
|
1564
1659
|
fs10.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2), "utf-8");
|
|
1565
|
-
(0,
|
|
1660
|
+
(0, import_core10.success)(`Created config file at ${configPath}`);
|
|
1566
1661
|
});
|
|
1567
1662
|
program.command("auth <provider>").description("Configure API key for an LLM provider").option("--key <key>", "API key (omit to be prompted)").action(async (provider, options) => {
|
|
1568
1663
|
let apiKey;
|
|
@@ -1572,14 +1667,14 @@ program.command("auth <provider>").description("Configure API key for an LLM pro
|
|
|
1572
1667
|
apiKey = await promptSecret(`Enter API key for ${provider}: `);
|
|
1573
1668
|
}
|
|
1574
1669
|
if (!apiKey.trim()) {
|
|
1575
|
-
(0,
|
|
1670
|
+
(0, import_core10.error)("API key cannot be empty");
|
|
1576
1671
|
process.exit(import_core2.EXIT_CODES.GENERAL_ERROR);
|
|
1577
1672
|
}
|
|
1578
1673
|
(0, import_config.saveAuth)(provider, apiKey.trim());
|
|
1579
|
-
(0,
|
|
1674
|
+
(0, import_core10.success)(`API key saved for ${provider}`);
|
|
1580
1675
|
});
|
|
1581
1676
|
program.command("providers").description("List available LLM providers").action(() => {
|
|
1582
|
-
(0,
|
|
1677
|
+
(0, import_core10.info)("Available LLM providers:");
|
|
1583
1678
|
console.log(" openai - OpenAI (GPT models)");
|
|
1584
1679
|
console.log(" anthropic - Anthropic (Claude models)");
|
|
1585
1680
|
console.log(" ollama - Ollama (local models)");
|
|
@@ -1600,7 +1695,7 @@ function increaseVerbosity(_, previous) {
|
|
|
1600
1695
|
}
|
|
1601
1696
|
function setVerbosity(level) {
|
|
1602
1697
|
const levels = ["info", "debug", "trace"];
|
|
1603
|
-
(0,
|
|
1698
|
+
(0, import_core10.setLogLevel)(levels[Math.min(level, levels.length - 1)] ?? "info");
|
|
1604
1699
|
}
|
|
1605
1700
|
async function readStdin() {
|
|
1606
1701
|
const chunks = [];
|
|
@@ -1623,7 +1718,7 @@ function handleError(err) {
|
|
|
1623
1718
|
err.logError();
|
|
1624
1719
|
process.exit(getExitCode(err));
|
|
1625
1720
|
}
|
|
1626
|
-
(0,
|
|
1721
|
+
(0, import_core10.error)(err instanceof Error ? err.message : String(err));
|
|
1627
1722
|
process.exit(import_core2.EXIT_CODES.GENERAL_ERROR);
|
|
1628
1723
|
}
|
|
1629
1724
|
program.parse();
|
package/dist/cli.js
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
runPipeline,
|
|
12
12
|
saveAuth,
|
|
13
13
|
writeMonorepoChangelogs
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-H44KSHFJ.js";
|
|
15
15
|
|
|
16
16
|
// src/cli.ts
|
|
17
17
|
import * as fs from "fs";
|
|
@@ -20,7 +20,7 @@ import { error, info, setLogLevel, setQuietMode, success } from "@releasekit/cor
|
|
|
20
20
|
import { Command } from "commander";
|
|
21
21
|
var program = new Command();
|
|
22
22
|
program.name("releasekit-notes").description("Generate changelogs with LLM-powered enhancement and flexible templating").version("0.1.0");
|
|
23
|
-
program.command("generate", { isDefault: true }).description("Generate changelog from input data").option("-i, --input <file>", "Input file (default: stdin)").option("-o, --output <spec>", "Output spec (format:file)", collectOutputs, []).option("-t, --template <path>", "Template file or directory").option("-e, --engine <engine>", "Template engine (handlebars|liquid|ejs)").option("--monorepo <mode>", "Monorepo mode (root|packages|both)").option("--llm-provider <provider>", "LLM provider").option("--llm-model <model>", "LLM model").option("--llm-base-url <url>", "LLM base URL (for openai-compatible provider)").option("--llm-tasks <tasks>", "Comma-separated LLM tasks").option("--no-llm", "Disable LLM processing").option("--config <path>", "Config file path").option("--dry-run", "Preview without writing").option("--regenerate", "Regenerate entire changelog").option("-v, --verbose", "Increase verbosity", increaseVerbosity, 0).option("-q, --quiet", "Suppress non-error output").action(async (options) => {
|
|
23
|
+
program.command("generate", { isDefault: true }).description("Generate changelog from input data").option("-i, --input <file>", "Input file (default: stdin)").option("-o, --output <spec>", "Output spec (format:file)", collectOutputs, []).option("-t, --template <path>", "Template file or directory").option("-e, --engine <engine>", "Template engine (handlebars|liquid|ejs)").option("--monorepo <mode>", "Monorepo mode (root|packages|both)").option("--llm-provider <provider>", "LLM provider").option("--llm-model <model>", "LLM model").option("--llm-base-url <url>", "LLM base URL (for openai-compatible provider)").option("--llm-tasks <tasks>", "Comma-separated LLM tasks").option("--no-llm", "Disable LLM processing").option("--target <package>", "Filter to a specific package name").option("--config <path>", "Config file path").option("--dry-run", "Preview without writing").option("--regenerate", "Regenerate entire changelog").option("-v, --verbose", "Increase verbosity", increaseVerbosity, 0).option("-q, --quiet", "Suppress non-error output").action(async (options) => {
|
|
24
24
|
setVerbosity(options.verbose);
|
|
25
25
|
if (options.quiet) setQuietMode(true);
|
|
26
26
|
try {
|
|
@@ -73,6 +73,15 @@ program.command("generate", { isDefault: true }).description("Generate changelog
|
|
|
73
73
|
inputJson = await readStdin();
|
|
74
74
|
}
|
|
75
75
|
const input = parsePackageVersioner(inputJson);
|
|
76
|
+
if (options.target) {
|
|
77
|
+
const before = input.packages.length;
|
|
78
|
+
input.packages = input.packages.filter((p) => p.packageName === options.target);
|
|
79
|
+
if (input.packages.length === 0) {
|
|
80
|
+
info(`No changelog found for package "${options.target}" (had ${before} package(s))`);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
info(`Filtered to package: ${options.target}`);
|
|
84
|
+
}
|
|
76
85
|
if (options.monorepo || config.monorepo) {
|
|
77
86
|
const monorepoMode = options.monorepo ?? config.monorepo?.mode ?? "both";
|
|
78
87
|
const detected = detectMonorepo(process.cwd());
|
package/dist/index.cjs
CHANGED
|
@@ -75,7 +75,7 @@ function getDefaultConfig() {
|
|
|
75
75
|
// src/core/pipeline.ts
|
|
76
76
|
var fs8 = __toESM(require("fs"), 1);
|
|
77
77
|
var path6 = __toESM(require("path"), 1);
|
|
78
|
-
var
|
|
78
|
+
var import_core8 = require("@releasekit/core");
|
|
79
79
|
|
|
80
80
|
// src/input/package-versioner.ts
|
|
81
81
|
var fs = __toESM(require("fs"), 1);
|
|
@@ -524,6 +524,81 @@ async function enhanceEntries(provider, entries, context, concurrency = LLM_DEFA
|
|
|
524
524
|
return results;
|
|
525
525
|
}
|
|
526
526
|
|
|
527
|
+
// src/llm/tasks/enhance-and-categorize.ts
|
|
528
|
+
var import_core4 = require("@releasekit/core");
|
|
529
|
+
function buildPrompt(entries, categories, style) {
|
|
530
|
+
const entriesText = entries.map((e, i) => `${i}. [${e.type}]${e.scope ? ` (${e.scope})` : ""}: ${e.description}`).join("\n");
|
|
531
|
+
const styleText = style || 'Use present tense ("Add feature" not "Added feature"). Be concise.';
|
|
532
|
+
const categorySection = categories ? `Categories (use ONLY these):
|
|
533
|
+
${categories.map((c) => `- "${c.name}": ${c.description}`).join("\n")}` : `Categories: Group into meaningful categories (e.g., "New", "Fixed", "Changed", "Removed").`;
|
|
534
|
+
return `You are generating release notes for a software project. Given the following changelog entries, do two things:
|
|
535
|
+
|
|
536
|
+
1. **Rewrite** each entry as a clear, user-friendly description
|
|
537
|
+
2. **Categorize** each entry into the appropriate category
|
|
538
|
+
|
|
539
|
+
Style guidelines:
|
|
540
|
+
- ${styleText}
|
|
541
|
+
- Be concise (1 short sentence per entry)
|
|
542
|
+
- Focus on what changed, not implementation details
|
|
543
|
+
|
|
544
|
+
${categorySection}
|
|
545
|
+
|
|
546
|
+
${categories ? 'For entries in categories involving internal/developer changes, set a "scope" field with a short subcategory label (e.g., "CI", "Dependencies", "Testing").' : ""}
|
|
547
|
+
|
|
548
|
+
Entries:
|
|
549
|
+
${entriesText}
|
|
550
|
+
|
|
551
|
+
Output a JSON object with:
|
|
552
|
+
- "entries": array of objects, one per input entry (same order), each with: { "description": "rewritten text", "category": "CategoryName", "scope": "optional subcategory label or null" }
|
|
553
|
+
|
|
554
|
+
Output only valid JSON, nothing else:`;
|
|
555
|
+
}
|
|
556
|
+
async function enhanceAndCategorize(provider, entries, context) {
|
|
557
|
+
if (entries.length === 0) {
|
|
558
|
+
return { enhancedEntries: [], categories: [] };
|
|
559
|
+
}
|
|
560
|
+
const prompt = buildPrompt(entries, context.categories, context.style);
|
|
561
|
+
try {
|
|
562
|
+
const response = await provider.complete(prompt);
|
|
563
|
+
const cleaned = response.replace(/^```(?:json)?\n?/, "").replace(/\n?```$/, "").trim();
|
|
564
|
+
const parsed = JSON.parse(cleaned);
|
|
565
|
+
if (!Array.isArray(parsed.entries)) {
|
|
566
|
+
throw new Error('Response missing "entries" array');
|
|
567
|
+
}
|
|
568
|
+
const enhancedEntries = entries.map((original, i) => {
|
|
569
|
+
const result = parsed.entries[i];
|
|
570
|
+
if (!result) return original;
|
|
571
|
+
return {
|
|
572
|
+
...original,
|
|
573
|
+
description: result.description || original.description,
|
|
574
|
+
scope: result.scope || original.scope
|
|
575
|
+
};
|
|
576
|
+
});
|
|
577
|
+
const categoryMap = /* @__PURE__ */ new Map();
|
|
578
|
+
for (let i = 0; i < parsed.entries.length; i++) {
|
|
579
|
+
const result = parsed.entries[i];
|
|
580
|
+
const category = result?.category || "General";
|
|
581
|
+
const entry = enhancedEntries[i];
|
|
582
|
+
if (!entry) continue;
|
|
583
|
+
if (!categoryMap.has(category)) {
|
|
584
|
+
categoryMap.set(category, []);
|
|
585
|
+
}
|
|
586
|
+
categoryMap.get(category).push(entry);
|
|
587
|
+
}
|
|
588
|
+
const categories = [];
|
|
589
|
+
for (const [category, catEntries] of categoryMap) {
|
|
590
|
+
categories.push({ category, entries: catEntries });
|
|
591
|
+
}
|
|
592
|
+
return { enhancedEntries, categories };
|
|
593
|
+
} catch (error) {
|
|
594
|
+
(0, import_core4.warn)(`Combined enhance+categorize failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
595
|
+
return {
|
|
596
|
+
enhancedEntries: entries,
|
|
597
|
+
categories: [{ category: "General", entries }]
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
527
602
|
// src/llm/tasks/release-notes.ts
|
|
528
603
|
var RELEASE_NOTES_PROMPT = `You are writing release notes for a software project.
|
|
529
604
|
|
|
@@ -624,12 +699,12 @@ function createProvider(config) {
|
|
|
624
699
|
|
|
625
700
|
// src/output/github-release.ts
|
|
626
701
|
var import_rest = require("@octokit/rest");
|
|
627
|
-
var
|
|
702
|
+
var import_core6 = require("@releasekit/core");
|
|
628
703
|
|
|
629
704
|
// src/output/markdown.ts
|
|
630
705
|
var fs2 = __toESM(require("fs"), 1);
|
|
631
706
|
var path = __toESM(require("path"), 1);
|
|
632
|
-
var
|
|
707
|
+
var import_core5 = require("@releasekit/core");
|
|
633
708
|
var TYPE_ORDER = ["added", "changed", "deprecated", "removed", "fixed", "security"];
|
|
634
709
|
var TYPE_LABELS = {
|
|
635
710
|
added: "Added",
|
|
@@ -728,9 +803,9 @@ ${body}`;
|
|
|
728
803
|
function writeMarkdown(outputPath, contexts, config, dryRun) {
|
|
729
804
|
const content = renderMarkdown(contexts);
|
|
730
805
|
if (dryRun) {
|
|
731
|
-
(0,
|
|
806
|
+
(0, import_core5.info)("--- Changelog Preview ---");
|
|
732
807
|
console.log(content);
|
|
733
|
-
(0,
|
|
808
|
+
(0, import_core5.info)("--- End Preview ---");
|
|
734
809
|
return;
|
|
735
810
|
}
|
|
736
811
|
const dir = path.dirname(outputPath);
|
|
@@ -746,7 +821,7 @@ function writeMarkdown(outputPath, contexts, config, dryRun) {
|
|
|
746
821
|
} else {
|
|
747
822
|
fs2.writeFileSync(outputPath, content, "utf-8");
|
|
748
823
|
}
|
|
749
|
-
(0,
|
|
824
|
+
(0, import_core5.success)(`Changelog written to ${outputPath}`);
|
|
750
825
|
}
|
|
751
826
|
|
|
752
827
|
// src/output/github-release.ts
|
|
@@ -771,7 +846,7 @@ var GitHubClient = class {
|
|
|
771
846
|
} else {
|
|
772
847
|
body = renderMarkdown([context]);
|
|
773
848
|
}
|
|
774
|
-
(0,
|
|
849
|
+
(0, import_core6.info)(`Creating GitHub release for ${tagName}`);
|
|
775
850
|
try {
|
|
776
851
|
const response = await this.octokit.repos.createRelease({
|
|
777
852
|
owner: this.owner,
|
|
@@ -783,7 +858,7 @@ var GitHubClient = class {
|
|
|
783
858
|
prerelease: options.prerelease ?? false,
|
|
784
859
|
generate_release_notes: options.generateNotes ?? false
|
|
785
860
|
});
|
|
786
|
-
(0,
|
|
861
|
+
(0, import_core6.success)(`Release created: ${response.data.html_url}`);
|
|
787
862
|
return {
|
|
788
863
|
id: response.data.id,
|
|
789
864
|
htmlUrl: response.data.html_url,
|
|
@@ -801,7 +876,7 @@ var GitHubClient = class {
|
|
|
801
876
|
} else {
|
|
802
877
|
body = renderMarkdown([context]);
|
|
803
878
|
}
|
|
804
|
-
(0,
|
|
879
|
+
(0, import_core6.info)(`Updating GitHub release ${releaseId}`);
|
|
805
880
|
try {
|
|
806
881
|
const response = await this.octokit.repos.updateRelease({
|
|
807
882
|
owner: this.owner,
|
|
@@ -813,7 +888,7 @@ var GitHubClient = class {
|
|
|
813
888
|
draft: options.draft ?? false,
|
|
814
889
|
prerelease: options.prerelease ?? false
|
|
815
890
|
});
|
|
816
|
-
(0,
|
|
891
|
+
(0, import_core6.success)(`Release updated: ${response.data.html_url}`);
|
|
817
892
|
return {
|
|
818
893
|
id: response.data.id,
|
|
819
894
|
htmlUrl: response.data.html_url,
|
|
@@ -865,7 +940,7 @@ async function createGitHubRelease(context, options) {
|
|
|
865
940
|
// src/output/json.ts
|
|
866
941
|
var fs3 = __toESM(require("fs"), 1);
|
|
867
942
|
var path2 = __toESM(require("path"), 1);
|
|
868
|
-
var
|
|
943
|
+
var import_core7 = require("@releasekit/core");
|
|
869
944
|
function renderJson(contexts) {
|
|
870
945
|
return JSON.stringify(
|
|
871
946
|
{
|
|
@@ -885,9 +960,9 @@ function renderJson(contexts) {
|
|
|
885
960
|
function writeJson(outputPath, contexts, dryRun) {
|
|
886
961
|
const content = renderJson(contexts);
|
|
887
962
|
if (dryRun) {
|
|
888
|
-
(0,
|
|
963
|
+
(0, import_core7.info)("--- JSON Output Preview ---");
|
|
889
964
|
console.log(content);
|
|
890
|
-
(0,
|
|
965
|
+
(0, import_core7.info)("--- End Preview ---");
|
|
891
966
|
return;
|
|
892
967
|
}
|
|
893
968
|
const dir = path2.dirname(outputPath);
|
|
@@ -895,7 +970,7 @@ function writeJson(outputPath, contexts, dryRun) {
|
|
|
895
970
|
fs3.mkdirSync(dir, { recursive: true });
|
|
896
971
|
}
|
|
897
972
|
fs3.writeFileSync(outputPath, content, "utf-8");
|
|
898
|
-
(0,
|
|
973
|
+
(0, import_core7.success)(`JSON output written to ${outputPath}`);
|
|
899
974
|
}
|
|
900
975
|
|
|
901
976
|
// src/templates/ejs.ts
|
|
@@ -1233,9 +1308,9 @@ async function processWithLLM(context, config) {
|
|
|
1233
1308
|
entries: context.entries
|
|
1234
1309
|
};
|
|
1235
1310
|
try {
|
|
1236
|
-
(0,
|
|
1311
|
+
(0, import_core8.info)(`Using LLM provider: ${config.llm.provider}${config.llm.model ? ` (${config.llm.model})` : ""}`);
|
|
1237
1312
|
if (config.llm.baseURL) {
|
|
1238
|
-
(0,
|
|
1313
|
+
(0, import_core8.info)(`LLM base URL: ${config.llm.baseURL}`);
|
|
1239
1314
|
}
|
|
1240
1315
|
const rawProvider = createProvider(config.llm);
|
|
1241
1316
|
const retryOpts = config.llm.retry ?? LLM_DEFAULTS.retry;
|
|
@@ -1244,38 +1319,49 @@ async function processWithLLM(context, config) {
|
|
|
1244
1319
|
complete: (prompt, opts) => withRetry(() => rawProvider.complete(prompt, opts), retryOpts)
|
|
1245
1320
|
};
|
|
1246
1321
|
const activeTasks = Object.entries(tasks).filter(([, enabled]) => enabled).map(([name]) => name);
|
|
1247
|
-
(0,
|
|
1248
|
-
if (tasks.enhance) {
|
|
1249
|
-
(0,
|
|
1250
|
-
|
|
1251
|
-
|
|
1322
|
+
(0, import_core8.info)(`Running LLM tasks: ${activeTasks.join(", ")}`);
|
|
1323
|
+
if (tasks.enhance && tasks.categorize) {
|
|
1324
|
+
(0, import_core8.info)("Enhancing and categorizing entries with LLM (single call)...");
|
|
1325
|
+
const result = await enhanceAndCategorize(provider, context.entries, llmContext);
|
|
1326
|
+
enhanced.entries = result.enhancedEntries;
|
|
1327
|
+
enhanced.categories = {};
|
|
1328
|
+
for (const cat of result.categories) {
|
|
1329
|
+
enhanced.categories[cat.category] = cat.entries;
|
|
1330
|
+
}
|
|
1331
|
+
(0, import_core8.info)(`Enhanced ${enhanced.entries.length} entries into ${result.categories.length} categories`);
|
|
1332
|
+
} else {
|
|
1333
|
+
if (tasks.enhance) {
|
|
1334
|
+
(0, import_core8.info)("Enhancing entries with LLM...");
|
|
1335
|
+
enhanced.entries = await enhanceEntries(provider, context.entries, llmContext, config.llm.concurrency);
|
|
1336
|
+
(0, import_core8.info)(`Enhanced ${enhanced.entries.length} entries`);
|
|
1337
|
+
}
|
|
1338
|
+
if (tasks.categorize) {
|
|
1339
|
+
(0, import_core8.info)("Categorizing entries with LLM...");
|
|
1340
|
+
const categorized = await categorizeEntries(provider, enhanced.entries, llmContext);
|
|
1341
|
+
enhanced.categories = {};
|
|
1342
|
+
for (const cat of categorized) {
|
|
1343
|
+
enhanced.categories[cat.category] = cat.entries;
|
|
1344
|
+
}
|
|
1345
|
+
(0, import_core8.info)(`Created ${categorized.length} categories`);
|
|
1346
|
+
}
|
|
1252
1347
|
}
|
|
1253
1348
|
if (tasks.summarize) {
|
|
1254
|
-
(0,
|
|
1349
|
+
(0, import_core8.info)("Summarizing entries with LLM...");
|
|
1255
1350
|
enhanced.summary = await summarizeEntries(provider, enhanced.entries, llmContext);
|
|
1256
1351
|
if (enhanced.summary) {
|
|
1257
|
-
(0,
|
|
1258
|
-
(0,
|
|
1352
|
+
(0, import_core8.info)("Summary generated successfully");
|
|
1353
|
+
(0, import_core8.debug)(`Summary: ${enhanced.summary.substring(0, 100)}...`);
|
|
1259
1354
|
} else {
|
|
1260
|
-
(0,
|
|
1355
|
+
(0, import_core8.warn)("Summary generation returned empty result");
|
|
1261
1356
|
}
|
|
1262
1357
|
}
|
|
1263
|
-
if (tasks.categorize) {
|
|
1264
|
-
(0, import_core7.info)("Categorizing entries with LLM...");
|
|
1265
|
-
const categorized = await categorizeEntries(provider, enhanced.entries, llmContext);
|
|
1266
|
-
enhanced.categories = {};
|
|
1267
|
-
for (const cat of categorized) {
|
|
1268
|
-
enhanced.categories[cat.category] = cat.entries;
|
|
1269
|
-
}
|
|
1270
|
-
(0, import_core7.info)(`Created ${categorized.length} categories`);
|
|
1271
|
-
}
|
|
1272
1358
|
if (tasks.releaseNotes) {
|
|
1273
|
-
(0,
|
|
1359
|
+
(0, import_core8.info)("Generating release notes with LLM...");
|
|
1274
1360
|
enhanced.releaseNotes = await generateReleaseNotes(provider, enhanced.entries, llmContext);
|
|
1275
1361
|
if (enhanced.releaseNotes) {
|
|
1276
|
-
(0,
|
|
1362
|
+
(0, import_core8.info)("Release notes generated successfully");
|
|
1277
1363
|
} else {
|
|
1278
|
-
(0,
|
|
1364
|
+
(0, import_core8.warn)("Release notes generation returned empty result");
|
|
1279
1365
|
}
|
|
1280
1366
|
}
|
|
1281
1367
|
return {
|
|
@@ -1284,8 +1370,8 @@ async function processWithLLM(context, config) {
|
|
|
1284
1370
|
enhanced
|
|
1285
1371
|
};
|
|
1286
1372
|
} catch (error) {
|
|
1287
|
-
(0,
|
|
1288
|
-
(0,
|
|
1373
|
+
(0, import_core8.warn)(`LLM processing failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
1374
|
+
(0, import_core8.warn)("Falling back to raw entries");
|
|
1289
1375
|
return context;
|
|
1290
1376
|
}
|
|
1291
1377
|
}
|
|
@@ -1313,9 +1399,9 @@ async function generateWithTemplate(contexts, config, outputPath, dryRun) {
|
|
|
1313
1399
|
);
|
|
1314
1400
|
const result = renderTemplate(templatePath, documentContext, config.templates?.engine);
|
|
1315
1401
|
if (dryRun) {
|
|
1316
|
-
(0,
|
|
1402
|
+
(0, import_core8.info)("--- Changelog Preview ---");
|
|
1317
1403
|
console.log(result.content);
|
|
1318
|
-
(0,
|
|
1404
|
+
(0, import_core8.info)("--- End Preview ---");
|
|
1319
1405
|
return;
|
|
1320
1406
|
}
|
|
1321
1407
|
const dir = path6.dirname(outputPath);
|
|
@@ -1323,17 +1409,17 @@ async function generateWithTemplate(contexts, config, outputPath, dryRun) {
|
|
|
1323
1409
|
fs8.mkdirSync(dir, { recursive: true });
|
|
1324
1410
|
}
|
|
1325
1411
|
fs8.writeFileSync(outputPath, result.content, "utf-8");
|
|
1326
|
-
(0,
|
|
1412
|
+
(0, import_core8.success)(`Changelog written to ${outputPath} (using ${result.engine} template)`);
|
|
1327
1413
|
}
|
|
1328
1414
|
async function runPipeline(input, config, dryRun) {
|
|
1329
|
-
(0,
|
|
1415
|
+
(0, import_core8.debug)(`Processing ${input.packages.length} package(s)`);
|
|
1330
1416
|
let contexts = input.packages.map(createTemplateContext);
|
|
1331
1417
|
if (config.llm && !process.env.CHANGELOG_NO_LLM) {
|
|
1332
|
-
(0,
|
|
1418
|
+
(0, import_core8.info)("Processing with LLM enhancement");
|
|
1333
1419
|
contexts = await Promise.all(contexts.map((ctx) => processWithLLM(ctx, config)));
|
|
1334
1420
|
}
|
|
1335
1421
|
for (const output of config.output) {
|
|
1336
|
-
(0,
|
|
1422
|
+
(0, import_core8.info)(`Generating ${output.format} output`);
|
|
1337
1423
|
switch (output.format) {
|
|
1338
1424
|
case "markdown": {
|
|
1339
1425
|
const file = output.file ?? "CHANGELOG.md";
|
|
@@ -1351,22 +1437,22 @@ async function runPipeline(input, config, dryRun) {
|
|
|
1351
1437
|
}
|
|
1352
1438
|
case "github-release": {
|
|
1353
1439
|
if (dryRun) {
|
|
1354
|
-
(0,
|
|
1440
|
+
(0, import_core8.info)("[DRY RUN] Would create GitHub release");
|
|
1355
1441
|
break;
|
|
1356
1442
|
}
|
|
1357
1443
|
const firstContext = contexts[0];
|
|
1358
1444
|
if (!firstContext) {
|
|
1359
|
-
(0,
|
|
1445
|
+
(0, import_core8.warn)("No context available for GitHub release");
|
|
1360
1446
|
break;
|
|
1361
1447
|
}
|
|
1362
1448
|
const repoUrl = firstContext.repoUrl;
|
|
1363
1449
|
if (!repoUrl) {
|
|
1364
|
-
(0,
|
|
1450
|
+
(0, import_core8.warn)("No repo URL available, cannot create GitHub release");
|
|
1365
1451
|
break;
|
|
1366
1452
|
}
|
|
1367
1453
|
const parsed = parseRepoUrl(repoUrl);
|
|
1368
1454
|
if (!parsed) {
|
|
1369
|
-
(0,
|
|
1455
|
+
(0, import_core8.warn)(`Could not parse repo URL: ${repoUrl}`);
|
|
1370
1456
|
break;
|
|
1371
1457
|
}
|
|
1372
1458
|
await createGitHubRelease(firstContext, {
|
|
@@ -1388,7 +1474,7 @@ async function processInput(inputJson, config, dryRun) {
|
|
|
1388
1474
|
// src/monorepo/aggregator.ts
|
|
1389
1475
|
var fs9 = __toESM(require("fs"), 1);
|
|
1390
1476
|
var path7 = __toESM(require("path"), 1);
|
|
1391
|
-
var
|
|
1477
|
+
var import_core9 = require("@releasekit/core");
|
|
1392
1478
|
|
|
1393
1479
|
// src/monorepo/splitter.ts
|
|
1394
1480
|
function splitByPackage(contexts) {
|
|
@@ -1402,7 +1488,7 @@ function splitByPackage(contexts) {
|
|
|
1402
1488
|
// src/monorepo/aggregator.ts
|
|
1403
1489
|
function writeFile(outputPath, content, dryRun) {
|
|
1404
1490
|
if (dryRun) {
|
|
1405
|
-
(0,
|
|
1491
|
+
(0, import_core9.info)(`[DRY RUN] Would write to ${outputPath}`);
|
|
1406
1492
|
console.log(content);
|
|
1407
1493
|
return;
|
|
1408
1494
|
}
|
|
@@ -1411,7 +1497,7 @@ function writeFile(outputPath, content, dryRun) {
|
|
|
1411
1497
|
fs9.mkdirSync(dir, { recursive: true });
|
|
1412
1498
|
}
|
|
1413
1499
|
fs9.writeFileSync(outputPath, content, "utf-8");
|
|
1414
|
-
(0,
|
|
1500
|
+
(0, import_core9.success)(`Changelog written to ${outputPath}`);
|
|
1415
1501
|
}
|
|
1416
1502
|
function aggregateToRoot(contexts) {
|
|
1417
1503
|
const aggregated = {
|
|
@@ -1436,7 +1522,7 @@ function writeMonorepoChangelogs(contexts, options, config, dryRun) {
|
|
|
1436
1522
|
if (options.mode === "root" || options.mode === "both") {
|
|
1437
1523
|
const aggregated = aggregateToRoot(contexts);
|
|
1438
1524
|
const rootPath = path7.join(options.rootPath, "CHANGELOG.md");
|
|
1439
|
-
(0,
|
|
1525
|
+
(0, import_core9.info)(`Writing root changelog to ${rootPath}`);
|
|
1440
1526
|
const rootContent = config.updateStrategy === "prepend" && fs9.existsSync(rootPath) ? prependVersion(rootPath, aggregated) : renderMarkdown([aggregated]);
|
|
1441
1527
|
writeFile(rootPath, rootContent, dryRun);
|
|
1442
1528
|
}
|
|
@@ -1448,11 +1534,11 @@ function writeMonorepoChangelogs(contexts, options, config, dryRun) {
|
|
|
1448
1534
|
const packageDir = packageDirMap.get(packageName) ?? (simpleName ? packageDirMap.get(simpleName) : void 0) ?? null;
|
|
1449
1535
|
if (packageDir) {
|
|
1450
1536
|
const changelogPath = path7.join(packageDir, "CHANGELOG.md");
|
|
1451
|
-
(0,
|
|
1537
|
+
(0, import_core9.info)(`Writing changelog for ${packageName} to ${changelogPath}`);
|
|
1452
1538
|
const pkgContent = config.updateStrategy === "prepend" && fs9.existsSync(changelogPath) ? prependVersion(changelogPath, ctx) : renderMarkdown([ctx]);
|
|
1453
1539
|
writeFile(changelogPath, pkgContent, dryRun);
|
|
1454
1540
|
} else {
|
|
1455
|
-
(0,
|
|
1541
|
+
(0, import_core9.info)(`Could not find directory for package ${packageName}, skipping`);
|
|
1456
1542
|
}
|
|
1457
1543
|
}
|
|
1458
1544
|
}
|
package/dist/index.js
CHANGED