@releasekit/notes 0.2.0-next.9 → 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.
- package/LICENSE +21 -0
- package/README.md +1 -1
- package/dist/aggregator-BDTUZWOA.js +13 -0
- package/dist/chunk-H7G2HRHI.js +134 -0
- package/dist/chunk-O4VCGEZT.js +147 -0
- package/dist/{chunk-BLWJTLRD.js → chunk-X4LY5WGG.js} +289 -394
- package/dist/cli.cjs +542 -369
- package/dist/cli.js +6 -27
- package/dist/index.cjs +544 -350
- package/dist/index.d.cts +41 -8
- package/dist/index.d.ts +41 -8
- package/dist/index.js +12 -6
- package/package.json +42 -31
package/dist/index.cjs
CHANGED
|
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
8
11
|
var __export = (target, all) => {
|
|
9
12
|
for (var name in all)
|
|
10
13
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -27,6 +30,295 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
30
|
));
|
|
28
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
32
|
|
|
33
|
+
// src/output/markdown.ts
|
|
34
|
+
function groupEntriesByType(entries) {
|
|
35
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
36
|
+
for (const type of TYPE_ORDER) {
|
|
37
|
+
grouped.set(type, []);
|
|
38
|
+
}
|
|
39
|
+
for (const entry of entries) {
|
|
40
|
+
const existing = grouped.get(entry.type) ?? [];
|
|
41
|
+
existing.push(entry);
|
|
42
|
+
grouped.set(entry.type, existing);
|
|
43
|
+
}
|
|
44
|
+
return grouped;
|
|
45
|
+
}
|
|
46
|
+
function formatEntry(entry) {
|
|
47
|
+
let line;
|
|
48
|
+
if (entry.breaking && entry.scope) {
|
|
49
|
+
line = `- **BREAKING** **${entry.scope}**: ${entry.description}`;
|
|
50
|
+
} else if (entry.breaking) {
|
|
51
|
+
line = `- **BREAKING** ${entry.description}`;
|
|
52
|
+
} else if (entry.scope) {
|
|
53
|
+
line = `- **${entry.scope}**: ${entry.description}`;
|
|
54
|
+
} else {
|
|
55
|
+
line = `- ${entry.description}`;
|
|
56
|
+
}
|
|
57
|
+
if (entry.issueIds && entry.issueIds.length > 0) {
|
|
58
|
+
line += ` (${entry.issueIds.join(", ")})`;
|
|
59
|
+
}
|
|
60
|
+
return line;
|
|
61
|
+
}
|
|
62
|
+
function formatVersion(context) {
|
|
63
|
+
const lines = [];
|
|
64
|
+
const versionHeader = context.previousVersion ? `## [${context.version}]` : `## ${context.version}`;
|
|
65
|
+
lines.push(`${versionHeader} - ${context.date}`);
|
|
66
|
+
lines.push("");
|
|
67
|
+
if (context.compareUrl) {
|
|
68
|
+
lines.push(`[Full Changelog](${context.compareUrl})`);
|
|
69
|
+
lines.push("");
|
|
70
|
+
}
|
|
71
|
+
if (context.enhanced?.summary) {
|
|
72
|
+
lines.push(context.enhanced.summary);
|
|
73
|
+
lines.push("");
|
|
74
|
+
}
|
|
75
|
+
const grouped = groupEntriesByType(context.entries);
|
|
76
|
+
for (const [type, entries] of grouped) {
|
|
77
|
+
if (entries.length === 0) continue;
|
|
78
|
+
lines.push(`### ${TYPE_LABELS[type]}`);
|
|
79
|
+
for (const entry of entries) {
|
|
80
|
+
lines.push(formatEntry(entry));
|
|
81
|
+
}
|
|
82
|
+
lines.push("");
|
|
83
|
+
}
|
|
84
|
+
return lines.join("\n");
|
|
85
|
+
}
|
|
86
|
+
function formatHeader() {
|
|
87
|
+
return `# Changelog
|
|
88
|
+
|
|
89
|
+
All notable changes to this project will be documented in this file.
|
|
90
|
+
|
|
91
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
92
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
93
|
+
|
|
94
|
+
`;
|
|
95
|
+
}
|
|
96
|
+
function renderMarkdown(contexts) {
|
|
97
|
+
const sections = [formatHeader()];
|
|
98
|
+
for (const context of contexts) {
|
|
99
|
+
sections.push(formatVersion(context));
|
|
100
|
+
}
|
|
101
|
+
return sections.join("\n");
|
|
102
|
+
}
|
|
103
|
+
function prependVersion(existingPath, context) {
|
|
104
|
+
let existing = "";
|
|
105
|
+
if (fs2.existsSync(existingPath)) {
|
|
106
|
+
existing = fs2.readFileSync(existingPath, "utf-8");
|
|
107
|
+
const headerEnd = existing.indexOf("\n## ");
|
|
108
|
+
if (headerEnd >= 0) {
|
|
109
|
+
const header = existing.slice(0, headerEnd);
|
|
110
|
+
const body = existing.slice(headerEnd + 1);
|
|
111
|
+
const newVersion = formatVersion(context);
|
|
112
|
+
return `${header}
|
|
113
|
+
|
|
114
|
+
${newVersion}
|
|
115
|
+
${body}`;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return renderMarkdown([context]);
|
|
119
|
+
}
|
|
120
|
+
function writeMarkdown(outputPath, contexts, config, dryRun) {
|
|
121
|
+
const content = renderMarkdown(contexts);
|
|
122
|
+
if (dryRun) {
|
|
123
|
+
(0, import_core5.info)(`Would write changelog to ${outputPath}`);
|
|
124
|
+
(0, import_core5.debug)("--- Changelog Preview ---");
|
|
125
|
+
(0, import_core5.debug)(content);
|
|
126
|
+
(0, import_core5.debug)("--- End Preview ---");
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const dir = path.dirname(outputPath);
|
|
130
|
+
if (!fs2.existsSync(dir)) {
|
|
131
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
132
|
+
}
|
|
133
|
+
if (outputPath === "-") {
|
|
134
|
+
process.stdout.write(content);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (config.updateStrategy === "prepend" && fs2.existsSync(outputPath) && contexts.length === 1) {
|
|
138
|
+
const firstContext = contexts[0];
|
|
139
|
+
if (firstContext) {
|
|
140
|
+
const updated = prependVersion(outputPath, firstContext);
|
|
141
|
+
fs2.writeFileSync(outputPath, updated, "utf-8");
|
|
142
|
+
}
|
|
143
|
+
} else {
|
|
144
|
+
fs2.writeFileSync(outputPath, content, "utf-8");
|
|
145
|
+
}
|
|
146
|
+
(0, import_core5.success)(`Changelog written to ${outputPath}`);
|
|
147
|
+
}
|
|
148
|
+
var fs2, path, import_core5, TYPE_ORDER, TYPE_LABELS;
|
|
149
|
+
var init_markdown = __esm({
|
|
150
|
+
"src/output/markdown.ts"() {
|
|
151
|
+
"use strict";
|
|
152
|
+
fs2 = __toESM(require("fs"), 1);
|
|
153
|
+
path = __toESM(require("path"), 1);
|
|
154
|
+
import_core5 = require("@releasekit/core");
|
|
155
|
+
TYPE_ORDER = ["added", "changed", "deprecated", "removed", "fixed", "security"];
|
|
156
|
+
TYPE_LABELS = {
|
|
157
|
+
added: "Added",
|
|
158
|
+
changed: "Changed",
|
|
159
|
+
deprecated: "Deprecated",
|
|
160
|
+
removed: "Removed",
|
|
161
|
+
fixed: "Fixed",
|
|
162
|
+
security: "Security"
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// src/monorepo/splitter.ts
|
|
168
|
+
function splitByPackage(contexts) {
|
|
169
|
+
const byPackage = /* @__PURE__ */ new Map();
|
|
170
|
+
for (const ctx of contexts) {
|
|
171
|
+
byPackage.set(ctx.packageName, ctx);
|
|
172
|
+
}
|
|
173
|
+
return byPackage;
|
|
174
|
+
}
|
|
175
|
+
var init_splitter = __esm({
|
|
176
|
+
"src/monorepo/splitter.ts"() {
|
|
177
|
+
"use strict";
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// src/monorepo/aggregator.ts
|
|
182
|
+
var aggregator_exports = {};
|
|
183
|
+
__export(aggregator_exports, {
|
|
184
|
+
aggregateToRoot: () => aggregateToRoot,
|
|
185
|
+
detectMonorepo: () => detectMonorepo,
|
|
186
|
+
splitByPackage: () => splitByPackage,
|
|
187
|
+
writeMonorepoChangelogs: () => writeMonorepoChangelogs
|
|
188
|
+
});
|
|
189
|
+
function writeFile(outputPath, content, dryRun) {
|
|
190
|
+
if (dryRun) {
|
|
191
|
+
(0, import_core8.info)(`Would write to ${outputPath}`);
|
|
192
|
+
(0, import_core8.debug)(content);
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
const dir = path6.dirname(outputPath);
|
|
196
|
+
if (!fs8.existsSync(dir)) {
|
|
197
|
+
fs8.mkdirSync(dir, { recursive: true });
|
|
198
|
+
}
|
|
199
|
+
fs8.writeFileSync(outputPath, content, "utf-8");
|
|
200
|
+
(0, import_core8.success)(`Changelog written to ${outputPath}`);
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
function aggregateToRoot(contexts) {
|
|
204
|
+
const aggregated = {
|
|
205
|
+
packageName: "monorepo",
|
|
206
|
+
version: contexts[0]?.version ?? "0.0.0",
|
|
207
|
+
previousVersion: contexts[0]?.previousVersion ?? null,
|
|
208
|
+
date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0] ?? "",
|
|
209
|
+
repoUrl: contexts[0]?.repoUrl ?? null,
|
|
210
|
+
entries: []
|
|
211
|
+
};
|
|
212
|
+
for (const ctx of contexts) {
|
|
213
|
+
for (const entry of ctx.entries) {
|
|
214
|
+
aggregated.entries.push({
|
|
215
|
+
...entry,
|
|
216
|
+
scope: entry.scope ? `${ctx.packageName}/${entry.scope}` : ctx.packageName
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return aggregated;
|
|
221
|
+
}
|
|
222
|
+
function writeMonorepoChangelogs(contexts, options, config, dryRun) {
|
|
223
|
+
const files = [];
|
|
224
|
+
if (options.mode === "root" || options.mode === "both") {
|
|
225
|
+
const aggregated = aggregateToRoot(contexts);
|
|
226
|
+
const rootPath = path6.join(options.rootPath, "CHANGELOG.md");
|
|
227
|
+
(0, import_core8.info)(`Writing root changelog to ${rootPath}`);
|
|
228
|
+
const rootContent = config.updateStrategy === "prepend" && fs8.existsSync(rootPath) ? prependVersion(rootPath, aggregated) : renderMarkdown([aggregated]);
|
|
229
|
+
if (writeFile(rootPath, rootContent, dryRun)) {
|
|
230
|
+
files.push(rootPath);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (options.mode === "packages" || options.mode === "both") {
|
|
234
|
+
const byPackage = splitByPackage(contexts);
|
|
235
|
+
const packageDirMap = buildPackageDirMap(options.rootPath, options.packagesPath);
|
|
236
|
+
for (const [packageName, ctx] of byPackage) {
|
|
237
|
+
const simpleName = packageName.split("/").pop();
|
|
238
|
+
const packageDir = packageDirMap.get(packageName) ?? (simpleName ? packageDirMap.get(simpleName) : void 0) ?? null;
|
|
239
|
+
if (packageDir) {
|
|
240
|
+
const changelogPath = path6.join(packageDir, "CHANGELOG.md");
|
|
241
|
+
(0, import_core8.info)(`Writing changelog for ${packageName} to ${changelogPath}`);
|
|
242
|
+
const pkgContent = config.updateStrategy === "prepend" && fs8.existsSync(changelogPath) ? prependVersion(changelogPath, ctx) : renderMarkdown([ctx]);
|
|
243
|
+
if (writeFile(changelogPath, pkgContent, dryRun)) {
|
|
244
|
+
files.push(changelogPath);
|
|
245
|
+
}
|
|
246
|
+
} else {
|
|
247
|
+
(0, import_core8.info)(`Could not find directory for package ${packageName}, skipping`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return files;
|
|
252
|
+
}
|
|
253
|
+
function buildPackageDirMap(rootPath, packagesPath) {
|
|
254
|
+
const map = /* @__PURE__ */ new Map();
|
|
255
|
+
const packagesDir = path6.join(rootPath, packagesPath);
|
|
256
|
+
if (!fs8.existsSync(packagesDir)) {
|
|
257
|
+
return map;
|
|
258
|
+
}
|
|
259
|
+
for (const entry of fs8.readdirSync(packagesDir, { withFileTypes: true })) {
|
|
260
|
+
if (!entry.isDirectory()) continue;
|
|
261
|
+
const dirPath = path6.join(packagesDir, entry.name);
|
|
262
|
+
map.set(entry.name, dirPath);
|
|
263
|
+
const packageJsonPath = path6.join(dirPath, "package.json");
|
|
264
|
+
if (fs8.existsSync(packageJsonPath)) {
|
|
265
|
+
try {
|
|
266
|
+
const pkg = JSON.parse(fs8.readFileSync(packageJsonPath, "utf-8"));
|
|
267
|
+
if (pkg.name) {
|
|
268
|
+
map.set(pkg.name, dirPath);
|
|
269
|
+
}
|
|
270
|
+
} catch {
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return map;
|
|
275
|
+
}
|
|
276
|
+
function detectMonorepo(cwd) {
|
|
277
|
+
const pnpmWorkspacesPath = path6.join(cwd, "pnpm-workspace.yaml");
|
|
278
|
+
const packageJsonPath = path6.join(cwd, "package.json");
|
|
279
|
+
if (fs8.existsSync(pnpmWorkspacesPath)) {
|
|
280
|
+
const content = fs8.readFileSync(pnpmWorkspacesPath, "utf-8");
|
|
281
|
+
const packagesMatch = content.match(/packages:\s*\n\s*-\s*['"]([^'"]+)['"]/);
|
|
282
|
+
if (packagesMatch?.[1]) {
|
|
283
|
+
const packagesGlob = packagesMatch[1];
|
|
284
|
+
const packagesPath = packagesGlob.replace(/\/?\*$/, "").replace(/\/\*\*$/, "");
|
|
285
|
+
return { isMonorepo: true, packagesPath: packagesPath || "packages" };
|
|
286
|
+
}
|
|
287
|
+
return { isMonorepo: true, packagesPath: "packages" };
|
|
288
|
+
}
|
|
289
|
+
if (fs8.existsSync(packageJsonPath)) {
|
|
290
|
+
try {
|
|
291
|
+
const content = fs8.readFileSync(packageJsonPath, "utf-8");
|
|
292
|
+
const pkg = JSON.parse(content);
|
|
293
|
+
if (pkg.workspaces) {
|
|
294
|
+
const workspaces = Array.isArray(pkg.workspaces) ? pkg.workspaces : pkg.workspaces.packages;
|
|
295
|
+
if (workspaces?.length) {
|
|
296
|
+
const firstWorkspace = workspaces[0];
|
|
297
|
+
if (firstWorkspace) {
|
|
298
|
+
const packagesPath = firstWorkspace.replace(/\/?\*$/, "").replace(/\/\*\*$/, "");
|
|
299
|
+
return { isMonorepo: true, packagesPath: packagesPath || "packages" };
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
} catch {
|
|
304
|
+
return { isMonorepo: false, packagesPath: "" };
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return { isMonorepo: false, packagesPath: "" };
|
|
308
|
+
}
|
|
309
|
+
var fs8, path6, import_core8;
|
|
310
|
+
var init_aggregator = __esm({
|
|
311
|
+
"src/monorepo/aggregator.ts"() {
|
|
312
|
+
"use strict";
|
|
313
|
+
fs8 = __toESM(require("fs"), 1);
|
|
314
|
+
path6 = __toESM(require("path"), 1);
|
|
315
|
+
import_core8 = require("@releasekit/core");
|
|
316
|
+
init_markdown();
|
|
317
|
+
init_splitter();
|
|
318
|
+
init_splitter();
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
|
|
30
322
|
// src/index.ts
|
|
31
323
|
var index_exports = {};
|
|
32
324
|
__export(index_exports, {
|
|
@@ -41,6 +333,7 @@ __export(index_exports, {
|
|
|
41
333
|
aggregateToRoot: () => aggregateToRoot,
|
|
42
334
|
createTemplateContext: () => createTemplateContext,
|
|
43
335
|
detectMonorepo: () => detectMonorepo,
|
|
336
|
+
formatVersion: () => formatVersion,
|
|
44
337
|
getDefaultConfig: () => getDefaultConfig,
|
|
45
338
|
getExitCode: () => getExitCode,
|
|
46
339
|
loadAuth: () => import_config.loadAuth,
|
|
@@ -73,9 +366,9 @@ function getDefaultConfig() {
|
|
|
73
366
|
}
|
|
74
367
|
|
|
75
368
|
// src/core/pipeline.ts
|
|
76
|
-
var
|
|
77
|
-
var
|
|
78
|
-
var
|
|
369
|
+
var fs9 = __toESM(require("fs"), 1);
|
|
370
|
+
var path7 = __toESM(require("path"), 1);
|
|
371
|
+
var import_core9 = require("@releasekit/core");
|
|
79
372
|
|
|
80
373
|
// src/input/package-versioner.ts
|
|
81
374
|
var fs = __toESM(require("fs"), 1);
|
|
@@ -404,6 +697,83 @@ var OpenAICompatibleProvider = class extends BaseLLMProvider {
|
|
|
404
697
|
|
|
405
698
|
// src/llm/tasks/categorize.ts
|
|
406
699
|
var import_core3 = require("@releasekit/core");
|
|
700
|
+
|
|
701
|
+
// src/llm/prompts.ts
|
|
702
|
+
function resolvePrompt(taskName, defaultPrompt, promptsConfig) {
|
|
703
|
+
if (!promptsConfig) return defaultPrompt;
|
|
704
|
+
const fullTemplate = promptsConfig.templates?.[taskName];
|
|
705
|
+
if (fullTemplate) return fullTemplate;
|
|
706
|
+
const additionalInstructions = promptsConfig.instructions?.[taskName];
|
|
707
|
+
if (additionalInstructions) {
|
|
708
|
+
const insertionPoint = defaultPrompt.lastIndexOf("Output only valid JSON");
|
|
709
|
+
if (insertionPoint !== -1) {
|
|
710
|
+
return `${defaultPrompt.slice(0, insertionPoint)}Additional instructions:
|
|
711
|
+
${additionalInstructions}
|
|
712
|
+
|
|
713
|
+
${defaultPrompt.slice(insertionPoint)}`;
|
|
714
|
+
}
|
|
715
|
+
return `${defaultPrompt}
|
|
716
|
+
|
|
717
|
+
Additional instructions:
|
|
718
|
+
${additionalInstructions}`;
|
|
719
|
+
}
|
|
720
|
+
return defaultPrompt;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
// src/llm/scopes.ts
|
|
724
|
+
function getAllowedScopesFromCategories(categories) {
|
|
725
|
+
const scopeMap = /* @__PURE__ */ new Map();
|
|
726
|
+
for (const cat of categories) {
|
|
727
|
+
if (cat.scopes && cat.scopes.length > 0) {
|
|
728
|
+
scopeMap.set(cat.name, cat.scopes);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
return scopeMap;
|
|
732
|
+
}
|
|
733
|
+
function resolveAllowedScopes(scopeConfig, categories, packageNames) {
|
|
734
|
+
if (!scopeConfig || scopeConfig.mode === "unrestricted") return null;
|
|
735
|
+
if (scopeConfig.mode === "none") return [];
|
|
736
|
+
if (scopeConfig.mode === "packages") return packageNames ?? [];
|
|
737
|
+
if (scopeConfig.mode === "restricted") {
|
|
738
|
+
const explicit = scopeConfig.rules?.allowed ?? [];
|
|
739
|
+
const all = new Set(explicit);
|
|
740
|
+
if (categories) {
|
|
741
|
+
const fromCategories = getAllowedScopesFromCategories(categories);
|
|
742
|
+
for (const scopes of fromCategories.values()) {
|
|
743
|
+
for (const s of scopes) all.add(s);
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
return [...all];
|
|
747
|
+
}
|
|
748
|
+
return null;
|
|
749
|
+
}
|
|
750
|
+
function validateScope(scope, allowedScopes, rules) {
|
|
751
|
+
if (!scope || allowedScopes === null) return scope;
|
|
752
|
+
if (allowedScopes.length === 0) return void 0;
|
|
753
|
+
const caseSensitive = rules?.caseSensitive ?? false;
|
|
754
|
+
const normalise = (s) => caseSensitive ? s : s.toLowerCase();
|
|
755
|
+
const isAllowed = allowedScopes.some((a) => normalise(a) === normalise(scope));
|
|
756
|
+
if (isAllowed) return scope;
|
|
757
|
+
switch (rules?.invalidScopeAction ?? "remove") {
|
|
758
|
+
case "keep":
|
|
759
|
+
return scope;
|
|
760
|
+
case "fallback":
|
|
761
|
+
return rules?.fallbackScope;
|
|
762
|
+
case "remove":
|
|
763
|
+
default:
|
|
764
|
+
return void 0;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
function validateEntryScopes(entries, scopeConfig, categories) {
|
|
768
|
+
const allowedScopes = resolveAllowedScopes(scopeConfig, categories);
|
|
769
|
+
if (allowedScopes === null) return entries;
|
|
770
|
+
return entries.map((entry) => ({
|
|
771
|
+
...entry,
|
|
772
|
+
scope: validateScope(entry.scope, allowedScopes, scopeConfig?.rules)
|
|
773
|
+
}));
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
// src/llm/tasks/categorize.ts
|
|
407
777
|
var DEFAULT_CATEGORIZE_PROMPT = `You are categorizing changelog entries for a software release.
|
|
408
778
|
|
|
409
779
|
Given the following entries, group them into meaningful categories (e.g., "Core", "UI", "API", "Performance", "Bug Fixes", "Documentation").
|
|
@@ -415,20 +785,21 @@ Entries:
|
|
|
415
785
|
|
|
416
786
|
Output only valid JSON, nothing else:`;
|
|
417
787
|
function buildCustomCategorizePrompt(categories) {
|
|
418
|
-
const categoryList = categories.map((c) =>
|
|
419
|
-
|
|
788
|
+
const categoryList = categories.map((c) => {
|
|
789
|
+
const scopeInfo = c.scopes?.length ? ` Allowed scopes: ${c.scopes.join(", ")}.` : "";
|
|
790
|
+
return `- "${c.name}": ${c.description}${scopeInfo}`;
|
|
791
|
+
}).join("\n");
|
|
792
|
+
const scopeMap = getAllowedScopesFromCategories(categories);
|
|
420
793
|
let scopeInstructions = "";
|
|
421
|
-
if (
|
|
422
|
-
const
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
if (scopes.length > 0) {
|
|
426
|
-
scopeInstructions = `
|
|
427
|
-
|
|
428
|
-
For the "Developer" category, you MUST assign a scope from this exact list: ${scopes.join(", ")}.
|
|
429
|
-
`;
|
|
430
|
-
}
|
|
794
|
+
if (scopeMap.size > 0) {
|
|
795
|
+
const entries = [];
|
|
796
|
+
for (const [catName, scopes] of scopeMap) {
|
|
797
|
+
entries.push(`For "${catName}", assign a scope from: ${scopes.join(", ")}.`);
|
|
431
798
|
}
|
|
799
|
+
scopeInstructions = `
|
|
800
|
+
|
|
801
|
+
${entries.join("\n")}
|
|
802
|
+
Only use scopes from these predefined lists. If an entry does not fit any scope, set scope to null.`;
|
|
432
803
|
}
|
|
433
804
|
return `You are categorizing changelog entries for a software release.
|
|
434
805
|
|
|
@@ -436,9 +807,10 @@ Given the following entries, group them into the specified categories. Only use
|
|
|
436
807
|
|
|
437
808
|
Categories:
|
|
438
809
|
${categoryList}${scopeInstructions}
|
|
810
|
+
|
|
439
811
|
Output a JSON object with two fields:
|
|
440
812
|
- "categories": an object where keys are category names and values are arrays of entry indices (0-based)
|
|
441
|
-
- "scopes": an object where keys are entry indices (as strings) and values are scope labels
|
|
813
|
+
- "scopes": an object where keys are entry indices (as strings) and values are scope labels. Only include entries that have a valid scope from the predefined list.
|
|
442
814
|
|
|
443
815
|
Entries:
|
|
444
816
|
{{entries}}
|
|
@@ -449,9 +821,11 @@ async function categorizeEntries(provider, entries, context) {
|
|
|
449
821
|
if (entries.length === 0) {
|
|
450
822
|
return [];
|
|
451
823
|
}
|
|
452
|
-
const
|
|
824
|
+
const entriesCopy = entries.map((e) => ({ ...e, scope: void 0 }));
|
|
825
|
+
const entriesText = entriesCopy.map((e, i) => `${i}. [${e.type}]: ${e.description}`).join("\n");
|
|
453
826
|
const hasCustomCategories = context.categories && context.categories.length > 0;
|
|
454
|
-
const
|
|
827
|
+
const defaultPrompt = hasCustomCategories ? buildCustomCategorizePrompt(context.categories) : DEFAULT_CATEGORIZE_PROMPT;
|
|
828
|
+
const promptTemplate = resolvePrompt("categorize", defaultPrompt, context.prompts);
|
|
455
829
|
const prompt = promptTemplate.replace("{{entries}}", entriesText);
|
|
456
830
|
try {
|
|
457
831
|
const response = await provider.complete(prompt);
|
|
@@ -463,13 +837,14 @@ async function categorizeEntries(provider, entries, context) {
|
|
|
463
837
|
const scopeMap = parsed.scopes || {};
|
|
464
838
|
for (const [indexStr, scope] of Object.entries(scopeMap)) {
|
|
465
839
|
const idx = Number.parseInt(indexStr, 10);
|
|
466
|
-
if (
|
|
467
|
-
|
|
840
|
+
if (entriesCopy[idx] && scope && scope.trim()) {
|
|
841
|
+
entriesCopy[idx] = { ...entriesCopy[idx], scope: scope.trim() };
|
|
468
842
|
}
|
|
469
843
|
}
|
|
844
|
+
const validatedEntries = validateEntryScopes(entriesCopy, context.scopes, context.categories);
|
|
470
845
|
for (const [category, rawIndices] of Object.entries(categoryMap)) {
|
|
471
846
|
const indices = Array.isArray(rawIndices) ? rawIndices : [];
|
|
472
|
-
const categoryEntries = indices.map((i) =>
|
|
847
|
+
const categoryEntries = indices.map((i) => validatedEntries[i]).filter((e) => e !== void 0);
|
|
473
848
|
if (categoryEntries.length > 0) {
|
|
474
849
|
result.push({ category, entries: categoryEntries });
|
|
475
850
|
}
|
|
@@ -478,7 +853,7 @@ async function categorizeEntries(provider, entries, context) {
|
|
|
478
853
|
const categoryMap = parsed;
|
|
479
854
|
for (const [category, rawIndices] of Object.entries(categoryMap)) {
|
|
480
855
|
const indices = Array.isArray(rawIndices) ? rawIndices : [];
|
|
481
|
-
const categoryEntries = indices.map((i) =>
|
|
856
|
+
const categoryEntries = indices.map((i) => entriesCopy[i]).filter((e) => e !== void 0);
|
|
482
857
|
if (categoryEntries.length > 0) {
|
|
483
858
|
result.push({ category, entries: categoryEntries });
|
|
484
859
|
}
|
|
@@ -489,12 +864,12 @@ async function categorizeEntries(provider, entries, context) {
|
|
|
489
864
|
(0, import_core3.warn)(
|
|
490
865
|
`LLM categorization failed, falling back to General: ${error instanceof Error ? error.message : String(error)}`
|
|
491
866
|
);
|
|
492
|
-
return [{ category: "General", entries }];
|
|
867
|
+
return [{ category: "General", entries: entriesCopy }];
|
|
493
868
|
}
|
|
494
869
|
}
|
|
495
870
|
|
|
496
871
|
// src/llm/tasks/enhance.ts
|
|
497
|
-
var
|
|
872
|
+
var DEFAULT_ENHANCE_PROMPT = `You are improving changelog entries for a software project.
|
|
498
873
|
Given a technical commit message, rewrite it as a clear, user-friendly changelog entry.
|
|
499
874
|
|
|
500
875
|
Rules:
|
|
@@ -510,9 +885,10 @@ Type: {{type}}
|
|
|
510
885
|
Description: {{description}}
|
|
511
886
|
|
|
512
887
|
Rewritten description (only output the new description, nothing else):`;
|
|
513
|
-
async function enhanceEntry(provider, entry,
|
|
514
|
-
const styleText =
|
|
515
|
-
const
|
|
888
|
+
async function enhanceEntry(provider, entry, context) {
|
|
889
|
+
const styleText = context.style ? `- ${context.style}` : '- Use present tense ("Add feature" not "Added feature")';
|
|
890
|
+
const defaultPrompt = DEFAULT_ENHANCE_PROMPT.replace("{{style}}", styleText).replace("{{type}}", entry.type).replace("{{#if scope}}Scope: {{scope}}{{/if}}", entry.scope ? `Scope: ${entry.scope}` : "").replace("{{description}}", entry.description);
|
|
891
|
+
const prompt = resolvePrompt("enhance", defaultPrompt, context.prompts);
|
|
516
892
|
const response = await provider.complete(prompt);
|
|
517
893
|
return response.trim();
|
|
518
894
|
}
|
|
@@ -568,7 +944,23 @@ function buildPrompt(entries, categories, style) {
|
|
|
568
944
|
const entriesText = entries.map((e, i) => `${i}. [${e.type}]${e.scope ? ` (${e.scope})` : ""}: ${e.description}`).join("\n");
|
|
569
945
|
const styleText = style || 'Use present tense ("Add feature" not "Added feature"). Be concise.';
|
|
570
946
|
const categorySection = categories ? `Categories (use ONLY these):
|
|
571
|
-
${categories.map((c) =>
|
|
947
|
+
${categories.map((c) => {
|
|
948
|
+
const scopeInfo = c.scopes?.length ? ` Allowed scopes: ${c.scopes.join(", ")}.` : "";
|
|
949
|
+
return `- "${c.name}": ${c.description}${scopeInfo}`;
|
|
950
|
+
}).join("\n")}` : `Categories: Group into meaningful categories (e.g., "New", "Fixed", "Changed", "Removed").`;
|
|
951
|
+
let scopeInstruction = "";
|
|
952
|
+
if (categories) {
|
|
953
|
+
const scopeMap = getAllowedScopesFromCategories(categories);
|
|
954
|
+
if (scopeMap.size > 0) {
|
|
955
|
+
const parts = [];
|
|
956
|
+
for (const [catName, scopes] of scopeMap) {
|
|
957
|
+
parts.push(`For "${catName}" entries, assign a scope from: ${scopes.join(", ")}.`);
|
|
958
|
+
}
|
|
959
|
+
scopeInstruction = `
|
|
960
|
+
${parts.join("\n")}
|
|
961
|
+
Only use scopes from these predefined lists. Set scope to null if no scope applies.`;
|
|
962
|
+
}
|
|
963
|
+
}
|
|
572
964
|
return `You are generating release notes for a software project. Given the following changelog entries, do two things:
|
|
573
965
|
|
|
574
966
|
1. **Rewrite** each entry as a clear, user-friendly description
|
|
@@ -579,9 +971,7 @@ Style guidelines:
|
|
|
579
971
|
- Be concise (1 short sentence per entry)
|
|
580
972
|
- Focus on what changed, not implementation details
|
|
581
973
|
|
|
582
|
-
${categorySection}
|
|
583
|
-
|
|
584
|
-
${categories ? 'For entries in categories involving internal/developer changes, set a "scope" field with a short subcategory label (e.g., "CI", "Dependencies", "Testing").' : ""}
|
|
974
|
+
${categorySection}${scopeInstruction}
|
|
585
975
|
|
|
586
976
|
Entries:
|
|
587
977
|
${entriesText}
|
|
@@ -598,7 +988,8 @@ async function enhanceAndCategorize(provider, entries, context) {
|
|
|
598
988
|
const retryOpts = LLM_DEFAULTS.retry;
|
|
599
989
|
try {
|
|
600
990
|
return await withRetry(async () => {
|
|
601
|
-
const
|
|
991
|
+
const defaultPrompt = buildPrompt(entries, context.categories, context.style);
|
|
992
|
+
const prompt = resolvePrompt("enhanceAndCategorize", defaultPrompt, context.prompts);
|
|
602
993
|
const response = await provider.complete(prompt);
|
|
603
994
|
const cleaned = response.replace(/^```(?:json)?\n?/, "").replace(/\n?```$/, "").trim();
|
|
604
995
|
const parsed = JSON.parse(cleaned);
|
|
@@ -614,22 +1005,23 @@ async function enhanceAndCategorize(provider, entries, context) {
|
|
|
614
1005
|
scope: result.scope || original.scope
|
|
615
1006
|
};
|
|
616
1007
|
});
|
|
1008
|
+
const validatedEntries = validateEntryScopes(enhancedEntries, context.scopes, context.categories);
|
|
617
1009
|
const categoryMap = /* @__PURE__ */ new Map();
|
|
618
1010
|
for (let i = 0; i < parsed.entries.length; i++) {
|
|
619
1011
|
const result = parsed.entries[i];
|
|
620
1012
|
const category = result?.category || "General";
|
|
621
|
-
const entry =
|
|
1013
|
+
const entry = validatedEntries[i];
|
|
622
1014
|
if (!entry) continue;
|
|
623
1015
|
if (!categoryMap.has(category)) {
|
|
624
1016
|
categoryMap.set(category, []);
|
|
625
1017
|
}
|
|
626
|
-
categoryMap.get(category)
|
|
1018
|
+
categoryMap.get(category)?.push(entry);
|
|
627
1019
|
}
|
|
628
1020
|
const categories = [];
|
|
629
1021
|
for (const [category, catEntries] of categoryMap) {
|
|
630
1022
|
categories.push({ category, entries: catEntries });
|
|
631
1023
|
}
|
|
632
|
-
return { enhancedEntries, categories };
|
|
1024
|
+
return { enhancedEntries: validatedEntries, categories };
|
|
633
1025
|
}, retryOpts);
|
|
634
1026
|
} catch (error) {
|
|
635
1027
|
(0, import_core4.warn)(
|
|
@@ -643,7 +1035,7 @@ async function enhanceAndCategorize(provider, entries, context) {
|
|
|
643
1035
|
}
|
|
644
1036
|
|
|
645
1037
|
// src/llm/tasks/release-notes.ts
|
|
646
|
-
var
|
|
1038
|
+
var DEFAULT_RELEASE_NOTES_PROMPT = `You are writing release notes for a software project.
|
|
647
1039
|
|
|
648
1040
|
Create engaging, user-friendly release notes for the following changes.
|
|
649
1041
|
|
|
@@ -676,16 +1068,17 @@ No notable changes in this release.`;
|
|
|
676
1068
|
if (e.breaking) line += " **BREAKING**";
|
|
677
1069
|
return line;
|
|
678
1070
|
}).join("\n");
|
|
679
|
-
const
|
|
1071
|
+
const defaultPrompt = DEFAULT_RELEASE_NOTES_PROMPT.replace("{{version}}", context.version ?? "v1.0.0").replace(
|
|
680
1072
|
"{{#if previousVersion}}Previous version: {{previousVersion}}{{/if}}",
|
|
681
1073
|
context.previousVersion ? `Previous version: ${context.previousVersion}` : ""
|
|
682
1074
|
).replace("{{date}}", context.date ?? (/* @__PURE__ */ new Date()).toISOString().split("T")[0] ?? "").replace("{{entries}}", entriesText);
|
|
1075
|
+
const prompt = resolvePrompt("releaseNotes", defaultPrompt, context.prompts);
|
|
683
1076
|
const response = await provider.complete(prompt);
|
|
684
1077
|
return response.trim();
|
|
685
1078
|
}
|
|
686
1079
|
|
|
687
1080
|
// src/llm/tasks/summarize.ts
|
|
688
|
-
var
|
|
1081
|
+
var DEFAULT_SUMMARIZE_PROMPT = `You are creating a summary of changes for a software release.
|
|
689
1082
|
|
|
690
1083
|
Given the following changelog entries, create a brief summary (2-3 sentences) that captures the main themes of this release.
|
|
691
1084
|
|
|
@@ -693,12 +1086,13 @@ Entries:
|
|
|
693
1086
|
{{entries}}
|
|
694
1087
|
|
|
695
1088
|
Summary (only output the summary, nothing else):`;
|
|
696
|
-
async function summarizeEntries(provider, entries,
|
|
1089
|
+
async function summarizeEntries(provider, entries, context) {
|
|
697
1090
|
if (entries.length === 0) {
|
|
698
1091
|
return "";
|
|
699
1092
|
}
|
|
700
1093
|
const entriesText = entries.map((e) => `- [${e.type}]${e.scope ? ` (${e.scope})` : ""}: ${e.description}`).join("\n");
|
|
701
|
-
const
|
|
1094
|
+
const defaultPrompt = DEFAULT_SUMMARIZE_PROMPT.replace("{{entries}}", entriesText);
|
|
1095
|
+
const prompt = resolvePrompt("summarize", defaultPrompt, context.prompts);
|
|
702
1096
|
const response = await provider.complete(prompt);
|
|
703
1097
|
return response.trim();
|
|
704
1098
|
}
|
|
@@ -743,135 +1137,7 @@ function createProvider(config) {
|
|
|
743
1137
|
// src/output/github-release.ts
|
|
744
1138
|
var import_rest = require("@octokit/rest");
|
|
745
1139
|
var import_core6 = require("@releasekit/core");
|
|
746
|
-
|
|
747
|
-
// src/output/markdown.ts
|
|
748
|
-
var fs2 = __toESM(require("fs"), 1);
|
|
749
|
-
var path = __toESM(require("path"), 1);
|
|
750
|
-
var import_core5 = require("@releasekit/core");
|
|
751
|
-
var TYPE_ORDER = ["added", "changed", "deprecated", "removed", "fixed", "security"];
|
|
752
|
-
var TYPE_LABELS = {
|
|
753
|
-
added: "Added",
|
|
754
|
-
changed: "Changed",
|
|
755
|
-
deprecated: "Deprecated",
|
|
756
|
-
removed: "Removed",
|
|
757
|
-
fixed: "Fixed",
|
|
758
|
-
security: "Security"
|
|
759
|
-
};
|
|
760
|
-
function groupEntriesByType(entries) {
|
|
761
|
-
const grouped = /* @__PURE__ */ new Map();
|
|
762
|
-
for (const type of TYPE_ORDER) {
|
|
763
|
-
grouped.set(type, []);
|
|
764
|
-
}
|
|
765
|
-
for (const entry of entries) {
|
|
766
|
-
const existing = grouped.get(entry.type) ?? [];
|
|
767
|
-
existing.push(entry);
|
|
768
|
-
grouped.set(entry.type, existing);
|
|
769
|
-
}
|
|
770
|
-
return grouped;
|
|
771
|
-
}
|
|
772
|
-
function formatEntry(entry) {
|
|
773
|
-
let line;
|
|
774
|
-
if (entry.breaking && entry.scope) {
|
|
775
|
-
line = `- **BREAKING** **${entry.scope}**: ${entry.description}`;
|
|
776
|
-
} else if (entry.breaking) {
|
|
777
|
-
line = `- **BREAKING** ${entry.description}`;
|
|
778
|
-
} else if (entry.scope) {
|
|
779
|
-
line = `- **${entry.scope}**: ${entry.description}`;
|
|
780
|
-
} else {
|
|
781
|
-
line = `- ${entry.description}`;
|
|
782
|
-
}
|
|
783
|
-
if (entry.issueIds && entry.issueIds.length > 0) {
|
|
784
|
-
line += ` (${entry.issueIds.join(", ")})`;
|
|
785
|
-
}
|
|
786
|
-
return line;
|
|
787
|
-
}
|
|
788
|
-
function formatVersion(context) {
|
|
789
|
-
const lines = [];
|
|
790
|
-
const versionHeader = context.previousVersion ? `## [${context.version}]` : `## ${context.version}`;
|
|
791
|
-
lines.push(`${versionHeader} - ${context.date}`);
|
|
792
|
-
lines.push("");
|
|
793
|
-
if (context.compareUrl) {
|
|
794
|
-
lines.push(`[Full Changelog](${context.compareUrl})`);
|
|
795
|
-
lines.push("");
|
|
796
|
-
}
|
|
797
|
-
if (context.enhanced?.summary) {
|
|
798
|
-
lines.push(context.enhanced.summary);
|
|
799
|
-
lines.push("");
|
|
800
|
-
}
|
|
801
|
-
const grouped = groupEntriesByType(context.entries);
|
|
802
|
-
for (const [type, entries] of grouped) {
|
|
803
|
-
if (entries.length === 0) continue;
|
|
804
|
-
lines.push(`### ${TYPE_LABELS[type]}`);
|
|
805
|
-
for (const entry of entries) {
|
|
806
|
-
lines.push(formatEntry(entry));
|
|
807
|
-
}
|
|
808
|
-
lines.push("");
|
|
809
|
-
}
|
|
810
|
-
return lines.join("\n");
|
|
811
|
-
}
|
|
812
|
-
function formatHeader() {
|
|
813
|
-
return `# Changelog
|
|
814
|
-
|
|
815
|
-
All notable changes to this project will be documented in this file.
|
|
816
|
-
|
|
817
|
-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
818
|
-
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
819
|
-
|
|
820
|
-
`;
|
|
821
|
-
}
|
|
822
|
-
function renderMarkdown(contexts) {
|
|
823
|
-
const sections = [formatHeader()];
|
|
824
|
-
for (const context of contexts) {
|
|
825
|
-
sections.push(formatVersion(context));
|
|
826
|
-
}
|
|
827
|
-
return sections.join("\n");
|
|
828
|
-
}
|
|
829
|
-
function prependVersion(existingPath, context) {
|
|
830
|
-
let existing = "";
|
|
831
|
-
if (fs2.existsSync(existingPath)) {
|
|
832
|
-
existing = fs2.readFileSync(existingPath, "utf-8");
|
|
833
|
-
const headerEnd = existing.indexOf("\n## ");
|
|
834
|
-
if (headerEnd >= 0) {
|
|
835
|
-
const header = existing.slice(0, headerEnd);
|
|
836
|
-
const body = existing.slice(headerEnd + 1);
|
|
837
|
-
const newVersion = formatVersion(context);
|
|
838
|
-
return `${header}
|
|
839
|
-
|
|
840
|
-
${newVersion}
|
|
841
|
-
${body}`;
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
return renderMarkdown([context]);
|
|
845
|
-
}
|
|
846
|
-
function writeMarkdown(outputPath, contexts, config, dryRun) {
|
|
847
|
-
const content = renderMarkdown(contexts);
|
|
848
|
-
if (dryRun) {
|
|
849
|
-
(0, import_core5.info)("--- Changelog Preview ---");
|
|
850
|
-
console.log(content);
|
|
851
|
-
(0, import_core5.info)("--- End Preview ---");
|
|
852
|
-
return;
|
|
853
|
-
}
|
|
854
|
-
const dir = path.dirname(outputPath);
|
|
855
|
-
if (!fs2.existsSync(dir)) {
|
|
856
|
-
fs2.mkdirSync(dir, { recursive: true });
|
|
857
|
-
}
|
|
858
|
-
if (outputPath === "-") {
|
|
859
|
-
process.stdout.write(content);
|
|
860
|
-
return;
|
|
861
|
-
}
|
|
862
|
-
if (config.updateStrategy === "prepend" && fs2.existsSync(outputPath) && contexts.length === 1) {
|
|
863
|
-
const firstContext = contexts[0];
|
|
864
|
-
if (firstContext) {
|
|
865
|
-
const updated = prependVersion(outputPath, firstContext);
|
|
866
|
-
fs2.writeFileSync(outputPath, updated, "utf-8");
|
|
867
|
-
}
|
|
868
|
-
} else {
|
|
869
|
-
fs2.writeFileSync(outputPath, content, "utf-8");
|
|
870
|
-
}
|
|
871
|
-
(0, import_core5.success)(`Changelog written to ${outputPath}`);
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
// src/output/github-release.ts
|
|
1140
|
+
init_markdown();
|
|
875
1141
|
var GitHubClient = class {
|
|
876
1142
|
octokit;
|
|
877
1143
|
owner;
|
|
@@ -1007,9 +1273,10 @@ function renderJson(contexts) {
|
|
|
1007
1273
|
function writeJson(outputPath, contexts, dryRun) {
|
|
1008
1274
|
const content = renderJson(contexts);
|
|
1009
1275
|
if (dryRun) {
|
|
1010
|
-
(0, import_core7.info)(
|
|
1011
|
-
|
|
1012
|
-
(0, import_core7.
|
|
1276
|
+
(0, import_core7.info)(`Would write JSON output to ${outputPath}`);
|
|
1277
|
+
(0, import_core7.debug)("--- JSON Output Preview ---");
|
|
1278
|
+
(0, import_core7.debug)(content);
|
|
1279
|
+
(0, import_core7.debug)("--- End Preview ---");
|
|
1013
1280
|
return;
|
|
1014
1281
|
}
|
|
1015
1282
|
const dir = path2.dirname(outputPath);
|
|
@@ -1020,6 +1287,9 @@ function writeJson(outputPath, contexts, dryRun) {
|
|
|
1020
1287
|
(0, import_core7.success)(`JSON output written to ${outputPath}`);
|
|
1021
1288
|
}
|
|
1022
1289
|
|
|
1290
|
+
// src/core/pipeline.ts
|
|
1291
|
+
init_markdown();
|
|
1292
|
+
|
|
1023
1293
|
// src/templates/ejs.ts
|
|
1024
1294
|
var fs4 = __toESM(require("fs"), 1);
|
|
1025
1295
|
var import_ejs = __toESM(require("ejs"), 1);
|
|
@@ -1276,17 +1546,27 @@ function renderTemplate(templatePath, context, engine) {
|
|
|
1276
1546
|
|
|
1277
1547
|
// src/core/pipeline.ts
|
|
1278
1548
|
var import_meta = {};
|
|
1279
|
-
function generateCompareUrl(repoUrl, from, to) {
|
|
1549
|
+
function generateCompareUrl(repoUrl, from, to, packageName) {
|
|
1550
|
+
const isPackageSpecific = from.includes("@") && packageName && from.includes(packageName);
|
|
1551
|
+
let fromVersion;
|
|
1552
|
+
let toVersion;
|
|
1553
|
+
if (isPackageSpecific) {
|
|
1554
|
+
fromVersion = from;
|
|
1555
|
+
toVersion = `${packageName}@${to.startsWith("v") ? "" : "v"}${to}`;
|
|
1556
|
+
} else {
|
|
1557
|
+
fromVersion = from.replace(/^v/, "");
|
|
1558
|
+
toVersion = to.replace(/^v/, "");
|
|
1559
|
+
}
|
|
1280
1560
|
if (/gitlab\.com/i.test(repoUrl)) {
|
|
1281
|
-
return `${repoUrl}/-/compare/${
|
|
1561
|
+
return `${repoUrl}/-/compare/${fromVersion}...${toVersion}`;
|
|
1282
1562
|
}
|
|
1283
1563
|
if (/bitbucket\.org/i.test(repoUrl)) {
|
|
1284
|
-
return `${repoUrl}/branches/compare/${
|
|
1564
|
+
return `${repoUrl}/branches/compare/${fromVersion}..${toVersion}`;
|
|
1285
1565
|
}
|
|
1286
|
-
return `${repoUrl}/compare/${
|
|
1566
|
+
return `${repoUrl}/compare/${fromVersion}...${toVersion}`;
|
|
1287
1567
|
}
|
|
1288
1568
|
function createTemplateContext(pkg) {
|
|
1289
|
-
const compareUrl = pkg.repoUrl && pkg.previousVersion ? generateCompareUrl(pkg.repoUrl, pkg.previousVersion, pkg.version) : void 0;
|
|
1569
|
+
const compareUrl = pkg.repoUrl && pkg.previousVersion ? generateCompareUrl(pkg.repoUrl, pkg.previousVersion, pkg.version, pkg.packageName) : void 0;
|
|
1290
1570
|
return {
|
|
1291
1571
|
packageName: pkg.packageName,
|
|
1292
1572
|
version: pkg.version,
|
|
@@ -1324,15 +1604,17 @@ async function processWithLLM(context, config) {
|
|
|
1324
1604
|
previousVersion: context.previousVersion ?? void 0,
|
|
1325
1605
|
date: context.date,
|
|
1326
1606
|
categories: config.llm.categories,
|
|
1327
|
-
style: config.llm.style
|
|
1607
|
+
style: config.llm.style,
|
|
1608
|
+
scopes: config.llm.scopes,
|
|
1609
|
+
prompts: config.llm.prompts
|
|
1328
1610
|
};
|
|
1329
1611
|
const enhanced = {
|
|
1330
1612
|
entries: context.entries
|
|
1331
1613
|
};
|
|
1332
1614
|
try {
|
|
1333
|
-
(0,
|
|
1615
|
+
(0, import_core9.info)(`Using LLM provider: ${config.llm.provider}${config.llm.model ? ` (${config.llm.model})` : ""}`);
|
|
1334
1616
|
if (config.llm.baseURL) {
|
|
1335
|
-
(0,
|
|
1617
|
+
(0, import_core9.info)(`LLM base URL: ${config.llm.baseURL}`);
|
|
1336
1618
|
}
|
|
1337
1619
|
const rawProvider = createProvider(config.llm);
|
|
1338
1620
|
const retryOpts = config.llm.retry ?? LLM_DEFAULTS.retry;
|
|
@@ -1341,59 +1623,58 @@ async function processWithLLM(context, config) {
|
|
|
1341
1623
|
complete: (prompt, opts) => withRetry(() => rawProvider.complete(prompt, opts), retryOpts)
|
|
1342
1624
|
};
|
|
1343
1625
|
const activeTasks = Object.entries(tasks).filter(([, enabled]) => enabled).map(([name]) => name);
|
|
1344
|
-
(0,
|
|
1626
|
+
(0, import_core9.info)(`Running LLM tasks: ${activeTasks.join(", ")}`);
|
|
1345
1627
|
if (tasks.enhance && tasks.categorize) {
|
|
1346
|
-
(0,
|
|
1628
|
+
(0, import_core9.info)("Enhancing and categorizing entries with LLM...");
|
|
1347
1629
|
const result = await enhanceAndCategorize(provider, context.entries, llmContext);
|
|
1348
1630
|
enhanced.entries = result.enhancedEntries;
|
|
1349
1631
|
enhanced.categories = {};
|
|
1350
1632
|
for (const cat of result.categories) {
|
|
1351
1633
|
enhanced.categories[cat.category] = cat.entries;
|
|
1352
1634
|
}
|
|
1353
|
-
(0,
|
|
1635
|
+
(0, import_core9.info)(`Enhanced ${enhanced.entries.length} entries into ${result.categories.length} categories`);
|
|
1354
1636
|
} else {
|
|
1355
1637
|
if (tasks.enhance) {
|
|
1356
|
-
(0,
|
|
1638
|
+
(0, import_core9.info)("Enhancing entries with LLM...");
|
|
1357
1639
|
enhanced.entries = await enhanceEntries(provider, context.entries, llmContext, config.llm.concurrency);
|
|
1358
|
-
(0,
|
|
1640
|
+
(0, import_core9.info)(`Enhanced ${enhanced.entries.length} entries`);
|
|
1359
1641
|
}
|
|
1360
1642
|
if (tasks.categorize) {
|
|
1361
|
-
(0,
|
|
1643
|
+
(0, import_core9.info)("Categorizing entries with LLM...");
|
|
1362
1644
|
const categorized = await categorizeEntries(provider, enhanced.entries, llmContext);
|
|
1363
1645
|
enhanced.categories = {};
|
|
1364
1646
|
for (const cat of categorized) {
|
|
1365
1647
|
enhanced.categories[cat.category] = cat.entries;
|
|
1366
1648
|
}
|
|
1367
|
-
(0,
|
|
1649
|
+
(0, import_core9.info)(`Created ${categorized.length} categories`);
|
|
1368
1650
|
}
|
|
1369
1651
|
}
|
|
1370
1652
|
if (tasks.summarize) {
|
|
1371
|
-
(0,
|
|
1653
|
+
(0, import_core9.info)("Summarizing entries with LLM...");
|
|
1372
1654
|
enhanced.summary = await summarizeEntries(provider, enhanced.entries, llmContext);
|
|
1373
1655
|
if (enhanced.summary) {
|
|
1374
|
-
(0,
|
|
1375
|
-
(0,
|
|
1656
|
+
(0, import_core9.info)("Summary generated successfully");
|
|
1657
|
+
(0, import_core9.debug)(`Summary: ${enhanced.summary.substring(0, 100)}...`);
|
|
1376
1658
|
} else {
|
|
1377
|
-
(0,
|
|
1659
|
+
(0, import_core9.warn)("Summary generation returned empty result");
|
|
1378
1660
|
}
|
|
1379
1661
|
}
|
|
1380
1662
|
if (tasks.releaseNotes) {
|
|
1381
|
-
(0,
|
|
1663
|
+
(0, import_core9.info)("Generating release notes with LLM...");
|
|
1382
1664
|
enhanced.releaseNotes = await generateReleaseNotes(provider, enhanced.entries, llmContext);
|
|
1383
1665
|
if (enhanced.releaseNotes) {
|
|
1384
|
-
(0,
|
|
1666
|
+
(0, import_core9.info)("Release notes generated successfully");
|
|
1385
1667
|
} else {
|
|
1386
|
-
(0,
|
|
1668
|
+
(0, import_core9.warn)("Release notes generation returned empty result");
|
|
1387
1669
|
}
|
|
1388
1670
|
}
|
|
1389
1671
|
return {
|
|
1390
1672
|
...context,
|
|
1391
|
-
entries: enhanced.entries,
|
|
1392
1673
|
enhanced
|
|
1393
1674
|
};
|
|
1394
1675
|
} catch (error) {
|
|
1395
|
-
(0,
|
|
1396
|
-
(0,
|
|
1676
|
+
(0, import_core9.warn)(`LLM processing failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
1677
|
+
(0, import_core9.warn)("Falling back to raw entries");
|
|
1397
1678
|
return context;
|
|
1398
1679
|
}
|
|
1399
1680
|
}
|
|
@@ -1401,17 +1682,17 @@ function getBuiltinTemplatePath(style) {
|
|
|
1401
1682
|
let packageRoot;
|
|
1402
1683
|
try {
|
|
1403
1684
|
const currentUrl = import_meta.url;
|
|
1404
|
-
packageRoot =
|
|
1405
|
-
packageRoot =
|
|
1685
|
+
packageRoot = path7.dirname(new URL(currentUrl).pathname);
|
|
1686
|
+
packageRoot = path7.join(packageRoot, "..", "..");
|
|
1406
1687
|
} catch {
|
|
1407
1688
|
packageRoot = __dirname;
|
|
1408
1689
|
}
|
|
1409
|
-
return
|
|
1690
|
+
return path7.join(packageRoot, "templates", style);
|
|
1410
1691
|
}
|
|
1411
1692
|
async function generateWithTemplate(contexts, config, outputPath, dryRun) {
|
|
1412
1693
|
let templatePath;
|
|
1413
1694
|
if (config.templates?.path) {
|
|
1414
|
-
templatePath =
|
|
1695
|
+
templatePath = path7.resolve(config.templates.path);
|
|
1415
1696
|
} else {
|
|
1416
1697
|
templatePath = getBuiltinTemplatePath("keep-a-changelog");
|
|
1417
1698
|
}
|
|
@@ -1421,64 +1702,78 @@ async function generateWithTemplate(contexts, config, outputPath, dryRun) {
|
|
|
1421
1702
|
);
|
|
1422
1703
|
const result = renderTemplate(templatePath, documentContext, config.templates?.engine);
|
|
1423
1704
|
if (dryRun) {
|
|
1424
|
-
(0,
|
|
1425
|
-
|
|
1426
|
-
(0,
|
|
1705
|
+
(0, import_core9.info)(`Would write templated output to ${outputPath}`);
|
|
1706
|
+
(0, import_core9.debug)("--- Changelog Preview ---");
|
|
1707
|
+
(0, import_core9.debug)(result.content);
|
|
1708
|
+
(0, import_core9.debug)("--- End Preview ---");
|
|
1427
1709
|
return;
|
|
1428
1710
|
}
|
|
1429
1711
|
if (outputPath === "-") {
|
|
1430
1712
|
process.stdout.write(result.content);
|
|
1431
1713
|
return;
|
|
1432
1714
|
}
|
|
1433
|
-
const dir =
|
|
1434
|
-
if (!
|
|
1435
|
-
|
|
1715
|
+
const dir = path7.dirname(outputPath);
|
|
1716
|
+
if (!fs9.existsSync(dir)) {
|
|
1717
|
+
fs9.mkdirSync(dir, { recursive: true });
|
|
1436
1718
|
}
|
|
1437
|
-
|
|
1438
|
-
(0,
|
|
1719
|
+
fs9.writeFileSync(outputPath, result.content, "utf-8");
|
|
1720
|
+
(0, import_core9.success)(`Changelog written to ${outputPath} (using ${result.engine} template)`);
|
|
1439
1721
|
}
|
|
1440
1722
|
async function runPipeline(input, config, dryRun) {
|
|
1441
|
-
(0,
|
|
1723
|
+
(0, import_core9.debug)(`Processing ${input.packages.length} package(s)`);
|
|
1442
1724
|
let contexts = input.packages.map(createTemplateContext);
|
|
1443
1725
|
if (config.llm && !process.env.CHANGELOG_NO_LLM) {
|
|
1444
|
-
(0,
|
|
1726
|
+
(0, import_core9.info)("Processing with LLM enhancement");
|
|
1445
1727
|
contexts = await Promise.all(contexts.map((ctx) => processWithLLM(ctx, config)));
|
|
1446
1728
|
}
|
|
1729
|
+
const files = [];
|
|
1447
1730
|
for (const output of config.output) {
|
|
1448
|
-
(0,
|
|
1731
|
+
(0, import_core9.info)(`Generating ${output.format} output`);
|
|
1449
1732
|
switch (output.format) {
|
|
1450
1733
|
case "markdown": {
|
|
1451
1734
|
const file = output.file ?? "CHANGELOG.md";
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1735
|
+
try {
|
|
1736
|
+
const effectiveTemplateConfig = output.templates ?? config.templates;
|
|
1737
|
+
if (effectiveTemplateConfig?.path || output.options?.template) {
|
|
1738
|
+
const configWithTemplate = { ...config, templates: effectiveTemplateConfig };
|
|
1739
|
+
await generateWithTemplate(contexts, configWithTemplate, file, dryRun);
|
|
1740
|
+
} else {
|
|
1741
|
+
writeMarkdown(file, contexts, config, dryRun);
|
|
1742
|
+
}
|
|
1743
|
+
if (!dryRun) files.push(file);
|
|
1744
|
+
} catch (error) {
|
|
1745
|
+
(0, import_core9.warn)(`Failed to write ${file}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1456
1746
|
}
|
|
1457
1747
|
break;
|
|
1458
1748
|
}
|
|
1459
1749
|
case "json": {
|
|
1460
1750
|
const file = output.file ?? "changelog.json";
|
|
1461
|
-
|
|
1751
|
+
try {
|
|
1752
|
+
writeJson(file, contexts, dryRun);
|
|
1753
|
+
if (!dryRun) files.push(file);
|
|
1754
|
+
} catch (error) {
|
|
1755
|
+
(0, import_core9.warn)(`Failed to write ${file}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1756
|
+
}
|
|
1462
1757
|
break;
|
|
1463
1758
|
}
|
|
1464
1759
|
case "github-release": {
|
|
1465
1760
|
if (dryRun) {
|
|
1466
|
-
(0,
|
|
1761
|
+
(0, import_core9.info)("[DRY RUN] Would create GitHub release");
|
|
1467
1762
|
break;
|
|
1468
1763
|
}
|
|
1469
1764
|
const firstContext = contexts[0];
|
|
1470
1765
|
if (!firstContext) {
|
|
1471
|
-
(0,
|
|
1766
|
+
(0, import_core9.warn)("No context available for GitHub release");
|
|
1472
1767
|
break;
|
|
1473
1768
|
}
|
|
1474
1769
|
const repoUrl = firstContext.repoUrl;
|
|
1475
1770
|
if (!repoUrl) {
|
|
1476
|
-
(0,
|
|
1771
|
+
(0, import_core9.warn)("No repo URL available, cannot create GitHub release");
|
|
1477
1772
|
break;
|
|
1478
1773
|
}
|
|
1479
1774
|
const parsed = parseRepoUrl(repoUrl);
|
|
1480
1775
|
if (!parsed) {
|
|
1481
|
-
(0,
|
|
1776
|
+
(0, import_core9.warn)(`Could not parse repo URL: ${repoUrl}`);
|
|
1482
1777
|
break;
|
|
1483
1778
|
}
|
|
1484
1779
|
await createGitHubRelease(firstContext, {
|
|
@@ -1491,140 +1786,38 @@ async function runPipeline(input, config, dryRun) {
|
|
|
1491
1786
|
}
|
|
1492
1787
|
}
|
|
1493
1788
|
}
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
}
|
|
1511
|
-
return byPackage;
|
|
1512
|
-
}
|
|
1513
|
-
|
|
1514
|
-
// src/monorepo/aggregator.ts
|
|
1515
|
-
function writeFile(outputPath, content, dryRun) {
|
|
1516
|
-
if (dryRun) {
|
|
1517
|
-
(0, import_core9.info)(`[DRY RUN] Would write to ${outputPath}`);
|
|
1518
|
-
console.log(content);
|
|
1519
|
-
return;
|
|
1520
|
-
}
|
|
1521
|
-
const dir = path7.dirname(outputPath);
|
|
1522
|
-
if (!fs9.existsSync(dir)) {
|
|
1523
|
-
fs9.mkdirSync(dir, { recursive: true });
|
|
1524
|
-
}
|
|
1525
|
-
fs9.writeFileSync(outputPath, content, "utf-8");
|
|
1526
|
-
(0, import_core9.success)(`Changelog written to ${outputPath}`);
|
|
1527
|
-
}
|
|
1528
|
-
function aggregateToRoot(contexts) {
|
|
1529
|
-
const aggregated = {
|
|
1530
|
-
packageName: "monorepo",
|
|
1531
|
-
version: contexts[0]?.version ?? "0.0.0",
|
|
1532
|
-
previousVersion: contexts[0]?.previousVersion ?? null,
|
|
1533
|
-
date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0] ?? "",
|
|
1534
|
-
repoUrl: contexts[0]?.repoUrl ?? null,
|
|
1535
|
-
entries: []
|
|
1536
|
-
};
|
|
1537
|
-
for (const ctx of contexts) {
|
|
1538
|
-
for (const entry of ctx.entries) {
|
|
1539
|
-
aggregated.entries.push({
|
|
1540
|
-
...entry,
|
|
1541
|
-
scope: entry.scope ? `${ctx.packageName}/${entry.scope}` : ctx.packageName
|
|
1542
|
-
});
|
|
1789
|
+
if (config.monorepo?.mode) {
|
|
1790
|
+
const { detectMonorepo: detectMonorepo2, writeMonorepoChangelogs: writeMonorepoChangelogs2 } = await Promise.resolve().then(() => (init_aggregator(), aggregator_exports));
|
|
1791
|
+
const cwd = process.cwd();
|
|
1792
|
+
const detected = detectMonorepo2(cwd);
|
|
1793
|
+
if (detected.isMonorepo) {
|
|
1794
|
+
const monoFiles = writeMonorepoChangelogs2(
|
|
1795
|
+
contexts,
|
|
1796
|
+
{
|
|
1797
|
+
rootPath: config.monorepo.rootPath ?? cwd,
|
|
1798
|
+
packagesPath: config.monorepo.packagesPath ?? detected.packagesPath,
|
|
1799
|
+
mode: config.monorepo.mode
|
|
1800
|
+
},
|
|
1801
|
+
config,
|
|
1802
|
+
dryRun
|
|
1803
|
+
);
|
|
1804
|
+
files.push(...monoFiles);
|
|
1543
1805
|
}
|
|
1544
1806
|
}
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
if (options.mode === "root" || options.mode === "both") {
|
|
1549
|
-
const aggregated = aggregateToRoot(contexts);
|
|
1550
|
-
const rootPath = path7.join(options.rootPath, "CHANGELOG.md");
|
|
1551
|
-
(0, import_core9.info)(`Writing root changelog to ${rootPath}`);
|
|
1552
|
-
const rootContent = config.updateStrategy === "prepend" && fs9.existsSync(rootPath) ? prependVersion(rootPath, aggregated) : renderMarkdown([aggregated]);
|
|
1553
|
-
writeFile(rootPath, rootContent, dryRun);
|
|
1554
|
-
}
|
|
1555
|
-
if (options.mode === "packages" || options.mode === "both") {
|
|
1556
|
-
const byPackage = splitByPackage(contexts);
|
|
1557
|
-
const packageDirMap = buildPackageDirMap(options.rootPath, options.packagesPath);
|
|
1558
|
-
for (const [packageName, ctx] of byPackage) {
|
|
1559
|
-
const simpleName = packageName.split("/").pop();
|
|
1560
|
-
const packageDir = packageDirMap.get(packageName) ?? (simpleName ? packageDirMap.get(simpleName) : void 0) ?? null;
|
|
1561
|
-
if (packageDir) {
|
|
1562
|
-
const changelogPath = path7.join(packageDir, "CHANGELOG.md");
|
|
1563
|
-
(0, import_core9.info)(`Writing changelog for ${packageName} to ${changelogPath}`);
|
|
1564
|
-
const pkgContent = config.updateStrategy === "prepend" && fs9.existsSync(changelogPath) ? prependVersion(changelogPath, ctx) : renderMarkdown([ctx]);
|
|
1565
|
-
writeFile(changelogPath, pkgContent, dryRun);
|
|
1566
|
-
} else {
|
|
1567
|
-
(0, import_core9.info)(`Could not find directory for package ${packageName}, skipping`);
|
|
1568
|
-
}
|
|
1569
|
-
}
|
|
1570
|
-
}
|
|
1571
|
-
}
|
|
1572
|
-
function buildPackageDirMap(rootPath, packagesPath) {
|
|
1573
|
-
const map = /* @__PURE__ */ new Map();
|
|
1574
|
-
const packagesDir = path7.join(rootPath, packagesPath);
|
|
1575
|
-
if (!fs9.existsSync(packagesDir)) {
|
|
1576
|
-
return map;
|
|
1577
|
-
}
|
|
1578
|
-
for (const entry of fs9.readdirSync(packagesDir, { withFileTypes: true })) {
|
|
1579
|
-
if (!entry.isDirectory()) continue;
|
|
1580
|
-
const dirPath = path7.join(packagesDir, entry.name);
|
|
1581
|
-
map.set(entry.name, dirPath);
|
|
1582
|
-
const packageJsonPath = path7.join(dirPath, "package.json");
|
|
1583
|
-
if (fs9.existsSync(packageJsonPath)) {
|
|
1584
|
-
try {
|
|
1585
|
-
const pkg = JSON.parse(fs9.readFileSync(packageJsonPath, "utf-8"));
|
|
1586
|
-
if (pkg.name) {
|
|
1587
|
-
map.set(pkg.name, dirPath);
|
|
1588
|
-
}
|
|
1589
|
-
} catch {
|
|
1590
|
-
}
|
|
1591
|
-
}
|
|
1807
|
+
const packageNotes = {};
|
|
1808
|
+
for (const ctx of contexts) {
|
|
1809
|
+
packageNotes[ctx.packageName] = formatVersion(ctx);
|
|
1592
1810
|
}
|
|
1593
|
-
return
|
|
1811
|
+
return { packageNotes, files };
|
|
1594
1812
|
}
|
|
1595
|
-
function
|
|
1596
|
-
const
|
|
1597
|
-
|
|
1598
|
-
if (fs9.existsSync(pnpmWorkspacesPath)) {
|
|
1599
|
-
const content = fs9.readFileSync(pnpmWorkspacesPath, "utf-8");
|
|
1600
|
-
const packagesMatch = content.match(/packages:\s*\n\s*-\s*['"]([^'"]+)['"]/);
|
|
1601
|
-
if (packagesMatch?.[1]) {
|
|
1602
|
-
const packagesGlob = packagesMatch[1];
|
|
1603
|
-
const packagesPath = packagesGlob.replace(/\/?\*$/, "").replace(/\/\*\*$/, "");
|
|
1604
|
-
return { isMonorepo: true, packagesPath: packagesPath || "packages" };
|
|
1605
|
-
}
|
|
1606
|
-
return { isMonorepo: true, packagesPath: "packages" };
|
|
1607
|
-
}
|
|
1608
|
-
if (fs9.existsSync(packageJsonPath)) {
|
|
1609
|
-
try {
|
|
1610
|
-
const content = fs9.readFileSync(packageJsonPath, "utf-8");
|
|
1611
|
-
const pkg = JSON.parse(content);
|
|
1612
|
-
if (pkg.workspaces) {
|
|
1613
|
-
const workspaces = Array.isArray(pkg.workspaces) ? pkg.workspaces : pkg.workspaces.packages;
|
|
1614
|
-
if (workspaces?.length) {
|
|
1615
|
-
const firstWorkspace = workspaces[0];
|
|
1616
|
-
if (firstWorkspace) {
|
|
1617
|
-
const packagesPath = firstWorkspace.replace(/\/?\*$/, "").replace(/\/\*\*$/, "");
|
|
1618
|
-
return { isMonorepo: true, packagesPath: packagesPath || "packages" };
|
|
1619
|
-
}
|
|
1620
|
-
}
|
|
1621
|
-
}
|
|
1622
|
-
} catch {
|
|
1623
|
-
return { isMonorepo: false, packagesPath: "" };
|
|
1624
|
-
}
|
|
1625
|
-
}
|
|
1626
|
-
return { isMonorepo: false, packagesPath: "" };
|
|
1813
|
+
async function processInput(inputJson, config, dryRun) {
|
|
1814
|
+
const input = parsePackageVersioner(inputJson);
|
|
1815
|
+
return runPipeline(input, config, dryRun);
|
|
1627
1816
|
}
|
|
1817
|
+
|
|
1818
|
+
// src/index.ts
|
|
1819
|
+
init_aggregator();
|
|
1820
|
+
init_markdown();
|
|
1628
1821
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1629
1822
|
0 && (module.exports = {
|
|
1630
1823
|
ChangelogCreatorError,
|
|
@@ -1638,6 +1831,7 @@ function detectMonorepo(cwd) {
|
|
|
1638
1831
|
aggregateToRoot,
|
|
1639
1832
|
createTemplateContext,
|
|
1640
1833
|
detectMonorepo,
|
|
1834
|
+
formatVersion,
|
|
1641
1835
|
getDefaultConfig,
|
|
1642
1836
|
getExitCode,
|
|
1643
1837
|
loadAuth,
|