@releasekit/notes 0.2.0-next.6 → 0.2.0-next.7

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.
@@ -641,6 +641,33 @@ async function enhanceEntries(provider, entries, context, concurrency = LLM_DEFA
641
641
 
642
642
  // src/llm/tasks/enhance-and-categorize.ts
643
643
  import { warn as warn2 } from "@releasekit/core";
644
+
645
+ // src/utils/retry.ts
646
+ function sleep(ms) {
647
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
648
+ }
649
+ async function withRetry(fn, options = {}) {
650
+ const maxAttempts = options.maxAttempts ?? 3;
651
+ const initialDelay = options.initialDelay ?? 1e3;
652
+ const maxDelay = options.maxDelay ?? 3e4;
653
+ const backoffFactor = options.backoffFactor ?? 2;
654
+ let lastError;
655
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
656
+ try {
657
+ return await fn();
658
+ } catch (error) {
659
+ lastError = error;
660
+ if (attempt < maxAttempts - 1) {
661
+ const base = Math.min(initialDelay * backoffFactor ** attempt, maxDelay);
662
+ const jitter = base * 0.2 * (Math.random() * 2 - 1);
663
+ await sleep(Math.max(0, base + jitter));
664
+ }
665
+ }
666
+ }
667
+ throw lastError;
668
+ }
669
+
670
+ // src/llm/tasks/enhance-and-categorize.ts
644
671
  function buildPrompt(entries, categories, style) {
645
672
  const entriesText = entries.map((e, i) => `${i}. [${e.type}]${e.scope ? ` (${e.scope})` : ""}: ${e.description}`).join("\n");
646
673
  const styleText = style || 'Use present tense ("Add feature" not "Added feature"). Be concise.';
@@ -672,41 +699,46 @@ async function enhanceAndCategorize(provider, entries, context) {
672
699
  if (entries.length === 0) {
673
700
  return { enhancedEntries: [], categories: [] };
674
701
  }
675
- const prompt = buildPrompt(entries, context.categories, context.style);
702
+ const retryOpts = LLM_DEFAULTS.retry;
676
703
  try {
677
- const response = await provider.complete(prompt);
678
- const cleaned = response.replace(/^```(?:json)?\n?/, "").replace(/\n?```$/, "").trim();
679
- const parsed = JSON.parse(cleaned);
680
- if (!Array.isArray(parsed.entries)) {
681
- throw new Error('Response missing "entries" array');
682
- }
683
- const enhancedEntries = entries.map((original, i) => {
684
- const result = parsed.entries[i];
685
- if (!result) return original;
686
- return {
687
- ...original,
688
- description: result.description || original.description,
689
- scope: result.scope || original.scope
690
- };
691
- });
692
- const categoryMap = /* @__PURE__ */ new Map();
693
- for (let i = 0; i < parsed.entries.length; i++) {
694
- const result = parsed.entries[i];
695
- const category = result?.category || "General";
696
- const entry = enhancedEntries[i];
697
- if (!entry) continue;
698
- if (!categoryMap.has(category)) {
699
- categoryMap.set(category, []);
704
+ return await withRetry(async () => {
705
+ const prompt = buildPrompt(entries, context.categories, context.style);
706
+ const response = await provider.complete(prompt);
707
+ const cleaned = response.replace(/^```(?:json)?\n?/, "").replace(/\n?```$/, "").trim();
708
+ const parsed = JSON.parse(cleaned);
709
+ if (!Array.isArray(parsed.entries)) {
710
+ throw new Error('Response missing "entries" array');
700
711
  }
701
- categoryMap.get(category).push(entry);
702
- }
703
- const categories = [];
704
- for (const [category, catEntries] of categoryMap) {
705
- categories.push({ category, entries: catEntries });
706
- }
707
- return { enhancedEntries, categories };
712
+ const enhancedEntries = entries.map((original, i) => {
713
+ const result = parsed.entries[i];
714
+ if (!result) return original;
715
+ return {
716
+ ...original,
717
+ description: result.description || original.description,
718
+ scope: result.scope || original.scope
719
+ };
720
+ });
721
+ const categoryMap = /* @__PURE__ */ new Map();
722
+ for (let i = 0; i < parsed.entries.length; i++) {
723
+ const result = parsed.entries[i];
724
+ const category = result?.category || "General";
725
+ const entry = enhancedEntries[i];
726
+ if (!entry) continue;
727
+ if (!categoryMap.has(category)) {
728
+ categoryMap.set(category, []);
729
+ }
730
+ categoryMap.get(category).push(entry);
731
+ }
732
+ const categories = [];
733
+ for (const [category, catEntries] of categoryMap) {
734
+ categories.push({ category, entries: catEntries });
735
+ }
736
+ return { enhancedEntries, categories };
737
+ }, retryOpts);
708
738
  } catch (error) {
709
- warn2(`Combined enhance+categorize failed: ${error instanceof Error ? error.message : String(error)}`);
739
+ warn2(
740
+ `Combined enhance+categorize failed after ${retryOpts.maxAttempts} attempts: ${error instanceof Error ? error.message : String(error)}`
741
+ );
710
742
  return {
711
743
  enhancedEntries: entries,
712
744
  categories: [{ category: "General", entries }]
@@ -1181,31 +1213,6 @@ function renderTemplate(templatePath, context, engine) {
1181
1213
  return renderComposable(templatePath, context, engine);
1182
1214
  }
1183
1215
 
1184
- // src/utils/retry.ts
1185
- function sleep(ms) {
1186
- return new Promise((resolve2) => setTimeout(resolve2, ms));
1187
- }
1188
- async function withRetry(fn, options = {}) {
1189
- const maxAttempts = options.maxAttempts ?? 3;
1190
- const initialDelay = options.initialDelay ?? 1e3;
1191
- const maxDelay = options.maxDelay ?? 3e4;
1192
- const backoffFactor = options.backoffFactor ?? 2;
1193
- let lastError;
1194
- for (let attempt = 0; attempt < maxAttempts; attempt++) {
1195
- try {
1196
- return await fn();
1197
- } catch (error) {
1198
- lastError = error;
1199
- if (attempt < maxAttempts - 1) {
1200
- const base = Math.min(initialDelay * backoffFactor ** attempt, maxDelay);
1201
- const jitter = base * 0.2 * (Math.random() * 2 - 1);
1202
- await sleep(Math.max(0, base + jitter));
1203
- }
1204
- }
1205
- }
1206
- throw lastError;
1207
- }
1208
-
1209
1216
  // src/core/pipeline.ts
1210
1217
  function generateCompareUrl(repoUrl, from, to) {
1211
1218
  if (/gitlab\.com/i.test(repoUrl)) {
package/dist/cli.cjs CHANGED
@@ -487,6 +487,33 @@ async function enhanceEntries(provider, entries, context, concurrency = LLM_DEFA
487
487
 
488
488
  // src/llm/tasks/enhance-and-categorize.ts
489
489
  var import_core4 = require("@releasekit/core");
490
+
491
+ // src/utils/retry.ts
492
+ function sleep(ms) {
493
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
494
+ }
495
+ async function withRetry(fn, options = {}) {
496
+ const maxAttempts = options.maxAttempts ?? 3;
497
+ const initialDelay = options.initialDelay ?? 1e3;
498
+ const maxDelay = options.maxDelay ?? 3e4;
499
+ const backoffFactor = options.backoffFactor ?? 2;
500
+ let lastError;
501
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
502
+ try {
503
+ return await fn();
504
+ } catch (error2) {
505
+ lastError = error2;
506
+ if (attempt < maxAttempts - 1) {
507
+ const base = Math.min(initialDelay * backoffFactor ** attempt, maxDelay);
508
+ const jitter = base * 0.2 * (Math.random() * 2 - 1);
509
+ await sleep(Math.max(0, base + jitter));
510
+ }
511
+ }
512
+ }
513
+ throw lastError;
514
+ }
515
+
516
+ // src/llm/tasks/enhance-and-categorize.ts
490
517
  function buildPrompt(entries, categories, style) {
491
518
  const entriesText = entries.map((e, i) => `${i}. [${e.type}]${e.scope ? ` (${e.scope})` : ""}: ${e.description}`).join("\n");
492
519
  const styleText = style || 'Use present tense ("Add feature" not "Added feature"). Be concise.';
@@ -518,41 +545,46 @@ async function enhanceAndCategorize(provider, entries, context) {
518
545
  if (entries.length === 0) {
519
546
  return { enhancedEntries: [], categories: [] };
520
547
  }
521
- const prompt = buildPrompt(entries, context.categories, context.style);
548
+ const retryOpts = LLM_DEFAULTS.retry;
522
549
  try {
523
- const response = await provider.complete(prompt);
524
- const cleaned = response.replace(/^```(?:json)?\n?/, "").replace(/\n?```$/, "").trim();
525
- const parsed = JSON.parse(cleaned);
526
- if (!Array.isArray(parsed.entries)) {
527
- throw new Error('Response missing "entries" array');
528
- }
529
- const enhancedEntries = entries.map((original, i) => {
530
- const result = parsed.entries[i];
531
- if (!result) return original;
532
- return {
533
- ...original,
534
- description: result.description || original.description,
535
- scope: result.scope || original.scope
536
- };
537
- });
538
- const categoryMap = /* @__PURE__ */ new Map();
539
- for (let i = 0; i < parsed.entries.length; i++) {
540
- const result = parsed.entries[i];
541
- const category = result?.category || "General";
542
- const entry = enhancedEntries[i];
543
- if (!entry) continue;
544
- if (!categoryMap.has(category)) {
545
- categoryMap.set(category, []);
550
+ return await withRetry(async () => {
551
+ const prompt = buildPrompt(entries, context.categories, context.style);
552
+ const response = await provider.complete(prompt);
553
+ const cleaned = response.replace(/^```(?:json)?\n?/, "").replace(/\n?```$/, "").trim();
554
+ const parsed = JSON.parse(cleaned);
555
+ if (!Array.isArray(parsed.entries)) {
556
+ throw new Error('Response missing "entries" array');
546
557
  }
547
- categoryMap.get(category).push(entry);
548
- }
549
- const categories = [];
550
- for (const [category, catEntries] of categoryMap) {
551
- categories.push({ category, entries: catEntries });
552
- }
553
- return { enhancedEntries, categories };
558
+ const enhancedEntries = entries.map((original, i) => {
559
+ const result = parsed.entries[i];
560
+ if (!result) return original;
561
+ return {
562
+ ...original,
563
+ description: result.description || original.description,
564
+ scope: result.scope || original.scope
565
+ };
566
+ });
567
+ const categoryMap = /* @__PURE__ */ new Map();
568
+ for (let i = 0; i < parsed.entries.length; i++) {
569
+ const result = parsed.entries[i];
570
+ const category = result?.category || "General";
571
+ const entry = enhancedEntries[i];
572
+ if (!entry) continue;
573
+ if (!categoryMap.has(category)) {
574
+ categoryMap.set(category, []);
575
+ }
576
+ categoryMap.get(category).push(entry);
577
+ }
578
+ const categories = [];
579
+ for (const [category, catEntries] of categoryMap) {
580
+ categories.push({ category, entries: catEntries });
581
+ }
582
+ return { enhancedEntries, categories };
583
+ }, retryOpts);
554
584
  } catch (error2) {
555
- (0, import_core4.warn)(`Combined enhance+categorize failed: ${error2 instanceof Error ? error2.message : String(error2)}`);
585
+ (0, import_core4.warn)(
586
+ `Combined enhance+categorize failed after ${retryOpts.maxAttempts} attempts: ${error2 instanceof Error ? error2.message : String(error2)}`
587
+ );
556
588
  return {
557
589
  enhancedEntries: entries,
558
590
  categories: [{ category: "General", entries }]
@@ -1192,31 +1224,6 @@ function renderTemplate(templatePath, context, engine) {
1192
1224
  return renderComposable(templatePath, context, engine);
1193
1225
  }
1194
1226
 
1195
- // src/utils/retry.ts
1196
- function sleep(ms) {
1197
- return new Promise((resolve2) => setTimeout(resolve2, ms));
1198
- }
1199
- async function withRetry(fn, options = {}) {
1200
- const maxAttempts = options.maxAttempts ?? 3;
1201
- const initialDelay = options.initialDelay ?? 1e3;
1202
- const maxDelay = options.maxDelay ?? 3e4;
1203
- const backoffFactor = options.backoffFactor ?? 2;
1204
- let lastError;
1205
- for (let attempt = 0; attempt < maxAttempts; attempt++) {
1206
- try {
1207
- return await fn();
1208
- } catch (error2) {
1209
- lastError = error2;
1210
- if (attempt < maxAttempts - 1) {
1211
- const base = Math.min(initialDelay * backoffFactor ** attempt, maxDelay);
1212
- const jitter = base * 0.2 * (Math.random() * 2 - 1);
1213
- await sleep(Math.max(0, base + jitter));
1214
- }
1215
- }
1216
- }
1217
- throw lastError;
1218
- }
1219
-
1220
1227
  // src/core/pipeline.ts
1221
1228
  var import_meta = {};
1222
1229
  function generateCompareUrl(repoUrl, from, to) {
package/dist/cli.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  runPipeline,
12
12
  saveAuth,
13
13
  writeMonorepoChangelogs
14
- } from "./chunk-PJAWCB4Q.js";
14
+ } from "./chunk-BLWJTLRD.js";
15
15
 
16
16
  // src/cli.ts
17
17
  import * as fs from "fs";
package/dist/index.cjs CHANGED
@@ -537,6 +537,33 @@ async function enhanceEntries(provider, entries, context, concurrency = LLM_DEFA
537
537
 
538
538
  // src/llm/tasks/enhance-and-categorize.ts
539
539
  var import_core4 = require("@releasekit/core");
540
+
541
+ // src/utils/retry.ts
542
+ function sleep(ms) {
543
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
544
+ }
545
+ async function withRetry(fn, options = {}) {
546
+ const maxAttempts = options.maxAttempts ?? 3;
547
+ const initialDelay = options.initialDelay ?? 1e3;
548
+ const maxDelay = options.maxDelay ?? 3e4;
549
+ const backoffFactor = options.backoffFactor ?? 2;
550
+ let lastError;
551
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
552
+ try {
553
+ return await fn();
554
+ } catch (error) {
555
+ lastError = error;
556
+ if (attempt < maxAttempts - 1) {
557
+ const base = Math.min(initialDelay * backoffFactor ** attempt, maxDelay);
558
+ const jitter = base * 0.2 * (Math.random() * 2 - 1);
559
+ await sleep(Math.max(0, base + jitter));
560
+ }
561
+ }
562
+ }
563
+ throw lastError;
564
+ }
565
+
566
+ // src/llm/tasks/enhance-and-categorize.ts
540
567
  function buildPrompt(entries, categories, style) {
541
568
  const entriesText = entries.map((e, i) => `${i}. [${e.type}]${e.scope ? ` (${e.scope})` : ""}: ${e.description}`).join("\n");
542
569
  const styleText = style || 'Use present tense ("Add feature" not "Added feature"). Be concise.';
@@ -568,41 +595,46 @@ async function enhanceAndCategorize(provider, entries, context) {
568
595
  if (entries.length === 0) {
569
596
  return { enhancedEntries: [], categories: [] };
570
597
  }
571
- const prompt = buildPrompt(entries, context.categories, context.style);
598
+ const retryOpts = LLM_DEFAULTS.retry;
572
599
  try {
573
- const response = await provider.complete(prompt);
574
- const cleaned = response.replace(/^```(?:json)?\n?/, "").replace(/\n?```$/, "").trim();
575
- const parsed = JSON.parse(cleaned);
576
- if (!Array.isArray(parsed.entries)) {
577
- throw new Error('Response missing "entries" array');
578
- }
579
- const enhancedEntries = entries.map((original, i) => {
580
- const result = parsed.entries[i];
581
- if (!result) return original;
582
- return {
583
- ...original,
584
- description: result.description || original.description,
585
- scope: result.scope || original.scope
586
- };
587
- });
588
- const categoryMap = /* @__PURE__ */ new Map();
589
- for (let i = 0; i < parsed.entries.length; i++) {
590
- const result = parsed.entries[i];
591
- const category = result?.category || "General";
592
- const entry = enhancedEntries[i];
593
- if (!entry) continue;
594
- if (!categoryMap.has(category)) {
595
- categoryMap.set(category, []);
600
+ return await withRetry(async () => {
601
+ const prompt = buildPrompt(entries, context.categories, context.style);
602
+ const response = await provider.complete(prompt);
603
+ const cleaned = response.replace(/^```(?:json)?\n?/, "").replace(/\n?```$/, "").trim();
604
+ const parsed = JSON.parse(cleaned);
605
+ if (!Array.isArray(parsed.entries)) {
606
+ throw new Error('Response missing "entries" array');
596
607
  }
597
- categoryMap.get(category).push(entry);
598
- }
599
- const categories = [];
600
- for (const [category, catEntries] of categoryMap) {
601
- categories.push({ category, entries: catEntries });
602
- }
603
- return { enhancedEntries, categories };
608
+ const enhancedEntries = entries.map((original, i) => {
609
+ const result = parsed.entries[i];
610
+ if (!result) return original;
611
+ return {
612
+ ...original,
613
+ description: result.description || original.description,
614
+ scope: result.scope || original.scope
615
+ };
616
+ });
617
+ const categoryMap = /* @__PURE__ */ new Map();
618
+ for (let i = 0; i < parsed.entries.length; i++) {
619
+ const result = parsed.entries[i];
620
+ const category = result?.category || "General";
621
+ const entry = enhancedEntries[i];
622
+ if (!entry) continue;
623
+ if (!categoryMap.has(category)) {
624
+ categoryMap.set(category, []);
625
+ }
626
+ categoryMap.get(category).push(entry);
627
+ }
628
+ const categories = [];
629
+ for (const [category, catEntries] of categoryMap) {
630
+ categories.push({ category, entries: catEntries });
631
+ }
632
+ return { enhancedEntries, categories };
633
+ }, retryOpts);
604
634
  } catch (error) {
605
- (0, import_core4.warn)(`Combined enhance+categorize failed: ${error instanceof Error ? error.message : String(error)}`);
635
+ (0, import_core4.warn)(
636
+ `Combined enhance+categorize failed after ${retryOpts.maxAttempts} attempts: ${error instanceof Error ? error.message : String(error)}`
637
+ );
606
638
  return {
607
639
  enhancedEntries: entries,
608
640
  categories: [{ category: "General", entries }]
@@ -1242,31 +1274,6 @@ function renderTemplate(templatePath, context, engine) {
1242
1274
  return renderComposable(templatePath, context, engine);
1243
1275
  }
1244
1276
 
1245
- // src/utils/retry.ts
1246
- function sleep(ms) {
1247
- return new Promise((resolve2) => setTimeout(resolve2, ms));
1248
- }
1249
- async function withRetry(fn, options = {}) {
1250
- const maxAttempts = options.maxAttempts ?? 3;
1251
- const initialDelay = options.initialDelay ?? 1e3;
1252
- const maxDelay = options.maxDelay ?? 3e4;
1253
- const backoffFactor = options.backoffFactor ?? 2;
1254
- let lastError;
1255
- for (let attempt = 0; attempt < maxAttempts; attempt++) {
1256
- try {
1257
- return await fn();
1258
- } catch (error) {
1259
- lastError = error;
1260
- if (attempt < maxAttempts - 1) {
1261
- const base = Math.min(initialDelay * backoffFactor ** attempt, maxDelay);
1262
- const jitter = base * 0.2 * (Math.random() * 2 - 1);
1263
- await sleep(Math.max(0, base + jitter));
1264
- }
1265
- }
1266
- }
1267
- throw lastError;
1268
- }
1269
-
1270
1277
  // src/core/pipeline.ts
1271
1278
  var import_meta = {};
1272
1279
  function generateCompareUrl(repoUrl, from, to) {
package/dist/index.js CHANGED
@@ -24,7 +24,7 @@ import {
24
24
  writeJson,
25
25
  writeMarkdown,
26
26
  writeMonorepoChangelogs
27
- } from "./chunk-PJAWCB4Q.js";
27
+ } from "./chunk-BLWJTLRD.js";
28
28
  export {
29
29
  NotesError as ChangelogCreatorError,
30
30
  ConfigError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@releasekit/notes",
3
- "version": "0.2.0-next.6",
3
+ "version": "0.2.0-next.7",
4
4
  "description": "Changelog generation with LLM-powered enhancement and flexible templating",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",