nyxcore-systems
7 min read

Bringing GitHub PR Reviews In-House: A Deep Dive into nyxCore's New AI-Powered Workflow

We just shipped a major feature for nyxCore: a fully integrated GitHub PR review workflow, complete with a diff viewer, intelligent AI analysis, and streamlined submission, all within our project pages. Here's how we built it.

GitHubPR ReviewAItRPCNext.jsDeveloper ProductivityCode Review

It's always a good feeling to hit a significant development milestone, especially when it fundamentally changes how you interact with your core tools. This past week, we wrapped up a major initiative for nyxCore: a complete, in-house GitHub Pull Request (PR) review workflow, directly accessible from our project pages.

Our goal was ambitious: allow developers to list PRs, view diffs, leverage AI for initial analysis, submit comments and reviews, and even merge PRs, all without leaving the nyxCore environment. After a focused sprint, I'm thrilled to report that all eight core tasks are complete, committed, backed by 293 passing tests, and typecheck clean. Let's dive into how we built it.

The Journey Begins: Laying the Foundation

Any deep integration starts with connecting to the external service. For us, that meant the GitHub API.

GitHub Connector: The Bridge to Our Repos

The first order of business was to establish a robust connection to GitHub. We extended our src/server/services/github-connector.ts with seven new functions, acting as our dedicated bridge to GitHub's PR universe:

  • listPullRequests: To fetch all relevant PRs for a project.
  • getPullRequest: To retrieve details for a specific PR.
  • getPullRequestFiles: Essential for the diff viewer.
  • getPullRequestComments: To display existing review discussions.
  • createReviewComment: To add new comments to the diff.
  • submitReview: To formally approve, request changes, or comment on a PR.
  • mergePullRequest: The ultimate action, bringing changes into main.

These functions, committed across f339de6 and a4ed2f8, form the backbone of our integration.

tRPC API: Our Internal Gateway

With the connector in place, we needed a secure, type-safe way for our frontend to interact with these new capabilities. This is where tRPC shines. We created src/server/trpc/routers/reviews.ts with a createReviewsRouter() containing eight procedures, mirroring our connector functions and adding the AI review capability:

  • list, get, getFiles, getComments: For data retrieval.
  • addComment, submitReview, merge: For actions.
  • aiReview: The exciting part, which we'll discuss shortly.

This reviews sub-router was then mounted within src/server/trpc/routers/projects.ts, making it accessible via trpc.projects.reviews.*. This structured approach keeps our API organized and predictable.

Bringing it to Life: The Frontend Experience

A powerful backend is nothing without an intuitive user interface.

The New "Reviews" Tab

We integrated a new "Reviews" tab (#15) into our project page sidebar, nestled within the "Quality" group in src/app/(dashboard)/dashboard/projects/[id]/page.tsx. This tab houses our ReviewsTab inline component, providing:

  • A clear list of PRs.
  • Filters (all, assigned, nyxCore-owned) for easy navigation.
  • Thoughtful loading and empty states for a smooth user experience.

The Review Detail Page: Diff Viewer & Actions

The core of the review experience lives at src/app/(dashboard)/dashboard/projects/[id]/reviews/[prNumber]/page.tsx. This page features a two-column layout:

  • Left Column: A custom DiffViewer component, powered by a DiffFileTree, allowing developers to navigate changes file by file.
  • Right Column: A dedicated actions panel for adding comments, submitting reviews, and merging.

We built five specialized review components in src/components/reviews/ (PRListCard, PRFilters, DiffViewer, DiffFileTree, AIAnnotation) to ensure a consistent and powerful UI. A minor but necessary detail was also creating src/components/ui/textarea.tsx, which was surprisingly missing from our project's UI library.

The AI Edge: Intelligent Code Review

This is where the nyxCore workflow truly differentiates itself. We wanted to leverage the power of Large Language Models (LLMs) to provide an initial, automated layer of code review.

The pr-review-service and LLM Integration

Our src/server/services/pr-review-service.ts is the brain behind the AI review. It contains:

  • buildReviewPrompt(): Crafts a detailed prompt for the LLM, including the PR diff, context, and review guidelines.
  • parseReviewSuggestions(): Interprets the LLM's raw output into structured, actionable suggestions.

"Review with AI" Button

The UI integrates an "Review with AI" button. Clicking this triggers an LLM analysis of the current PR diff. The results are then displayed as severity-colored annotation cards directly within the review detail page, highlighting potential issues or areas for improvement. This provides a valuable first pass, helping reviewers focus their efforts.

Currently, the LLM provider is hardcoded to "google" in reviews.ts:aiReview, using resolveProvider("google", tenantId, userId). This is a clear candidate for future configurability.

Lessons Learned: Navigating the Trenches

No significant feature ships without its share of "gotchas." These moments are invaluable for learning and improving our development process.

1. GitHub API Nuance: The commit_id Requirement

The Challenge: When implementing createReviewComment, my initial attempt omitted a commit_id parameter. I assumed the API would infer the latest commit for the PR.

The Reality: GitHub's API is explicit. For PR review comments, it requires a commit_id to anchor the comment to a specific version of the code. Without it, the API would have returned a 422 Unprocessable Entity error at runtime.

The Fix: We updated createReviewComment to accept commitSha: string and pass it as commit_id in the request body. Our tRPC addComment procedure's Zod schema also now includes commitSha.

typescript
// Simplified example of the fix
// In github-connector.ts
async function createReviewComment(
  // ... other params
  commitSha: string,
  path: string,
  position: number,
  body: string
) {
  // ...
  await octokit.pulls.createReviewComment({
    // ...
    commit_id: commitSha, // <--- This was the missing piece!
    path,
    position,
    body,
  });
}

Takeaway: Always double-check API documentation for required parameters, especially for actions that modify resources. Even seemingly optional parameters can be critical for specific contexts. When calling addComment, remember to pass the PR's head.sha as commitSha.

2. UI Component Library Quirks: Custom Badge Variants

The Challenge: While styling the review components, I naturally reached for common shadcn/ui Badge variants like outline and secondary.

The Reality: Our project's Badge component has custom variants (default, accent, success, warning, danger) that diverge from shadcn/ui defaults. Using outline or secondary resulted in unstyled components.

The Fix: A quick check of our local src/components/ui/badge.tsx revealed the custom variants. We switched to variant="default" and variant="accent" for the desired visual effect.

Takeaway: Even when using popular UI libraries, be aware of any local customizations. Always verify the available props and variants in your project's specific implementation to avoid frustrating styling issues.

Under the Hood: Key Details & Quality Assurance

  • Branch: All 9 commits for this feature landed directly on main, testament to our confidence in the implementation.
  • Latest Commit: 220dc76 (a documentation update).
  • Router Path: trpc.projects.reviews.*
  • Review Detail URL: /dashboard/projects/[id]/reviews/[prNumber]?owner=X&repo=Y — we pass owner and repo as query parameters for seamless navigation from the PR list to the detail page.
  • Testing: We added 17 new tests across 3 test files (11 for the connector, 6 for the service, 1 for the router export), ensuring critical paths are covered.
  • Documentation: A design doc (docs/plans/2026-03-10-pr-review-workflow-design.md) and an implementation plan (docs/plans/2026-03-10-pr-review-workflow-implementation.md) were written, capturing our thought process and decisions.

What's Next for nyxCore Reviews

Shipping this feature is just the beginning. Our immediate next steps include:

  1. Deployment & Smoke Testing: Getting this into production and thoroughly testing the Reviews tab on projects with linked repos.
  2. AI Review Verification: Rigorously testing the AI review with diverse PR diffs to ensure the Google LLM provider works as expected and provides valuable insights.
  3. Configurable AI Provider: Making the LLM provider for AI review configurable rather than hardcoded.
  4. "Deep Review" Mode: Implementing a more advanced review mode that triggers our full workflow engine for comprehensive analysis.
  5. Mobile Responsiveness: Ensuring the two-column review detail page gracefully stacks on mobile devices.
  6. Inline Comment Creation: Enhancing the diff viewer to allow direct comment creation by clicking on specific lines.

This new PR review workflow marks a significant step forward in nyxCore's mission to streamline developer productivity. By bringing these critical functions in-house, we're not just saving clicks; we're creating a more integrated, intelligent, and efficient development experience.

json
{
  "thingsDone": [
    "Implemented full GitHub PR Review Workflow (list, diff, AI review, submit, merge)",
    "Created 7 GitHub connector functions for PR interactions",
    "Developed tRPC router with 8 procedures for reviews",
    "Added 'Reviews' tab to project pages with PR filters",
    "Built two-column review detail page with custom diff viewer",
    "Created 5 dedicated review UI components",
    "Integrated AI review with LLM analysis and annotation cards",
    "Wrote design and implementation documentation",
    "Added 17 new tests for connector, service, and router"
  ],
  "pains": [
    "GitHub API requires `commit_id` for PR review comments, leading to a 422 error without it.",
    "Project's custom Badge component variants (`default`, `accent`) differ from `shadcn/ui` defaults (`outline`, `secondary`)."
  ],
  "successes": [
    "All 8 core tasks completed as planned",
    "293 tests passing, typecheck clean",
    "Robust GitHub API integration",
    "Intuitive frontend UI for PR reviews",
    "Successful integration of AI for code analysis",
    "Comprehensive documentation and testing"
  ],
  "techStack": [
    "GitHub API",
    "tRPC",
    "Next.js",
    "React",
    "TypeScript",
    "LLM (Google)",
    "Zod"
  ]
}