Skip to content

Conversation

@D-K-P
Copy link
Member

@D-K-P D-K-P commented Dec 18, 2025

Summary by CodeRabbit

  • New Features

    • Added a Changelog Generator app to produce streamed, categorized changelogs from a GitHub repo and date range with per-section copy-to-MDX and an agent status panel.
  • UI

    • New responsive submission and response views with validation, example repos, loading/error states, auto-scroll, and clipboard actions.
  • Privacy

    • Optional token support for private repositories.
  • Chores

    • Expanded ignore rules to reduce tracked transient files.
  • Documentation

    • Added README and example environment configuration.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 18, 2025

Walkthrough

Adds a new changelog-generator Next.js app and supporting configs. Introduces UI pages (form at / and streaming response at /response/[runId]), global styles, Tailwind/PostCSS, TypeScript and ESLint configs, package manifest, and environment example. Adds Trigger.dev artifacts: a trigger task (generateChangelog), a stream definition (changelogStream), and a server-side API route that starts the task. Implements GitHub MCP tools (list_commits, get_commit_diff) using Octokit, several UI primitives (Button, Card, Alert, Input), a cn utility, and updates top-level .gitignore and README.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45–60 minutes

Areas to focus during review:

  • changelog-generator/trigger/generate-changelog.ts — schema, MCP tool integration, Octokit usage, streaming contract, error handling, abort behavior, and metadata updates.
  • changelog-generator/app/response/[runId]/page.tsx — streaming render logic, section parsing, Streamdown usage, auto-scroll behavior, clipboard interactions, and edge-case/error states.
  • changelog-generator/app/api/generate-changelog/route.ts — input validation, GitHub URL parsing, Trigger.dev invocation and error responses.
  • Streaming definition and cross-boundary data shapes: changelog-generator/trigger/changelog-stream.ts and callers.
  • UI primitives and utilities: components under changelog-generator/components/ui/* and changelog-generator/lib/utils.ts for correctness of variants, ref forwarding, and class merging.
  • Build/configs: package.json, tsconfig.json, next.config.js, tailwind.config.ts, trigger.config.ts, .env.example, and .eslintrc.json for consistency with project code.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Claude changelog generator' accurately describes the main addition: a new changelog generator application built with Claude Agent SDK and Trigger.dev, which is evident from the extensive file additions in the changelog-generator directory.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude-changelog-generator

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (13)
changelog-generator/.gitignore (1)

3-3: Reorganize CLAUDE.md to misc section for consistency.

CLAUDE.md is placed at line 3, ahead of standard Node.js/Next.js ignores and before the "# misc" section comment at line 24. Consider moving it to the misc section (around line 24-27) to maintain consistent .gitignore organization.

🔎 Suggested reorganization:
 # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
 
-CLAUDE.md
-
 postgres-data
 # dependencies
 node_modules

Then add to the misc section:

 # misc
 .DS_Store
 *.pem
+CLAUDE.md
+ARCHITECTURE.md
changelog-generator/.env.example (1)

1-9: LGTM!

Environment variable examples are clear and well-documented with helpful comments indicating where to obtain each credential.

Note: The linter suggests alphabetical ordering (TRIGGER_PROJECT_REF before TRIGGER_SECRET_KEY), but the current grouping by service is logical and readable. This is purely a style preference.

changelog-generator/tsconfig.json (1)

3-3: Consider upgrading the compilation target.

The es5 target is quite outdated and generates larger, less performant code. Modern Next.js projects typically use "ES2017" or newer, which all supported browsers and Node.js versions can handle.

🔎 Apply this diff to update the target:
-    "target": "es5",
+    "target": "ES2017",
changelog-generator/README.md (1)

28-42: Add language specifier to fenced code block.

The code block showing the workflow diagram should have a language specifier for proper rendering and syntax highlighting. Consider using mermaid, text, or plaintext.

🔎 Apply this diff:
-```
+```text
 User enters repo URL + date range
     ↓
changelog-generator/app/api/generate-changelog/route.ts (2)

5-15: Consider handling JSON parse errors explicitly.

If request.json() receives malformed JSON, it throws an error that gets caught by the outer catch block, returning a 500. For better UX, a 400 with a clear message would be more appropriate.

🔎 Suggested improvement:
 export async function POST(request: NextRequest) {
   try {
-    const { repoUrl, startDate, endDate } = await request.json();
+    let body;
+    try {
+      body = await request.json();
+    } catch {
+      return NextResponse.json(
+        { error: "Invalid JSON body" },
+        { status: 400 }
+      );
+    }
+    const { repoUrl, startDate, endDate } = body;

17-22: Date format validation is missing.

The code validates presence of dates but not their format. Invalid date strings will be passed to the task, which may cause unexpected behavior downstream. The task receives these as ISO strings from the frontend, but the API doesn't enforce this.

🔎 Optional: Add basic date validation
     if (!startDate || !endDate) {
       return NextResponse.json(
         { error: "Start and end dates are required" },
         { status: 400 }
       );
     }
+
+    // Validate date format
+    if (isNaN(Date.parse(startDate)) || isNaN(Date.parse(endDate))) {
+      return NextResponse.json(
+        { error: "Invalid date format" },
+        { status: 400 }
+      );
+    }
changelog-generator/app/page.tsx (1)

177-187: Consider adding max attribute to date inputs.

The end date input could benefit from a max attribute to prevent selecting future dates, since generating changelogs for future commits wouldn't be meaningful.

🔎 Optional enhancement:
                   <Input
                     id="endDate"
                     type="date"
                     value={endDate}
                     onChange={(e) => setEndDate(e.target.value)}
                     disabled={isLoading}
+                    max={new Date().toISOString().split("T")[0]}
                   />
changelog-generator/components/ui/alert.tsx (2)

35-44: Minor ref type mismatch.

AlertTitle declares ref type as HTMLParagraphElement but renders an h5 element. This is a common pattern in shadcn/ui components and works functionally, but for type accuracy it should be HTMLHeadingElement.

🔎 Type-accurate version:
 const AlertTitle = React.forwardRef<
-  HTMLParagraphElement,
+  HTMLHeadingElement,
   React.HTMLAttributes<HTMLHeadingElement>
 >(({ className, ...props }, ref) => (

47-56: Minor ref type mismatch.

Similarly, AlertDescription declares ref type as HTMLParagraphElement but renders a div element. Should be HTMLDivElement for accuracy.

🔎 Type-accurate version:
 const AlertDescription = React.forwardRef<
-  HTMLParagraphElement,
+  HTMLDivElement,
   React.HTMLAttributes<HTMLParagraphElement>
 >(({ className, ...props }, ref) => (
changelog-generator/app/response/[runId]/page.tsx (2)

137-145: Clipboard write error is not handled.

navigator.clipboard.writeText can fail (e.g., in non-secure contexts or if permissions are denied). Consider adding error handling to provide user feedback.

🔎 Add error handling:
   const handleCopySection = async (
     section: { title: string; content: string; category?: string },
     index: number
   ) => {
     const mdx = `### ${section.title}\n\n${section.content}`;
-    await navigator.clipboard.writeText(mdx);
-    setCopiedIndex(index);
-    setTimeout(() => setCopiedIndex(null), 2000);
+    try {
+      await navigator.clipboard.writeText(mdx);
+      setCopiedIndex(index);
+      setTimeout(() => setCopiedIndex(null), 2000);
+    } catch (err) {
+      console.error("Failed to copy to clipboard:", err);
+    }
   };

338-344: Unconventional but functional auto-scroll approach.

Using a ref callback to trigger scrollIntoView on every render while streaming works, but it may cause performance issues or janky scrolling on slower devices. Consider using useEffect with a dependency on combinedText.length for more controlled behavior.

changelog-generator/trigger/generate-changelog.ts (2)

138-145: Reduce code duplication in repository name parsing.

The .replace(".git", "") operation is called twice (lines 142 and 145). Consider extracting the cleaned repo name once.

🔎 Apply this diff to eliminate duplication:
     // Parse repo URL
     const match = repoUrl.match(/github\.com\/([^/]+)\/([^/]+)/);
     if (!match) throw new Error("Invalid GitHub repository URL");
 
-    const [, owner, repo] = match;
-    const repoName = `${owner}/${repo.replace(".git", "")}`;
+    const [, owner, repoRaw] = match;
+    const repo = repoRaw.replace(".git", "");
+    const repoName = `${owner}/${repo}`;
     metadata.set("repository", repoName);
 
-    const githubServer = createGitHubTools(owner, repo.replace(".git", ""));
+    const githubServer = createGitHubTools(owner, repo);

252-267: Consider making the Claude model configurable.

The model is hardcoded to "claude-sonnet-4-20250514", which is a valid snapshot but now outdated. Claude Sonnet 4.5 is the current available model, and making the model name configurable via environment variable or parameter would improve flexibility for testing and adapting to future model updates.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5bacf16 and 2357346.

⛔ Files ignored due to path filters (1)
  • changelog-generator/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (24)
  • .gitignore (1 hunks)
  • changelog-generator/.env.example (1 hunks)
  • changelog-generator/.eslintrc.json (1 hunks)
  • changelog-generator/.gitignore (1 hunks)
  • changelog-generator/README.md (1 hunks)
  • changelog-generator/app/api/generate-changelog/route.ts (1 hunks)
  • changelog-generator/app/globals.css (1 hunks)
  • changelog-generator/app/layout.tsx (1 hunks)
  • changelog-generator/app/page.tsx (1 hunks)
  • changelog-generator/app/response/[runId]/page.tsx (1 hunks)
  • changelog-generator/components/ui/alert.tsx (1 hunks)
  • changelog-generator/components/ui/button.tsx (1 hunks)
  • changelog-generator/components/ui/card.tsx (1 hunks)
  • changelog-generator/components/ui/input.tsx (1 hunks)
  • changelog-generator/lib/utils.ts (1 hunks)
  • changelog-generator/next-env.d.ts (1 hunks)
  • changelog-generator/next.config.js (1 hunks)
  • changelog-generator/package.json (1 hunks)
  • changelog-generator/postcss.config.js (1 hunks)
  • changelog-generator/tailwind.config.ts (1 hunks)
  • changelog-generator/trigger.config.ts (1 hunks)
  • changelog-generator/trigger/changelog-stream.ts (1 hunks)
  • changelog-generator/trigger/generate-changelog.ts (1 hunks)
  • changelog-generator/tsconfig.json (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (6)
changelog-generator/components/ui/button.tsx (1)
changelog-generator/lib/utils.ts (1)
  • cn (4-6)
changelog-generator/components/ui/card.tsx (1)
changelog-generator/lib/utils.ts (1)
  • cn (4-6)
changelog-generator/components/ui/input.tsx (1)
changelog-generator/lib/utils.ts (1)
  • cn (4-6)
changelog-generator/trigger/generate-changelog.ts (2)
changelog-generator/app/layout.tsx (1)
  • metadata (7-11)
changelog-generator/trigger/changelog-stream.ts (1)
  • changelogStream (3-5)
changelog-generator/components/ui/alert.tsx (1)
changelog-generator/lib/utils.ts (1)
  • cn (4-6)
changelog-generator/app/api/generate-changelog/route.ts (1)
changelog-generator/trigger/generate-changelog.ts (1)
  • generateChangelog (129-330)
🪛 dotenv-linter (4.0.0)
changelog-generator/.env.example

[warning] 3-3: [UnorderedKey] The TRIGGER_PROJECT_REF key should go before the TRIGGER_SECRET_KEY key

(UnorderedKey)

🪛 LanguageTool
changelog-generator/README.md

[uncategorized] ~22-~22: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...ll list_commits and get_commit_diff on demand - Private repo support – Optional G...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

🪛 markdownlint-cli2 (0.18.1)
changelog-generator/README.md

28-28: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (25)
.gitignore (1)

52-54: ✓ Appropriate entries for ignoring generated documentation.

The additions to track generated CLAUDE.md and ARCHITECTURE.md artifacts under the "# Misc" section are well-placed and aligned with the new changelog-generator project's Claude Agent integration.

changelog-generator/.gitignore (1)

1-62: Verify ARCHITECTURE.md entry in changelog-generator/.gitignore.

The AI-generated summary mentions that both CLAUDE.md and ARCHITECTURE.md were added to the misc section, but only CLAUDE.md is visible in the provided code at line 3. Please confirm whether ARCHITECTURE.md should also be included (to match the root .gitignore pattern).

changelog-generator/.eslintrc.json (1)

1-3: LGTM!

Standard Next.js ESLint configuration using the Core Web Vitals preset.

changelog-generator/next-env.d.ts (1)

1-5: LGTM!

Auto-generated Next.js TypeScript declaration file with standard reference directives.

changelog-generator/trigger/changelog-stream.ts (1)

1-5: LGTM!

Clean stream definition for changelog output using Trigger.dev SDK. The stream ID is descriptive and the string type is appropriate for changelog content.

changelog-generator/lib/utils.ts (1)

1-6: LGTM!

Standard utility function for composing Tailwind classes. Correctly combines clsx for conditional classes with twMerge to handle Tailwind class conflicts.

changelog-generator/postcss.config.js (1)

1-6: LGTM!

Standard PostCSS configuration for Tailwind CSS with Autoprefixer. Empty plugin objects use default configurations, which is appropriate for most projects.

changelog-generator/components/ui/input.tsx (1)

7-22: LGTM!

Well-structured Input component following React best practices with proper ref forwarding and displayName. The composed className string provides comprehensive styling while allowing override via the className prop.

changelog-generator/app/globals.css (1)

1-83: LGTM! Well-structured theme implementation.

The GitHub dark theme with CSS variables provides a solid foundation for consistent styling across the application. The custom styling for inline code and date inputs is a nice touch.

changelog-generator/tailwind.config.ts (1)

1-69: LGTM! Comprehensive Tailwind configuration.

The configuration properly extends the theme with custom colors, border radii, and gradients. The inclusion of streamdown in the content paths is appropriate for ensuring its classes are scanned.

changelog-generator/app/layout.tsx (1)

1-23: LGTM! Clean Next.js layout implementation.

The layout properly imports global styles, configures the Inter font, and sets appropriate metadata. The structure follows Next.js App Router best practices.

changelog-generator/components/ui/card.tsx (1)

1-86: Well-structured Card component suite.

The Card primitives are cleanly implemented with proper ref forwarding and composable design. Good use of the cn utility for className composition.

changelog-generator/components/ui/button.tsx (1)

1-56: LGTM! Excellent Button component implementation.

The use of class-variance-authority for variant management and Radix Slot for polymorphic behavior demonstrates solid architectural choices. The component is properly typed and follows React best practices with forwardRef.

changelog-generator/app/api/generate-changelog/route.ts (1)

33-42: LGTM!

The Trigger.dev SDK usage is correct. The task trigger returns the run handle with id and publicAccessToken, which are properly extracted and returned to the client.

changelog-generator/app/page.tsx (2)

55-65: Good URL validation approach.

The validation correctly verifies the hostname is github.com and that the path has at least owner and repository segments. Using the URL constructor handles edge cases well.


93-123: Form submission logic looks correct.

The error handling, API call, and navigation flow are well-structured. The date conversion to ISO format before sending and the query parameter construction for the redirect are handled properly.

Note: isLoading is not reset on success, but since router.push navigates away, this is not an issue.

changelog-generator/trigger.config.ts (1)

3-22: LGTM!

The configuration is well-structured:

  • Externalizing @anthropic-ai/claude-agent-sdk is correct for the build process
  • The 5-minute timeout and retry settings are reasonable for an AI agent task
  • Machine size small-2x provides adequate resources for the Agent SDK

One minor note: the non-null assertion on TRIGGER_PROJECT_REF (line 4) will throw a runtime error if the environment variable is missing. Ensure this is documented in the project's setup instructions.

changelog-generator/components/ui/alert.tsx (1)

6-33: LGTM!

The Alert component follows the standard shadcn/ui pattern with proper CVA variant configuration, accessibility role, and ref forwarding. The variant styles are well-defined for both default and destructive states.

changelog-generator/app/response/[runId]/page.tsx (2)

34-79: Markdown parsing logic is well-structured.

The parseChangelogSections function correctly handles the hierarchical markdown structure with ## for categories and ### for section titles. The final filter for non-empty content is a good safeguard.


272-335: Streaming UI implementation looks good.

The changelog cards with Streamdown integration handle the streaming animation correctly by only animating the last section (i === sections.length - 1). The fallback "thinking text" display before sections appear is a nice UX touch.

changelog-generator/trigger/generate-changelog.ts (5)

74-124: Good error handling and patch truncation.

The error handling appropriately catches failures and returns them as text content rather than throwing. The patch truncation at 2000 characters is a reasonable safeguard against token limits for large diffs.


147-234: Well-structured prompt with comprehensive instructions.

The prompt provides clear categorization guidelines and detailed examples. The workflow section effectively addresses the previous feedback about recognizing which components got updated by instructing the agent to categorize commits into Features, Improvements, Breaking Changes, and Bug Fixes.


237-249: LGTM!

The async generator correctly implements the required format for MCP servers.


321-329: LGTM!

The completion logic properly waits for all async operations, updates metadata, and returns the expected result structure.


47-52: Add null safety for commit date parsing.

Line 49 uses optional chaining but still calls .split("T")[0] on a potentially undefined date value. While the fallback empty string prevents a crash, it would be safer to handle this more explicitly.

🔎 Apply this diff for safer date handling:
             for (const commit of data) {
               const sha = commit.sha.substring(0, 7);
-              const date = commit.commit.author?.date?.split("T")[0] || "";
+              const date = commit.commit.author?.date 
+                ? commit.commit.author.date.split("T")[0] 
+                : "";
               const author = commit.commit.author?.name || "Unknown";
               const message = commit.commit.message.split("\n")[0];
               commits.push(`[${sha}] ${date} (${author}): ${message}`);

Likely an incorrect or invalid review comment.

Comment on lines +177 to +182
return (
<div
className="min-h-screen bg-background"
onScroll={handleScroll}
onWheel={handleScroll}
>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Scroll event handlers may not fire as expected.

The onScroll and onWheel events are attached to the outer div, but since the page itself scrolls (not an inner scrollable container), these events may not fire. The scroll happens on document or window, not on this div.

🔎 Use window event listeners instead:
+import { useEffect } from "react";
+
 export default function ResponsePage() {
   // ... existing code ...
+
+  useEffect(() => {
+    window.addEventListener("scroll", handleScroll);
+    return () => window.removeEventListener("scroll", handleScroll);
+  }, []);

   return (
     <div
       className="min-h-screen bg-background"
-      onScroll={handleScroll}
-      onWheel={handleScroll}
     >

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In changelog-generator/app/response/[runId]/page.tsx around lines 177–182, the
onScroll and onWheel props on the outer div won't reliably fire for page-level
scrolling; remove those props and instead add window-level listeners inside a
useEffect: attach window.addEventListener('scroll', handleScroll, { passive:
true }) and window.addEventListener('wheel', handleScroll, { passive: true })
(or separate handlers if needed), ensure handleScroll is stable (wrap in
useCallback or read via ref) and clean up both listeners in the effect's return
to avoid leaks.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 540272a and 53ea8c4.

📒 Files selected for processing (2)
  • changelog-generator/README.md (1 hunks)
  • claude-agent-github-wiki/README.md (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • claude-agent-github-wiki/README.md
🧰 Additional context used
🪛 LanguageTool
changelog-generator/README.md

[grammar] ~1-~1: Ensure spelling is correct
Context: # Changelog generator using theClaude Agent SDK and Trigger.dev An AI agent ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 53ea8c4 and 9e634a2.

📒 Files selected for processing (3)
  • changelog-generator/README.md (1 hunks)
  • changelog-generator/next.config.js (1 hunks)
  • changelog-generator/package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • changelog-generator/README.md
🔇 Additional comments (1)
changelog-generator/next.config.js (1)

1-6: LGTM! Previous concerns addressed.

The configuration now correctly enables React Strict Mode and doesn't bypass ESLint during builds. Both issues flagged in previous reviews have been resolved. The minimal configuration follows Next.js best practices.

@D-K-P D-K-P merged commit 4f95cd6 into main Dec 19, 2025
1 of 2 checks passed
@D-K-P D-K-P deleted the claude-changelog-generator branch December 19, 2025 14:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants