-
Notifications
You must be signed in to change notification settings - Fork 17
Claude changelog generator #88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughAdds 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:
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this 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_modulesThen add to the misc section:
# misc .DS_Store *.pem +CLAUDE.md +ARCHITECTURE.mdchangelog-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
es5target 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, orplaintext.🔎 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 addingmaxattribute to date inputs.The end date input could benefit from a
maxattribute 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.
AlertTitledeclares ref type asHTMLParagraphElementbut renders anh5element. This is a common pattern in shadcn/ui components and works functionally, but for type accuracy it should beHTMLHeadingElement.🔎 Type-accurate version:
const AlertTitle = React.forwardRef< - HTMLParagraphElement, + HTMLHeadingElement, React.HTMLAttributes<HTMLHeadingElement> >(({ className, ...props }, ref) => (
47-56: Minor ref type mismatch.Similarly,
AlertDescriptiondeclares ref type asHTMLParagraphElementbut renders adivelement. Should beHTMLDivElementfor 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.writeTextcan 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
scrollIntoViewon every render while streaming works, but it may cause performance issues or janky scrolling on slower devices. Consider usinguseEffectwith a dependency oncombinedText.lengthfor 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
⛔ Files ignored due to path filters (1)
changelog-generator/package-lock.jsonis 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
clsxfor conditional classes withtwMergeto 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
cnutility 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
idandpublicAccessToken, 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.comand 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:
isLoadingis not reset on success, but sincerouter.pushnavigates 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-sdkis correct for the build process- The 5-minute timeout and retry settings are reasonable for an AI agent task
- Machine size
small-2xprovides adequate resources for the Agent SDKOne 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
parseChangelogSectionsfunction 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.
| return ( | ||
| <div | ||
| className="min-h-screen bg-background" | ||
| onScroll={handleScroll} | ||
| onWheel={handleScroll} | ||
| > |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this 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
📒 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)
There was a problem hiding this 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
📒 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.
Summary by CodeRabbit
New Features
UI
Privacy
Chores
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.