@codefresh-io/gitops-release 1.3.1 → 1.5.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.
Files changed (52) hide show
  1. package/dist/agent/hooks.d.ts +1 -1
  2. package/dist/agent/hooks.d.ts.map +1 -1
  3. package/dist/agent/hooks.js +70 -13
  4. package/dist/agent/hooks.js.map +1 -1
  5. package/dist/agent/prompts.d.ts +1 -1
  6. package/dist/agent/prompts.d.ts.map +1 -1
  7. package/dist/agent/prompts.js +32 -16
  8. package/dist/agent/prompts.js.map +1 -1
  9. package/dist/commands/cherry-pick.test.js +3 -0
  10. package/dist/commands/cherry-pick.test.js.map +1 -1
  11. package/dist/commands/preview-query.d.ts +27 -0
  12. package/dist/commands/preview-query.d.ts.map +1 -0
  13. package/dist/commands/preview-query.js +271 -0
  14. package/dist/commands/preview-query.js.map +1 -0
  15. package/dist/commands/preview.d.ts +16 -0
  16. package/dist/commands/preview.d.ts.map +1 -0
  17. package/dist/commands/preview.js +284 -0
  18. package/dist/commands/preview.js.map +1 -0
  19. package/dist/commands/publish.test.js +1 -0
  20. package/dist/commands/publish.test.js.map +1 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +58 -0
  23. package/dist/index.js.map +1 -1
  24. package/dist/services/ai.d.ts +14 -0
  25. package/dist/services/ai.d.ts.map +1 -1
  26. package/dist/services/ai.js +124 -1
  27. package/dist/services/ai.js.map +1 -1
  28. package/dist/services/cherry-pick.d.ts +47 -0
  29. package/dist/services/cherry-pick.d.ts.map +1 -0
  30. package/dist/services/cherry-pick.js +165 -0
  31. package/dist/services/cherry-pick.js.map +1 -0
  32. package/dist/services/cherry-pick.test.d.ts +2 -0
  33. package/dist/services/cherry-pick.test.d.ts.map +1 -0
  34. package/dist/services/cherry-pick.test.js +202 -0
  35. package/dist/services/cherry-pick.test.js.map +1 -0
  36. package/dist/services/github.d.ts +19 -0
  37. package/dist/services/github.d.ts.map +1 -1
  38. package/dist/services/github.js +60 -0
  39. package/dist/services/github.js.map +1 -1
  40. package/dist/services/preview-cache.d.ts +75 -0
  41. package/dist/services/preview-cache.d.ts.map +1 -0
  42. package/dist/services/preview-cache.js +130 -0
  43. package/dist/services/preview-cache.js.map +1 -0
  44. package/dist/services/preview-cache.test.d.ts +2 -0
  45. package/dist/services/preview-cache.test.d.ts.map +1 -0
  46. package/dist/services/preview-cache.test.js +316 -0
  47. package/dist/services/preview-cache.test.js.map +1 -0
  48. package/dist/services/version.d.ts +7 -0
  49. package/dist/services/version.d.ts.map +1 -1
  50. package/dist/services/version.js +13 -0
  51. package/dist/services/version.js.map +1 -1
  52. package/package.json +1 -1
@@ -0,0 +1,271 @@
1
+ // ABOUTME: Query subcommands for the preview cache.
2
+ // ABOUTME: Allows drilling down into cached preview data (commits, stats, etc.).
3
+ import { loadPreviewCache, isCacheStale, getCacheAge, } from "../services/preview-cache.js";
4
+ import { ValidationError } from "../utils/errors.js";
5
+ /**
6
+ * Applies color to commit type for display.
7
+ */
8
+ function colorizeCommitType(c, type) {
9
+ switch (type) {
10
+ case "feat":
11
+ return c.green(type);
12
+ case "fix":
13
+ return c.yellow(type);
14
+ case "other":
15
+ return c.dim(type);
16
+ default:
17
+ return type;
18
+ }
19
+ }
20
+ /**
21
+ * Loads cache and shows staleness warning if needed.
22
+ * Throws if no cache exists.
23
+ */
24
+ async function loadCacheWithStalenessCheck(ctx) {
25
+ const cache = loadPreviewCache();
26
+ if (!cache) {
27
+ throw new ValidationError("No preview cache found. Run 'gitops-release preview' first to generate a preview.");
28
+ }
29
+ // Check staleness
30
+ const { github, formatter } = ctx;
31
+ const staleness = await isCacheStale(cache, github);
32
+ if (staleness.stale) {
33
+ const age = getCacheAge(cache);
34
+ const newCommitMsg = staleness.newCommits
35
+ ? ` (${staleness.newCommits} new commit${staleness.newCommits === 1 ? "" : "s"} since preview)`
36
+ : "";
37
+ formatter.warning(`Preview is stale${newCommitMsg} - generated ${age}`);
38
+ formatter.info("Run 'gitops-release preview' to refresh.");
39
+ formatter.newline();
40
+ }
41
+ return cache;
42
+ }
43
+ /**
44
+ * Lists commits from the preview cache with optional filters.
45
+ */
46
+ export async function previewCommitsCommand(ctx, options) {
47
+ const { formatter } = ctx;
48
+ const cache = await loadCacheWithStalenessCheck(ctx);
49
+ // Filter commits
50
+ let commits = cache.commits;
51
+ if (options.type) {
52
+ commits = commits.filter((c) => c.type === options.type);
53
+ }
54
+ if (options.author) {
55
+ const authorLower = options.author.toLowerCase();
56
+ commits = commits.filter((c) => c.author.toLowerCase().includes(authorLower));
57
+ }
58
+ if (options.breaking) {
59
+ commits = commits.filter((c) => c.isBreaking);
60
+ }
61
+ // Output
62
+ if (formatter.isJsonMode()) {
63
+ formatter.json({
64
+ total: commits.length,
65
+ filtered: commits.length !== cache.commits.length,
66
+ commits,
67
+ });
68
+ return;
69
+ }
70
+ const c = formatter.chalk();
71
+ // Header
72
+ if (options.breaking) {
73
+ formatter.header(`Potential Breaking Changes (${commits.length} commits)`);
74
+ }
75
+ else if (options.type) {
76
+ formatter.header(`Commits of type '${options.type}' (${commits.length} commits)`);
77
+ }
78
+ else if (options.author) {
79
+ formatter.header(`Commits by '${options.author}' (${commits.length} commits)`);
80
+ }
81
+ else {
82
+ formatter.header(`Commits in preview (${commits.length} total)`);
83
+ }
84
+ formatter.newline();
85
+ if (commits.length === 0) {
86
+ formatter.info("No commits match the filter criteria.");
87
+ return;
88
+ }
89
+ // Table header
90
+ const divider = c.dim("-".repeat(70));
91
+ formatter.text(`${c.bold("SHA".padEnd(9))} ${c.bold("Type".padEnd(8))} ${c.bold("Author".padEnd(15))} ${c.bold("Message")}`);
92
+ formatter.text(divider);
93
+ // Commits
94
+ for (const commit of commits) {
95
+ const sha = commit.sha.substring(0, 7);
96
+ const type = commit.type || "other";
97
+ const author = commit.author.substring(0, 14);
98
+ const summary = commit.summary || commit.message.substring(0, 40);
99
+ const breakingMarker = commit.isBreaking ? c.red("!") : " ";
100
+ const typeColored = colorizeCommitType(c, type);
101
+ formatter.text(`${sha}${breakingMarker} ${typeColored.padEnd(17)} ${author.padEnd(15)} ${summary}`);
102
+ // Show breaking reason if breaking filter is active
103
+ if (options.breaking && commit.breakingReason) {
104
+ formatter.text(c.dim(` ↳ Reason: ${commit.breakingReason}`));
105
+ }
106
+ }
107
+ // Footer
108
+ formatter.newline();
109
+ const breakingCount = commits.filter((c) => c.isBreaking).length;
110
+ if (breakingCount > 0 && !options.breaking) {
111
+ formatter.text(c.yellow(`⚠️ ${breakingCount} breaking change(s) marked with !`));
112
+ }
113
+ }
114
+ /**
115
+ * Shows details for a single commit from the cache.
116
+ */
117
+ export async function previewCommitCommand(ctx, sha) {
118
+ const { formatter } = ctx;
119
+ const cache = await loadCacheWithStalenessCheck(ctx);
120
+ // Find commit (allow partial SHA match)
121
+ const commit = cache.commits.find((c) => c.sha.startsWith(sha) || c.sha === sha);
122
+ if (!commit) {
123
+ throw new ValidationError(`Commit '${sha}' not found in preview cache.\n` +
124
+ "Run 'gitops-release preview commits' to see available commits.");
125
+ }
126
+ // Output
127
+ if (formatter.isJsonMode()) {
128
+ formatter.json(commit);
129
+ return;
130
+ }
131
+ const c = formatter.chalk();
132
+ formatter.header(`Commit ${commit.sha.substring(0, 7)}`);
133
+ formatter.newline();
134
+ formatter.keyValue("Full SHA", commit.sha);
135
+ formatter.keyValue("Author", commit.author);
136
+ formatter.keyValue("Date", commit.date || "Unknown");
137
+ formatter.keyValue("Type", commit.type || "other");
138
+ formatter.keyValue("Breaking", commit.isBreaking ? c.red("Yes") : c.green("No"));
139
+ if (commit.isBreaking && commit.breakingReason) {
140
+ formatter.keyValue("Reason", c.yellow(commit.breakingReason));
141
+ }
142
+ formatter.newline();
143
+ formatter.text(c.bold("Message:"));
144
+ formatter.text(` ${commit.message}`);
145
+ if (commit.summary && commit.summary !== commit.message) {
146
+ formatter.newline();
147
+ formatter.text(c.bold("Summary:"));
148
+ formatter.text(` ${commit.summary}`);
149
+ }
150
+ }
151
+ /**
152
+ * Shows stats summary from the preview cache.
153
+ */
154
+ export async function previewStatsCommand(ctx) {
155
+ const { formatter } = ctx;
156
+ const cache = await loadCacheWithStalenessCheck(ctx);
157
+ // Output
158
+ if (formatter.isJsonMode()) {
159
+ formatter.json({
160
+ generatedAt: cache.generatedAt,
161
+ baseRef: cache.baseRef,
162
+ compareTag: cache.compareTag,
163
+ suggestedVersion: cache.suggestedVersion,
164
+ stats: cache.stats,
165
+ hasNotes: cache.notes !== null,
166
+ });
167
+ return;
168
+ }
169
+ const c = formatter.chalk();
170
+ formatter.header("Preview Stats Summary");
171
+ formatter.newline();
172
+ formatter.keyValue("Generated", getCacheAge(cache));
173
+ formatter.keyValue("Base ref", cache.baseRef);
174
+ formatter.keyValue("Compare tag", cache.compareTag);
175
+ formatter.keyValue("Suggested version", c.green(cache.suggestedVersion));
176
+ formatter.newline();
177
+ const divider = c.dim("-".repeat(50));
178
+ formatter.text(c.bold("Statistics"));
179
+ formatter.text(divider);
180
+ formatter.keyValue("Total commits", String(cache.stats.totalCommits));
181
+ formatter.keyValue("Contributors", String(cache.stats.contributors));
182
+ // Commits by type
183
+ formatter.newline();
184
+ formatter.text(c.bold("Commits by Type"));
185
+ formatter.text(divider);
186
+ const byType = new Map();
187
+ let breakingCount = 0;
188
+ for (const commit of cache.commits) {
189
+ const type = commit.type || "other";
190
+ byType.set(type, (byType.get(type) ?? 0) + 1);
191
+ if (commit.isBreaking) {
192
+ breakingCount++;
193
+ }
194
+ }
195
+ const typeLabels = Array.from(byType.entries())
196
+ .sort((a, b) => b[1] - a[1])
197
+ .map(([type, count]) => `${type}: ${count}`)
198
+ .join(" ");
199
+ formatter.text(` ${typeLabels}`);
200
+ // Breaking changes
201
+ if (breakingCount > 0) {
202
+ formatter.newline();
203
+ formatter.text(c.yellow(`⚠️ ${breakingCount} potential breaking change(s)`));
204
+ formatter.text(c.dim(" Run 'gitops-release preview commits --breaking' for details"));
205
+ }
206
+ // Notes status
207
+ formatter.newline();
208
+ formatter.keyValue("AI notes", cache.notes ? c.green("Cached") : c.dim("Not generated (use preview without --no-notes)"));
209
+ }
210
+ /**
211
+ * Lists PRs from commits in the preview cache.
212
+ * This fetches PR data from GitHub based on commit associations.
213
+ */
214
+ export async function previewPrsCommand(ctx) {
215
+ const { github, formatter } = ctx;
216
+ const cache = await loadCacheWithStalenessCheck(ctx);
217
+ const spinner = formatter.spinner("Fetching PR information...");
218
+ spinner.start();
219
+ // Extract PR numbers from commit messages (common patterns)
220
+ const prNumbers = new Set();
221
+ for (const commit of cache.commits) {
222
+ // Match patterns like (#123), PR #123, Merge pull request #123
223
+ const prMatches = commit.message.matchAll(/#(\d+)/g);
224
+ for (const match of prMatches) {
225
+ prNumbers.add(parseInt(match[1], 10));
226
+ }
227
+ }
228
+ // Fetch PR details from GitHub in parallel
229
+ const prResults = await Promise.all(Array.from(prNumbers).map(async (prNumber) => {
230
+ try {
231
+ return await github.getPullRequest(prNumber);
232
+ }
233
+ catch {
234
+ return null;
235
+ }
236
+ }));
237
+ const prs = prResults
238
+ .filter((pr) => pr !== null)
239
+ .map((pr) => ({
240
+ number: pr.number,
241
+ title: pr.title,
242
+ author: pr.author,
243
+ state: pr.state,
244
+ }));
245
+ spinner.stop();
246
+ // Output
247
+ if (formatter.isJsonMode()) {
248
+ formatter.json({
249
+ total: prs.length,
250
+ prs,
251
+ });
252
+ return;
253
+ }
254
+ const c = formatter.chalk();
255
+ formatter.header(`Pull Requests in preview (${prs.length} PRs)`);
256
+ formatter.newline();
257
+ if (prs.length === 0) {
258
+ formatter.info("No PR references found in commit messages.");
259
+ formatter.info("PRs are detected from commit messages containing #<number>.");
260
+ return;
261
+ }
262
+ // Table header
263
+ const divider = c.dim("-".repeat(70));
264
+ formatter.text(`${c.bold("PR".padEnd(8))} ${c.bold("Title")}`);
265
+ formatter.text(divider);
266
+ for (const pr of prs.sort((a, b) => b.number - a.number)) {
267
+ const title = pr.title.length > 55 ? pr.title.substring(0, 52) + "..." : pr.title;
268
+ formatter.text(`#${String(pr.number).padEnd(6)} ${title}`);
269
+ }
270
+ }
271
+ //# sourceMappingURL=preview-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-query.js","sourceRoot":"","sources":["../../src/commands/preview-query.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { CommandContext } from "../context.js";
2
+ /**
3
+ * Options for the preview command.
4
+ */
5
+ export interface PreviewOptions {
6
+ branch?: string;
7
+ from?: string;
8
+ noNotes: boolean;
9
+ clear?: boolean;
10
+ }
11
+ /**
12
+ * Executes the preview command.
13
+ * Shows what commits would be in the next release with AI-generated notes.
14
+ */
15
+ export declare function previewCommand(ctx: CommandContext, options: PreviewOptions): Promise<void>;
16
+ //# sourceMappingURL=preview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/commands/preview.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAc/C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAgCD;;;GAGG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAqPhG"}
@@ -0,0 +1,284 @@
1
+ // ABOUTME: Preview command that shows what commits would be in the next release.
2
+ // ABOUTME: Generates AI release notes preview and analyzes commit patterns.
3
+ import { AIService, requireAnthropicApiKey } from "../services/ai.js";
4
+ import { parseReleaseTagVersion, formatVersion, suggestNextVersion, parseStableBranch, } from "../services/version.js";
5
+ import { NotFoundError } from "../utils/errors.js";
6
+ import { savePreviewCache, clearPreviewCache } from "../services/preview-cache.js";
7
+ import { filterCherryPickedCommits } from "../services/cherry-pick.js";
8
+ /**
9
+ * Extracts cacheable notes data from GeneratedReleaseNotes.
10
+ */
11
+ function extractCacheableNotes(notes) {
12
+ if (!notes) {
13
+ return null;
14
+ }
15
+ return {
16
+ artifactHubChangelog: notes.artifactHubChangelog,
17
+ githubReleaseNotes: notes.githubReleaseNotes,
18
+ };
19
+ }
20
+ /**
21
+ * Executes the preview command.
22
+ * Shows what commits would be in the next release with AI-generated notes.
23
+ */
24
+ export async function previewCommand(ctx, options) {
25
+ const { github, formatter } = ctx;
26
+ // Handle --clear flag
27
+ if (options.clear) {
28
+ const cleared = clearPreviewCache();
29
+ if (cleared) {
30
+ formatter.success("Preview cache cleared.");
31
+ }
32
+ else {
33
+ formatter.info("No preview cache to clear.");
34
+ }
35
+ return;
36
+ }
37
+ const spinner = formatter.spinner("Analyzing release preview...");
38
+ spinner.start();
39
+ // Determine target ref (where we're releasing from)
40
+ let targetRef = "main";
41
+ let isPatchRelease = false;
42
+ if (options.branch) {
43
+ // Patch release to existing stable branch
44
+ const version = parseStableBranch(options.branch);
45
+ if (!version) {
46
+ throw new NotFoundError(`Branch '${options.branch}'`, `Invalid stable branch format. Expected: stable/X.Y (e.g., stable/0.26)`);
47
+ }
48
+ targetRef = options.branch;
49
+ isPatchRelease = true;
50
+ }
51
+ else if (options.from) {
52
+ targetRef = options.from;
53
+ }
54
+ // Verify target ref exists and get HEAD SHA for cache
55
+ spinner.text = "Verifying target ref...";
56
+ let headSha;
57
+ try {
58
+ headSha = await github.getRefSha(targetRef);
59
+ }
60
+ catch {
61
+ throw new NotFoundError(`Ref '${targetRef}'`, `Could not find ref '${targetRef}'. Make sure it exists in the repository.`);
62
+ }
63
+ // Find the last release
64
+ spinner.text = "Finding last release...";
65
+ const releases = await github.listReleases(false);
66
+ if (releases.length === 0) {
67
+ spinner.stop();
68
+ formatter.warning("No previous releases found. This would be the first release.");
69
+ formatter.info("Run 'gitops-release create <major.minor>' to create the first release.");
70
+ return;
71
+ }
72
+ // Find the appropriate previous version
73
+ let previousRelease = releases[0]; // Most recent by default
74
+ if (isPatchRelease && options.branch) {
75
+ // For patch releases, find the latest release in the same minor version
76
+ const branchVersion = parseStableBranch(options.branch);
77
+ if (branchVersion) {
78
+ const versionPrefix = `${branchVersion.major}.${branchVersion.minor}.`;
79
+ const matchingRelease = releases.find((r) => r.tag.startsWith(versionPrefix));
80
+ if (matchingRelease) {
81
+ previousRelease = matchingRelease;
82
+ }
83
+ }
84
+ }
85
+ const previousVersion = parseReleaseTagVersion(previousRelease.tag);
86
+ if (!previousVersion) {
87
+ throw new NotFoundError("Previous version", `Could not parse version from release tag '${previousRelease.tag}'`);
88
+ }
89
+ // Calculate suggested next version
90
+ let suggestedVersion;
91
+ if (isPatchRelease) {
92
+ suggestedVersion = {
93
+ ...previousVersion,
94
+ patch: previousVersion.patch + 1,
95
+ };
96
+ }
97
+ else {
98
+ suggestedVersion = suggestNextVersion(previousVersion);
99
+ }
100
+ // Get comparison stats
101
+ spinner.text = "Gathering commit statistics...";
102
+ let stats;
103
+ try {
104
+ stats = await github.getCompareStats(previousRelease.tag, targetRef);
105
+ }
106
+ catch {
107
+ spinner.stop();
108
+ formatter.warning(`Could not compare ${previousRelease.tag} to ${targetRef}`);
109
+ formatter.info("The target ref may not be ahead of the previous release.");
110
+ return;
111
+ }
112
+ if (stats.totalCommits === 0) {
113
+ spinner.stop();
114
+ formatter.warning("No new commits since the last release.");
115
+ formatter.keyValue("Last release", previousRelease.tag);
116
+ formatter.keyValue("Target", targetRef);
117
+ return;
118
+ }
119
+ // Filter out cherry-picked commits (commits that exist on stable branch with same patch)
120
+ let commitsToAnalyze = stats.commits;
121
+ let cherryPickCount = 0;
122
+ if (!isPatchRelease) {
123
+ const stableBranch = `stable/${previousVersion.major}.${previousVersion.minor}`;
124
+ spinner.text = "Detecting cherry-picked commits...";
125
+ const filterResult = await filterCherryPickedCommits(github, stats.commits, "main", stableBranch, (msg) => formatter.verbose(msg));
126
+ commitsToAnalyze = filterResult.filtered;
127
+ cherryPickCount = filterResult.cherryPickCount;
128
+ }
129
+ if (commitsToAnalyze.length === 0) {
130
+ spinner.stop();
131
+ formatter.warning("No new commits since the last release (all commits were cherry-picks).");
132
+ formatter.keyValue("Last release", previousRelease.tag);
133
+ formatter.keyValue("Target", targetRef);
134
+ formatter.keyValue("Cherry-picked commits", String(cherryPickCount));
135
+ return;
136
+ }
137
+ // Always analyze commits with LLM (uses Opus 4.5 for accuracy)
138
+ const apiKey = requireAnthropicApiKey();
139
+ const aiService = new AIService(apiKey);
140
+ spinner.text = "Analyzing commits with AI...";
141
+ const analyzedCommits = await aiService.analyzeCommits(commitsToAnalyze);
142
+ // Calculate stats from analyzed commits
143
+ const byType = new Map();
144
+ let breakingCount = 0;
145
+ let nonConventionalCount = 0;
146
+ for (const commit of analyzedCommits) {
147
+ const type = commit.type || "other";
148
+ byType.set(type, (byType.get(type) ?? 0) + 1);
149
+ if (commit.isBreaking) {
150
+ breakingCount++;
151
+ }
152
+ if (type === "other") {
153
+ nonConventionalCount++;
154
+ }
155
+ }
156
+ // Build issues list
157
+ const issues = [];
158
+ if (breakingCount > 0) {
159
+ issues.push(`${breakingCount} commit(s) may contain breaking changes`);
160
+ }
161
+ if (nonConventionalCount > 0) {
162
+ issues.push(`${nonConventionalCount} commit(s) lack conventional format`);
163
+ }
164
+ // Get commits by type
165
+ const commitsByType = Array.from(byType.entries())
166
+ .sort((a, b) => b[1] - a[1])
167
+ .map(([type, count]) => ({ type, count }));
168
+ // Generate AI notes if not disabled
169
+ let notes = null;
170
+ if (!options.noNotes) {
171
+ spinner.text = "Generating AI release notes preview...";
172
+ try {
173
+ notes = await aiService.generateReleaseNotes({
174
+ version: formatVersion(suggestedVersion),
175
+ previousVersion: previousRelease.tag,
176
+ commits: commitsToAnalyze,
177
+ prDescriptions: [],
178
+ });
179
+ }
180
+ catch (error) {
181
+ // Don't fail the whole command if AI notes fail
182
+ spinner.warn("Could not generate AI release notes");
183
+ if (error instanceof Error) {
184
+ formatter.verbose(`AI error: ${error.message}`);
185
+ }
186
+ }
187
+ }
188
+ // Build shared stats and version string (used by both cache and preview data)
189
+ const formattedVersion = formatVersion(suggestedVersion);
190
+ const filteredAuthors = new Set(commitsToAnalyze.map((c) => c.author).filter((a) => a !== "Unknown"));
191
+ const previewStats = {
192
+ totalCommits: commitsToAnalyze.length,
193
+ contributors: filteredAuthors.size,
194
+ cherryPicksFiltered: cherryPickCount,
195
+ };
196
+ // Save cache
197
+ const cacheableNotes = extractCacheableNotes(notes);
198
+ const cache = {
199
+ generatedAt: new Date().toISOString(),
200
+ baseRef: targetRef,
201
+ headSha,
202
+ compareTag: previousRelease.tag,
203
+ suggestedVersion: formattedVersion,
204
+ stats: previewStats,
205
+ commits: analyzedCommits,
206
+ notes: cacheableNotes,
207
+ };
208
+ savePreviewCache(cache);
209
+ spinner.stop();
210
+ // Build preview data
211
+ const previewData = {
212
+ suggestedVersion: formattedVersion,
213
+ previousVersion: previousRelease.tag,
214
+ targetRef,
215
+ stats: previewStats,
216
+ commitsByType,
217
+ issues,
218
+ notes,
219
+ };
220
+ // Output
221
+ if (formatter.isJsonMode()) {
222
+ formatter.json({
223
+ ...previewData,
224
+ notes: cacheableNotes,
225
+ });
226
+ return;
227
+ }
228
+ displayPreview(formatter, previewData);
229
+ }
230
+ /**
231
+ * Displays the preview in human-readable format.
232
+ */
233
+ function displayPreview(formatter, data) {
234
+ const c = formatter.chalk();
235
+ formatter.header("Preview: Next Release");
236
+ formatter.newline();
237
+ formatter.keyValue("Comparing", `${data.targetRef} (HEAD) vs ${data.previousVersion} (last release)`);
238
+ formatter.keyValue("Suggested version", c.green(data.suggestedVersion));
239
+ formatter.newline();
240
+ // Summary section
241
+ const divider = c.dim("-".repeat(50));
242
+ formatter.text(c.bold("Summary"));
243
+ formatter.text(divider);
244
+ let summaryText = `${data.stats.totalCommits} commits from ${data.stats.contributors} contributor(s)`;
245
+ if (data.stats.cherryPicksFiltered && data.stats.cherryPicksFiltered > 0) {
246
+ summaryText += c.dim(` (${data.stats.cherryPicksFiltered} cherry-picks filtered)`);
247
+ }
248
+ formatter.text(summaryText);
249
+ formatter.newline();
250
+ // Commits by type
251
+ if (data.commitsByType.length > 0) {
252
+ formatter.text(c.bold("Commits by Type"));
253
+ formatter.text(divider);
254
+ const typeLabels = data.commitsByType.map(({ type, count }) => `${type}: ${count}`).join(" ");
255
+ formatter.text(` ${typeLabels}`);
256
+ formatter.newline();
257
+ }
258
+ // Potential issues
259
+ if (data.issues.length > 0) {
260
+ formatter.text(c.yellow.bold("Potential Issues"));
261
+ formatter.text(divider);
262
+ for (const issue of data.issues) {
263
+ formatter.text(` ${c.yellow("*")} ${issue}`);
264
+ }
265
+ formatter.newline();
266
+ }
267
+ // AI Release Notes
268
+ if (data.notes) {
269
+ formatter.text(c.bold("AI Release Notes (Preview)"));
270
+ formatter.text(divider);
271
+ formatter.newline();
272
+ formatter.text(data.notes.githubReleaseNotes);
273
+ formatter.newline();
274
+ }
275
+ else {
276
+ formatter.text(c.dim("(AI release notes skipped - use without --no-notes to generate)"));
277
+ formatter.newline();
278
+ }
279
+ // Next steps hint
280
+ formatter.text(divider);
281
+ formatter.text(c.dim(`To create this release: gitops-release create ${data.suggestedVersion.split(".").slice(0, 2).join(".")}`));
282
+ formatter.text(c.dim("Preview cached. Query with: preview commits, preview stats"));
283
+ }
284
+ //# sourceMappingURL=preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview.js","sourceRoot":"","sources":["../../src/commands/preview.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,7 @@ function createMockPR(overrides = {}) {
23
23
  mergeable: true,
24
24
  createdAt: "2025-01-01T00:00:00Z",
25
25
  updatedAt: "2025-01-01T00:00:00Z",
26
+ author: "testuser",
26
27
  ...overrides,
27
28
  };
28
29
  }