Skip to content

feat: Add github-auto-fix-agent AgentKit#87

Open
RitoG09 wants to merge 4 commits intoLamatic:mainfrom
RitoG09:main
Open

feat: Add github-auto-fix-agent AgentKit#87
RitoG09 wants to merge 4 commits intoLamatic:mainfrom
RitoG09:main

Conversation

@RitoG09
Copy link

@RitoG09 RitoG09 commented Mar 22, 2026

What This Kit Does

This kit automatically analyzes GitHub issues and generates intelligent code fixes along with ready-to-use pull request metadata.

It solves the problem of manually debugging issues by:

  • Understanding the issue context
  • Identifying the root cause
  • Generating minimal, targeted code fixes
  • Preparing PR title, description, and branch details

Instead of spending time manually fixing minimal bugs, developers can review AI-suggested changes and create PRs in seconds.

Providers & Prerequisites

Providers

  • GitHub API (for fetching issues and creating pull requests)
  • LLM provider: tested with Groq LLM Connect via Lamatic Studio.

Prerequisites

  • GitHub Personal Access Token (classic) with repo permissions
  • Node.js
  • Lamatic account (free trial)

Required Environment Variables

AGENTIC_GENERATE_CONTENT=your_flow_id
LAMATIC_API_URL=your_project_endpoint
LAMATIC_PROJECT_ID=your_project_id
LAMATIC_API_KEY=your_api_key
GITHUB_TOKEN=your_github_token

How to Run Locally

  1. cd kits/agentic/github-auto-fix-agent
  2. npm install
  3. cp .env.example .env and fill in values
  4. npm run dev
  5. Open http://localhost:3000/, paste a GitHub Issue URL, and Target File Path -> Fix Issue & Create PR

Live Preview

https://agent-kit-beta.vercel.app/

Lamatic Flow

Flow ID: b232a0d5-1bbd-44dd-96a1-33a3b98615b8

Checklist

  • Kit runs locally with npm run dev
  • .env.example has no secrets, only placeholders
  • README.md documents setup and usage
  • Folder structure follows kits/<category>/<kit-name>/
  • config.json is present and valid
  • All flows exported in flows/ folder
  • Vercel deployment works
  • Live preview URL works end-to-end

Overview

Adds a new "github-auto-fix-agent" kit that automates GitHub issue analysis and code fix generation with PR creation.

Key Additions

Core Functionality

  • Lamatic flow (github-issue-solver) with 7 nodes that extracts issue details, analyzes root causes, generates code fixes, and prepares PR metadata
  • Backend orchestration (actions/orchestrate.ts) that coordinates Lamatic flow execution and GitHub API interactions (issue fetching, branch creation, file updates, PR creation)
  • API endpoint (app/api/fix/route.ts) accepting GitHub issue URLs and optional file paths

Frontend (Next.js)

  • Main page with form for GitHub issue URL and optional target file path
  • Success/error result displays with animated transitions
  • Header, footer, and background decoration components
  • Yellow-themed design system with custom CSS properties and Tailwind integration

Configuration & Setup

  • Environment example (.env.example) with required variables: GITHUB_AUTO_FIX, LAMATIC_API_URL, LAMATIC_API_KEY, LAMATIC_PROJECT_ID, GITHUB_TOKEN
  • Next.js, TypeScript, ESLint, and PostCSS configuration
  • .gitignore for development artifacts
  • Comprehensive README with setup instructions and workflow diagram
  • Lamatic flow metadata and input configuration for LLM nodes

Dependencies

  • Next.js 16.2.1, React 19.2.4, Framer Motion for animations, Lucide React for icons, Lamatic SDK

File Structure

All files located under kits/agentic/github-auto-fix-agent/ with flows in flows/github-issue-solver/

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 22, 2026

📝 Walkthrough

Walkthrough

Adds a new GitHub Auto Fix Agent kit: a Next.js app, Lamatic flow configs, Lamatic client, server actions to run flows and create PRs, UI components/pages, API routes, and project/tooling configuration files.

Changes

Cohort / File(s) Summary
Project config & tooling
kits/agentic/github-auto-fix-agent/package.json, kits/agentic/github-auto-fix-agent/tsconfig.json, kits/agentic/github-auto-fix-agent/next.config.ts, kits/agentic/github-auto-fix-agent/postcss.config.mjs, kits/agentic/github-auto-fix-agent/eslint.config.mjs
New project manifests and build/lint/postcss/TypeScript configuration for the kit.
Env & ignores
kits/agentic/github-auto-fix-agent/.env.example, kits/agentic/github-auto-fix-agent/.gitignore
Added environment example with Lamatic/GitHub variables and a .gitignore for build/dev artifacts.
Lamatic client & flows
kits/agentic/github-auto-fix-agent/lib/lamatic-client.ts, kits/agentic/github-auto-fix-agent/flows/github-issue-solver/...
kits/agentic/github-auto-fix-agent/flows/github-issue-solver/config.json, .../inputs.json, .../meta.json, .../README.md
Lamatic client initializer (env-validated) and a complete github-issue-solver flow with node configs, inputs, metadata, and documentation.
Server orchestration & API routes
kits/agentic/github-auto-fix-agent/actions/orchestrate.ts, kits/agentic/github-auto-fix-agent/app/api/fix/route.ts, kits/agentic/github-auto-fix-agent/app/api/create-pr/route.ts
Added orchestration functions: handleFixIssue (executes Lamatic flow) and handleCreatePR (GitHub branch/file update + PR creation). Exposed via POST API routes with validation and error handling.
Next.js app layout & styles
kits/agentic/github-auto-fix-agent/app/layout.tsx, kits/agentic/github-auto-fix-agent/app/globals.css
Root layout with font setup and exported metadata; global yellow-themed CSS and Tailwind theme variables.
Pages & client logic
kits/agentic/github-auto-fix-agent/app/page.tsx
Home page with form state, POST to /api/fix, and conditional rendering of result components.
UI components
kits/agentic/github-auto-fix-agent/components/Header.tsx, .../IssueForm.tsx, .../SuccessResult.tsx, .../ErrorResult.tsx, .../Footer.tsx, .../BackgroundDecoration.tsx
New client components for the hero, form, success/error result panels (including PR creation flow), footer, and decorative background.
Docs
kits/agentic/github-auto-fix-agent/README.md
Project README describing the agent, workflow, setup, and local run instructions.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Frontend as Next.js Frontend
    participant API as /api/fix
    participant Orchestrator as handleFixIssue
    participant Lamatic as Lamatic Flow Engine
    participant GitHub as GitHub REST API

    User->>Frontend: submit issue URL (+ optional file path)
    Frontend->>API: POST { issue_url, file_path }
    API->>Orchestrator: handleFixIssue(input)
    Orchestrator->>Lamatic: executeFlow(flowId, input)
    activate Lamatic
    Lamatic->>GitHub: (optional) Extract repo/issue, GET issue details
    Lamatic->>Lamatic: LLMs analyze issue, generate fix, produce PR metadata
    Lamatic-->>Orchestrator: { analysis, fix, pr }
    deactivate Lamatic
    Orchestrator-->>Frontend: return analysis & fix (via API response)
    Frontend->>Frontend: render SuccessResult with Create PR action
    Frontend->>API: POST /api/create-pr with fix + pr metadata
    API->>Orchestrator: handleCreatePR(input)
    Orchestrator->>GitHub: GET default branch, create ref, GET file SHA, PUT updated file, POST pull request
    GitHub-->>Orchestrator: PR URL
    Orchestrator-->>API: { success: true, pr_url }
    API-->>Frontend: PR creation result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Fix : Config Removal #42: Changes Lamatic configuration handling (affects lamatic-client env schema and how the client is initialized).
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: Add github-auto-fix-agent AgentKit' directly and clearly describes the main change: addition of a new AgentKit. It is concise, specific, and clearly conveys the primary change to a teammate scanning history.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Tip

CodeRabbit can enforce grammar and style rules using `languagetool`.

Configure the reviews.tools.languagetool setting to enable/disable rules and categories. Refer to the LanguageTool Community to learn more.

Copy link
Contributor

@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: 13

🧹 Nitpick comments (4)
kits/agentic/github-auto-fix-agent/flows/github-issue-solver/meta.json (1)

3-8: Populate flow metadata fields for discoverability and maintainability.

Leaving description, testInput, and URLs empty reduces clarity for users consuming this flow package.

Suggested improvement
 {
   "name": "github-issue-solver",
-  "description": "",
-  "tags": [],
-  "testInput": "",
-  "githubUrl": "",
-  "documentationUrl": "",
-  "deployUrl": ""
+  "description": "Analyzes a GitHub issue, generates a minimal code-fix proposal, and prepares pull request metadata.",
+  "tags": ["github", "automation", "issue-triage", "code-fix"],
+  "testInput": "{\"issueUrl\":\"https://github.com/owner/repo/issues/123\"}",
+  "githubUrl": "https://github.com/Lamatic/AgentKit/tree/main/kits/agentic/github-auto-fix-agent",
+  "documentationUrl": "https://docs.lamatic.ai",
+  "deployUrl": "https://agent-kit-beta.vercel.app/"
 }
kits/agentic/github-auto-fix-agent/lib/lamatic-client.ts (1)

3-9: Improve env validation error specificity.

The fail-fast check is good, but the current message doesn’t say which variables are missing. Returning exact missing keys will reduce setup/debug time.

♻️ Proposed refinement
-if (
-  !process.env.LAMATIC_API_URL ||
-  !process.env.LAMATIC_PROJECT_ID ||
-  !process.env.LAMATIC_API_KEY
-) {
-  throw new Error("Missing Lamatic environment variables");
-}
+const requiredLamaticEnv = [
+  "LAMATIC_API_URL",
+  "LAMATIC_PROJECT_ID",
+  "LAMATIC_API_KEY",
+] as const;
+
+const missingLamaticEnv = requiredLamaticEnv.filter(
+  (key) => !process.env[key],
+);
+
+if (missingLamaticEnv.length > 0) {
+  throw new Error(
+    `Missing Lamatic environment variables: ${missingLamaticEnv.join(", ")}`,
+  );
+}
kits/agentic/github-auto-fix-agent/app/page.tsx (2)

36-49: Error details are discarded, making debugging harder.

The API error text is logged but then replaced with a generic "API failed" error. The actual error message from the server is lost when displayed to the user. Consider preserving the server error message for better UX.

♻️ Proposed fix to preserve error details
       if (!res.ok) {
         const text = await res.text();
         console.error("API ERROR:", text);
-        throw new Error("API failed");
+        let errorMessage = "API request failed";
+        try {
+          const errorJson = JSON.parse(text);
+          errorMessage = errorJson.error || errorMessage;
+        } catch {
+          errorMessage = text || errorMessage;
+        }
+        throw new Error(errorMessage);
       }

       const data = await res.json();
       setResult(data);
     } catch (err) {
       console.error(err);
       setResult({
         success: false,
-        error: "An unexpected error occurred while processing the request.",
+        error: err instanceof Error ? err.message : "An unexpected error occurred.",
       });
     }

16-16: Consider adding proper typing for result state.

Using any type loses TypeScript benefits. Define an interface matching the expected API response structure.

♻️ Proposed type definition
+interface FixResult {
+  success: boolean;
+  pr_url?: string;
+  analysis?: { summary?: string; root_cause?: string };
+  fix?: { explanation?: string; diff?: string };
+  error?: string;
+}
+
 export default function Home() {
   const [issueUrl, setIssueUrl] = useState("");
   const [filePath, setFilePath] = useState("");
   const [loading, setLoading] = useState(false);
-  const [result, setResult] = useState<any>(null);
+  const [result, setResult] = useState<FixResult | null>(null);

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a9f20308-5534-48be-b087-c8578c48ef9a

📥 Commits

Reviewing files that changed from the base of the PR and between e1ceb47 and f953c51.

⛔ Files ignored due to path filters (8)
  • kits/agentic/github-auto-fix-agent/app/favicon.ico is excluded by !**/*.ico
  • kits/agentic/github-auto-fix-agent/package-lock.json is excluded by !**/package-lock.json
  • kits/agentic/github-auto-fix-agent/public/file.svg is excluded by !**/*.svg
  • kits/agentic/github-auto-fix-agent/public/flows.png is excluded by !**/*.png
  • kits/agentic/github-auto-fix-agent/public/globe.svg is excluded by !**/*.svg
  • kits/agentic/github-auto-fix-agent/public/next.svg is excluded by !**/*.svg
  • kits/agentic/github-auto-fix-agent/public/vercel.svg is excluded by !**/*.svg
  • kits/agentic/github-auto-fix-agent/public/window.svg is excluded by !**/*.svg
📒 Files selected for processing (24)
  • kits/agentic/github-auto-fix-agent/.env.example
  • kits/agentic/github-auto-fix-agent/.gitignore
  • kits/agentic/github-auto-fix-agent/README.md
  • kits/agentic/github-auto-fix-agent/actions/orchestrate.ts
  • kits/agentic/github-auto-fix-agent/app/api/fix/route.ts
  • kits/agentic/github-auto-fix-agent/app/globals.css
  • kits/agentic/github-auto-fix-agent/app/layout.tsx
  • kits/agentic/github-auto-fix-agent/app/page.tsx
  • kits/agentic/github-auto-fix-agent/components/BackgroundDecoration.tsx
  • kits/agentic/github-auto-fix-agent/components/ErrorResult.tsx
  • kits/agentic/github-auto-fix-agent/components/Footer.tsx
  • kits/agentic/github-auto-fix-agent/components/Header.tsx
  • kits/agentic/github-auto-fix-agent/components/IssueForm.tsx
  • kits/agentic/github-auto-fix-agent/components/SuccessResult.tsx
  • kits/agentic/github-auto-fix-agent/eslint.config.mjs
  • kits/agentic/github-auto-fix-agent/flows/github-issue-solver/README.md
  • kits/agentic/github-auto-fix-agent/flows/github-issue-solver/config.json
  • kits/agentic/github-auto-fix-agent/flows/github-issue-solver/inputs.json
  • kits/agentic/github-auto-fix-agent/flows/github-issue-solver/meta.json
  • kits/agentic/github-auto-fix-agent/lib/lamatic-client.ts
  • kits/agentic/github-auto-fix-agent/next.config.ts
  • kits/agentic/github-auto-fix-agent/package.json
  • kits/agentic/github-auto-fix-agent/postcss.config.mjs
  • kits/agentic/github-auto-fix-agent/tsconfig.json

Comment on lines +1 to +5
GITHUB_AUTO_FIX = "YOUR_FLOW_ID"
LAMATIC_API_URL = "YOUR_API_ENDPOINT"
LAMATIC_API_KEY = "YOUR_API_KEY"
LAMATIC_PROJECT_ID = "YOUR_PROJECT_ID"
GITHUB_TOKEN = "YOUR_GITHUB_TOKEN" No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Normalize .env syntax to avoid parser/tooling inconsistencies.

Lines 1–5 use spaces around =, which is fragile across dotenv/shell workflows. Use canonical KEY=value format.

Suggested fix
-GITHUB_AUTO_FIX = "YOUR_FLOW_ID"
-LAMATIC_API_URL = "YOUR_API_ENDPOINT"
-LAMATIC_API_KEY = "YOUR_API_KEY"
-LAMATIC_PROJECT_ID = "YOUR_PROJECT_ID"
-GITHUB_TOKEN = "YOUR_GITHUB_TOKEN"
+GITHUB_AUTO_FIX=YOUR_FLOW_ID
+LAMATIC_API_URL=YOUR_API_ENDPOINT
+LAMATIC_API_KEY=YOUR_API_KEY
+LAMATIC_PROJECT_ID=YOUR_PROJECT_ID
+GITHUB_TOKEN=YOUR_GITHUB_TOKEN
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
GITHUB_AUTO_FIX = "YOUR_FLOW_ID"
LAMATIC_API_URL = "YOUR_API_ENDPOINT"
LAMATIC_API_KEY = "YOUR_API_KEY"
LAMATIC_PROJECT_ID = "YOUR_PROJECT_ID"
GITHUB_TOKEN = "YOUR_GITHUB_TOKEN"
GITHUB_AUTO_FIX=YOUR_FLOW_ID
LAMATIC_API_URL=YOUR_API_ENDPOINT
LAMATIC_API_KEY=YOUR_API_KEY
LAMATIC_PROJECT_ID=YOUR_PROJECT_ID
GITHUB_TOKEN=YOUR_GITHUB_TOKEN
🧰 Tools
🪛 dotenv-linter (4.0.0)

[warning] 1-1: [SpaceCharacter] The line has spaces around equal sign

(SpaceCharacter)


[warning] 2-2: [SpaceCharacter] The line has spaces around equal sign

(SpaceCharacter)


[warning] 3-3: [SpaceCharacter] The line has spaces around equal sign

(SpaceCharacter)


[warning] 3-3: [UnorderedKey] The LAMATIC_API_KEY key should go before the LAMATIC_API_URL key

(UnorderedKey)


[warning] 4-4: [SpaceCharacter] The line has spaces around equal sign

(SpaceCharacter)


[warning] 5-5: [EndingBlankLine] No blank line at the end of the file

(EndingBlankLine)


[warning] 5-5: [SpaceCharacter] The line has spaces around equal sign

(SpaceCharacter)


[warning] 5-5: [UnorderedKey] The GITHUB_TOKEN key should go before the LAMATIC_API_KEY key

(UnorderedKey)

Comment on lines +33 to +35
# env files (can opt-in for committing if needed)
.env

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Expand env ignore rules to prevent accidental secret commits.

Lines 33–35 only ignore .env; local variants can still be committed (.env.local, .env.production.local, etc.).

Suggested fix
-# env files (can opt-in for committing if needed)
-.env
+# env files (can opt-in for committing if needed)
+.env*
+!.env.example
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# env files (can opt-in for committing if needed)
.env
# env files (can opt-in for committing if needed)
.env*
!.env.example

Comment on lines +39 to +46
const repoData = await fetch(
`https://api.github.com/repos/${owner}/${repo}`,
{
headers: {
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
},
},
).then((res) => res.json());
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

GitHub API responses lack error handling.

All fetch calls to GitHub API directly chain .then(res => res.json()) without checking res.ok or response status. If any API call fails (401, 404, 422, etc.), the code will continue with malformed data, likely causing cryptic errors downstream or silent failures.

🐛 Proposed fix with proper response validation
+    async function githubFetch(url: string, options?: RequestInit) {
+      const res = await fetch(url, {
+        ...options,
+        headers: {
+          Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
+          "Content-Type": "application/json",
+          ...options?.headers,
+        },
+      });
+      const data = await res.json();
+      if (!res.ok) {
+        throw new Error(`GitHub API error (${res.status}): ${data.message || JSON.stringify(data)}`);
+      }
+      return data;
+    }

     // 🔥 Step 3: Get repo default branch
-    const repoData = await fetch(
-      `https://api.github.com/repos/${owner}/${repo}`,
-      {
-        headers: {
-          Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
-        },
-      },
-    ).then((res) => res.json());
+    const repoData = await githubFetch(`https://api.github.com/repos/${owner}/${repo}`);

Apply similar pattern to all subsequent GitHub API calls.

Comment on lines +63 to +73
await fetch(`https://api.github.com/repos/${owner}/${repo}/git/refs`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
ref: `refs/heads/${pr.branch_name}`,
sha: baseSha,
}),
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Branch creation fails silently if branch already exists.

If a PR for the same issue was attempted before, the branch may already exist. The 422 "Reference already exists" error is not handled, causing the subsequent file update to potentially fail or update the wrong branch state.

🐛 Proposed fix to handle existing branches
     // 🔥 Step 5: Create branch
-    await fetch(`https://api.github.com/repos/${owner}/${repo}/git/refs`, {
+    const branchRes = await fetch(`https://api.github.com/repos/${owner}/${repo}/git/refs`, {
       method: "POST",
       headers: {
         Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
         "Content-Type": "application/json",
       },
       body: JSON.stringify({
         ref: `refs/heads/${pr.branch_name}`,
         sha: baseSha,
       }),
     });
+    
+    if (!branchRes.ok) {
+      const branchError = await branchRes.json();
+      // Allow 422 if branch already exists, otherwise throw
+      if (branchRes.status !== 422 || !branchError.message?.includes("Reference already exists")) {
+        throw new Error(`Failed to create branch: ${branchError.message}`);
+      }
+      console.log("[agent] Branch already exists, continuing with update");
+    }

Comment on lines +106 to +121
<code
dangerouslySetInnerHTML={{
__html: result.fix?.diff
? result.fix.diff.replace(
/^(.*?)$/gm,
(line: string) => {
if (line.startsWith("+"))
return `<span class="text-[#3FB950] bg-[#2EA04326] block w-full px-3 -mx-3 rounded">${line}</span>`;
if (line.startsWith("-"))
return `<span class="text-[#F85149] bg-[#F8514926] block w-full px-3 -mx-3 rounded">${line}</span>`;
return `<span class="text-slate-400 block px-3 -mx-3">${line}</span>`;
}
)
: "No diff available.",
}}
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

XSS vulnerability: Unsanitized content injected via dangerouslySetInnerHTML.

The diff content from the LLM response is rendered without sanitization. If the LLM output contains malicious HTML/JavaScript (via prompt injection or other means), it will execute in the user's browser. The current regex replacement doesn't escape HTML special characters like <, >, &.

🛡️ Proposed fix using HTML escaping
+function escapeHtml(text: string): string {
+  return text
+    .replace(/&/g, "&amp;")
+    .replace(/</g, "&lt;")
+    .replace(/>/g, "&gt;")
+    .replace(/"/g, "&quot;")
+    .replace(/'/g, "&#039;");
+}
+
+function formatDiff(diff: string): string {
+  return diff
+    .split("\n")
+    .map((line) => {
+      const escaped = escapeHtml(line);
+      if (line.startsWith("+"))
+        return `<span class="text-[`#3FB950`] bg-[`#2EA04326`] block w-full px-3 -mx-3 rounded">${escaped}</span>`;
+      if (line.startsWith("-"))
+        return `<span class="text-[`#F85149`] bg-[`#F8514926`] block w-full px-3 -mx-3 rounded">${escaped}</span>`;
+      return `<span class="text-slate-400 block px-3 -mx-3">${escaped}</span>`;
+    })
+    .join("\n");
+}
+
           <pre className="text-[13px] leading-6 font-mono text-slate-300">
             <code
               dangerouslySetInnerHTML={{
-                __html: result.fix?.diff
-                  ? result.fix.diff.replace(
-                      /^(.*?)$/gm,
-                      (line: string) => {
-                        if (line.startsWith("+"))
-                          return `<span class="text-[`#3FB950`] bg-[`#2EA04326`] block w-full px-3 -mx-3 rounded">${line}</span>`;
-                        if (line.startsWith("-"))
-                          return `<span class="text-[`#F85149`] bg-[`#F8514926`] block w-full px-3 -mx-3 rounded">${line}</span>`;
-                        return `<span class="text-slate-400 block px-3 -mx-3">${line}</span>`;
-                      }
-                    )
+                __html: result.fix?.diff
+                  ? formatDiff(result.fix.diff)
                   : "No diff available.",
               }}
             />
           </pre>

Alternatively, consider using a library like DOMPurify for more robust sanitization.

🧰 Tools
🪛 ast-grep (0.41.1)

[warning] 106-106: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html

(react-unsafe-html-injection)

Comment on lines +43 to +47
{
"id": "187c2f4b-c23d-4545-abef-73dc897d6b7d",
"role": "user",
"content": "Extract:\n- issue_url\n- repo_owner\n- repo_name\n- issue_number\n- file_path\n- file_content\nExample:\nhttps://github.com/facebook/react/issues/123\n→ repo_owner: facebook\n→ repo_name: react\n→ issue_number: 123issue_url: https://github.com/hyperjump-io/json-schema-errors/issues/175\nfile_content: {{triggerNode_1.output.file_content}}\nfile_path: {{triggerNode_1.output.file_path}}"
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Hardcoded issue URL in prompt template.

The user prompt contains a hardcoded GitHub issue URL (https://github.com/hyperjump-io/json-schema-errors/issues/175) instead of using the dynamic template variable. This appears to be a copy-paste error from testing.

🐛 Proposed fix to use dynamic input
-              "content": "Extract:\n- issue_url\n- repo_owner\n- repo_name\n- issue_number\n- file_path\n- file_content\nExample:\nhttps://github.com/facebook/react/issues/123\n→ repo_owner: facebook\n→ repo_name: react\n→ issue_number: 123issue_url: https://github.com/hyperjump-io/json-schema-errors/issues/175\nfile_content: {{triggerNode_1.output.file_content}}\nfile_path: {{triggerNode_1.output.file_path}}"
+              "content": "Extract:\n- issue_url\n- repo_owner\n- repo_name\n- issue_number\n- file_path\n- file_content\n\nExample:\nhttps://github.com/facebook/react/issues/123\n→ repo_owner: facebook\n→ repo_name: react\n→ issue_number: 123\n\nissue_url: {{triggerNode_1.output.issue_url}}\nfile_content: {{triggerNode_1.output.file_content}}\nfile_path: {{triggerNode_1.output.file_path}}"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{
"id": "187c2f4b-c23d-4545-abef-73dc897d6b7d",
"role": "user",
"content": "Extract:\n- issue_url\n- repo_owner\n- repo_name\n- issue_number\n- file_path\n- file_content\nExample:\nhttps://github.com/facebook/react/issues/123\n→ repo_owner: facebook\n→ repo_name: react\n→ issue_number: 123issue_url: https://github.com/hyperjump-io/json-schema-errors/issues/175\nfile_content: {{triggerNode_1.output.file_content}}\nfile_path: {{triggerNode_1.output.file_path}}"
}
{
"id": "187c2f4b-c23d-4545-abef-73dc897d6b7d",
"role": "user",
"content": "Extract:\n- issue_url\n- repo_owner\n- repo_name\n- issue_number\n- file_path\n- file_content\n\nExample:\nhttps://github.com/facebook/react/issues/123\n→ repo_owner: facebook\n→ repo_name: react\n→ issue_number: 123\n\nissue_url: {{triggerNode_1.output.issue_url}}\nfile_content: {{triggerNode_1.output.file_content}}\nfile_path: {{triggerNode_1.output.file_path}}"
}

Comment on lines +153 to +157
{
"id": "187c2f4b-c23d-4545-abef-73dc897d6b7d",
"role": "user",
"content": "Generate:1. updated_code (full corrected code or snippet)2. diff (optional but preferred, in git diff format)3. explanation (short technical explanation)Issue Summary: {{InstructorLLMNode_361.output.issue_summary}}\nRoot Cause: {{InstructorLLMNode_361.output.root_cause}}\nAffected Area: {{InstructorLLMNode_361.output.affected_area}}\nFile Path: {{InstructorLLMNode_142.output.file_path}}\nFile Content: {{InstructorLLMNode_142.output.file_content}}"
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Field name mismatch: issue_summary vs summary.

The prompt references {{InstructorLLMNode_361.output.issue_summary}} but the schema for InstructorLLMNode_361 (Line 106) defines the field as summary, not issue_summary. This will result in undefined values being passed to the fix generation step.

🐛 Proposed fix to correct field reference
-              "content": "Generate:1. updated_code (full corrected code or snippet)2. diff (optional but preferred, in git diff format)3. explanation (short technical explanation)Issue Summary: {{InstructorLLMNode_361.output.issue_summary}}\nRoot Cause: {{InstructorLLMNode_361.output.root_cause}}\nAffected Area: {{InstructorLLMNode_361.output.affected_area}}\nFile Path: {{InstructorLLMNode_142.output.file_path}}\nFile Content: {{InstructorLLMNode_142.output.file_content}}"
+              "content": "Generate:\n1. updated_code (full corrected code or snippet)\n2. diff (optional but preferred, in git diff format)\n3. explanation (short technical explanation)\n\nIssue Summary: {{InstructorLLMNode_361.output.summary}}\nRoot Cause: {{InstructorLLMNode_361.output.root_cause}}\nAffected Area: {{InstructorLLMNode_361.output.affected_area}}\nFile Path: {{InstructorLLMNode_142.output.file_path}}\nFile Content: {{InstructorLLMNode_142.output.file_content}}"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{
"id": "187c2f4b-c23d-4545-abef-73dc897d6b7d",
"role": "user",
"content": "Generate:1. updated_code (full corrected code or snippet)2. diff (optional but preferred, in git diff format)3. explanation (short technical explanation)Issue Summary: {{InstructorLLMNode_361.output.issue_summary}}\nRoot Cause: {{InstructorLLMNode_361.output.root_cause}}\nAffected Area: {{InstructorLLMNode_361.output.affected_area}}\nFile Path: {{InstructorLLMNode_142.output.file_path}}\nFile Content: {{InstructorLLMNode_142.output.file_content}}"
}
{
"id": "187c2f4b-c23d-4545-abef-73dc897d6b7d",
"role": "user",
"content": "Generate:\n1. updated_code (full corrected code or snippet)\n2. diff (optional but preferred, in git diff format)\n3. explanation (short technical explanation)\n\nIssue Summary: {{InstructorLLMNode_361.output.summary}}\nRoot Cause: {{InstructorLLMNode_361.output.root_cause}}\nAffected Area: {{InstructorLLMNode_361.output.affected_area}}\nFile Path: {{InstructorLLMNode_142.output.file_path}}\nFile Content: {{InstructorLLMNode_142.output.file_content}}"
}


For questions or issues with this flow:
- Review the node documentation for specific integrations
- Check the Lamatic documentation at docs.lamatic.ai
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use an explicit URL scheme for the docs link.

Line 58 should include https:// to ensure consistent clickability across renderers.

Suggested fix
-- Check the Lamatic documentation at docs.lamatic.ai
+- Check the Lamatic documentation at https://docs.lamatic.ai
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- Check the Lamatic documentation at docs.lamatic.ai
- Check the Lamatic documentation at https://docs.lamatic.ai

Comment on lines +49 to +55
## Setup Locally

```bash
cd kits/agentic/github-auto-fix-agent
npm install
cp .env.example .env
npm run dev No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

README appears truncated.

The file ends abruptly after opening a code block for setup instructions without closing it. The README should include the closing triple backticks and possibly additional sections like "Usage", "Environment Variables", or "Troubleshooting".

📝 Proposed fix to complete the README
 ```bash
 cd kits/agentic/github-auto-fix-agent
 npm install
 cp .env.example .env
 npm run dev
+```
+
+Then open http://localhost:3000/ in your browser.
+
+## Environment Variables
+
+Copy `.env.example` to `.env` and configure:
+
+- `GITHUB_AUTO_FIX` - Lamatic Flow ID
+- `LAMATIC_API_URL` - Lamatic API endpoint
+- `LAMATIC_PROJECT_ID` - Your Lamatic project ID
+- `LAMATIC_API_KEY` - Your Lamatic API key
+- `GITHUB_TOKEN` - GitHub Personal Access Token with repo permissions

Copy link
Contributor

@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: 3

♻️ Duplicate comments (4)
kits/agentic/github-auto-fix-agent/actions/orchestrate.ts (3)

76-140: ⚠️ Potential issue | 🟠 Major

Validate GitHub API responses before consuming JSON.

Line 76 onward assumes success for repo/ref/file/update calls. A 401/404/422 currently propagates as malformed data instead of a clear failure at the source.

🔧 Proposed fix (centralized GitHub fetch with status checks)
+    async function githubFetch(url: string, options?: RequestInit) {
+      const res = await fetch(url, {
+        ...options,
+        headers: {
+          Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
+          "Content-Type": "application/json",
+          ...(options?.headers || {}),
+        },
+      });
+      const data = await res.json().catch(() => ({}));
+      if (!res.ok) {
+        throw new Error(
+          `GitHub API error (${res.status}): ${
+            (data as { message?: string })?.message || "Unknown error"
+          }`
+        );
+      }
+      return data;
+    }

Then replace direct fetch(...).then(res => res.json())/unchecked fetch(...) calls with githubFetch(...).


100-110: ⚠️ Potential issue | 🟠 Major

Handle existing-branch (422) as an idempotent path.

Line 100 creates the branch but does not handle “Reference already exists”. Re-running the flow for the same issue should continue safely.


160-165: ⚠️ Potential issue | 🟠 Major

Confirm PR creation succeeded before returning success.

Line 162 returns success even when GitHub rejects PR creation (e.g., validation/permission errors), which can produce pr_url: undefined.

🔧 Proposed fix
     const prData = await prRes.json();

+    if (!prRes.ok || !prData?.html_url) {
+      throw new Error(
+        `Failed to create PR: ${prData?.message || "Unknown GitHub error"}`
+      );
+    }
+
     return {
       success: true,
       pr_url: prData.html_url,
     };
kits/agentic/github-auto-fix-agent/components/SuccessResult.tsx (1)

195-209: ⚠️ Potential issue | 🔴 Critical

Sanitize diff content before dangerouslySetInnerHTML to prevent XSS.

Lines 195-209 inject raw LLM output into HTML. Prompt-injected <script>/event handlers can execute in-browser.

🔧 Proposed fix
+function escapeHtml(text: string): string {
+  return text
+    .replace(/&/g, "&amp;")
+    .replace(/</g, "&lt;")
+    .replace(/>/g, "&gt;")
+    .replace(/"/g, "&quot;")
+    .replace(/'/g, "&#039;");
+}
+
+function formatDiff(diff: string): string {
+  return diff
+    .split("\n")
+    .map((line) => {
+      const safe = escapeHtml(line);
+      if (line.startsWith("+"))
+        return `<span class="text-[`#3FB950`] bg-[`#2EA04326`] block w-full px-3 -mx-3 rounded">${safe}</span>`;
+      if (line.startsWith("-"))
+        return `<span class="text-[`#F85149`] bg-[`#F8514926`] block w-full px-3 -mx-3 rounded">${safe}</span>`;
+      return `<span class="text-slate-400 block px-3 -mx-3">${safe}</span>`;
+    })
+    .join("\n");
+}
...
-                __html: result.fix?.diff
-                  ? result.fix.diff.replace(
-                      /^(.*?)$/gm,
-                      (line: string) => {
-                        if (line.startsWith("+"))
-                          return `<span class="text-[`#3FB950`] bg-[`#2EA04326`] block w-full px-3 -mx-3 rounded">${line}</span>`;
-                        if (line.startsWith("-"))
-                          return `<span class="text-[`#F85149`] bg-[`#F8514926`] block w-full px-3 -mx-3 rounded">${line}</span>`;
-                        return `<span class="text-slate-400 block px-3 -mx-3">${line}</span>`;
-                      }
-                    )
+                __html: result.fix?.diff
+                  ? formatDiff(result.fix.diff)
                   : "No diff available.",
🧹 Nitpick comments (2)
kits/agentic/github-auto-fix-agent/app/api/create-pr/route.ts (1)

20-20: Consider mapping handler failures to non-200 HTTP status codes.

Line 20 always returns 200 even when result.success is false. Returning 4xx/5xx here simplifies client-side error handling and observability.

kits/agentic/github-auto-fix-agent/components/SuccessResult.tsx (1)

42-47: Pre-validate required PR fields before enabling submit.

Line 42 checks only result.pr object presence; missing branch_name/pr_title/etc. still sends a request that will fail downstream. Validate nested fields and disable the button when incomplete.

Also applies to: 116-119


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 368e84fc-9763-4963-9880-29dbac2f768e

📥 Commits

Reviewing files that changed from the base of the PR and between f953c51 and 0bb4565.

📒 Files selected for processing (6)
  • kits/agentic/github-auto-fix-agent/actions/orchestrate.ts
  • kits/agentic/github-auto-fix-agent/app/api/create-pr/route.ts
  • kits/agentic/github-auto-fix-agent/app/page.tsx
  • kits/agentic/github-auto-fix-agent/components/Header.tsx
  • kits/agentic/github-auto-fix-agent/components/IssueForm.tsx
  • kits/agentic/github-auto-fix-agent/components/SuccessResult.tsx
✅ Files skipped from review due to trivial changes (1)
  • kits/agentic/github-auto-fix-agent/components/Header.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • kits/agentic/github-auto-fix-agent/components/IssueForm.tsx
  • kits/agentic/github-auto-fix-agent/app/page.tsx

Comment on lines +15 to +31
console.log("[agent] Input:", input);

const flowId = process.env.GITHUB_AUTO_FIX;
console.log("FLOW ID:", flowId);
if (!flowId) throw new Error("Missing flow ID");

// Run Lamatic Flow
const resData = await lamaticClient.executeFlow(flowId, input);

if (resData.status !== "success" || !resData.result) {
throw new Error(resData.message || "Lamatic flow failed");
}

const result = resData.result;
const { analysis, fix, pr } = result;

console.log("[agent] Flow output:", result);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid logging raw issue payloads and full generated output.

Line 15 and Line 31 can emit repository code and issue context into server logs. Prefer redacted/metadata-only logs to reduce secret/PII leakage risk.

🔧 Proposed fix
-    console.log("[agent] Input:", input);
+    console.log("[agent] Input received", {
+      hasIssueUrl: Boolean(input.issue_url),
+      hasFilePath: Boolean(input.file_path),
+      hasFileContent: Boolean(input.file_content),
+    });
...
-    console.log("[agent] Flow output:", result);
+    console.log("[agent] Flow output received", {
+      hasAnalysis: Boolean(result?.analysis),
+      hasFix: Boolean(result?.fix),
+      hasPr: Boolean(result?.pr),
+    });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
console.log("[agent] Input:", input);
const flowId = process.env.GITHUB_AUTO_FIX;
console.log("FLOW ID:", flowId);
if (!flowId) throw new Error("Missing flow ID");
// Run Lamatic Flow
const resData = await lamaticClient.executeFlow(flowId, input);
if (resData.status !== "success" || !resData.result) {
throw new Error(resData.message || "Lamatic flow failed");
}
const result = resData.result;
const { analysis, fix, pr } = result;
console.log("[agent] Flow output:", result);
console.log("[agent] Input received", {
hasIssueUrl: Boolean(input.issue_url),
hasFilePath: Boolean(input.file_path),
hasFileContent: Boolean(input.file_content),
});
const flowId = process.env.GITHUB_AUTO_FIX;
console.log("FLOW ID:", flowId);
if (!flowId) throw new Error("Missing flow ID");
// Run Lamatic Flow
const resData = await lamaticClient.executeFlow(flowId, input);
if (resData.status !== "success" || !resData.result) {
throw new Error(resData.message || "Lamatic flow failed");
}
const result = resData.result;
const { analysis, fix, pr } = result;
console.log("[agent] Flow output received", {
hasAnalysis: Boolean(result?.analysis),
hasFix: Boolean(result?.fix),
hasPr: Boolean(result?.pr),
});

Comment on lines +17 to +20
const flowId = process.env.GITHUB_AUTO_FIX;
console.log("FLOW ID:", flowId);
if (!flowId) throw new Error("Missing flow ID");

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Use the documented flow env var (or support both names).

Line 17 reads GITHUB_AUTO_FIX, but the PR setup docs list AGENTIC_GENERATE_CONTENT. This can fail on first-run with a valid .env from README/PR docs.

🔧 Proposed fix
-    const flowId = process.env.GITHUB_AUTO_FIX;
+    const flowId =
+      process.env.GITHUB_AUTO_FIX ?? process.env.AGENTIC_GENERATE_CONTENT;
     console.log("FLOW ID:", flowId);
     if (!flowId) throw new Error("Missing flow ID");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const flowId = process.env.GITHUB_AUTO_FIX;
console.log("FLOW ID:", flowId);
if (!flowId) throw new Error("Missing flow ID");
const flowId =
process.env.GITHUB_AUTO_FIX ?? process.env.AGENTIC_GENERATE_CONTENT;
console.log("FLOW ID:", flowId);
if (!flowId) throw new Error("Missing flow ID");

Comment on lines +7 to +16
if (!body.issue_url || !body.file_path || !body.fix || !body.pr) {
return Response.json(
{
success: false,
error:
"issue_url, file_path, fix, and pr are all required",
},
{ status: 400 },
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Validate nested payload fields before calling handleCreatePR.

Line 7 only checks object presence; it does not enforce fix.updated_code and required PR fields. Reject malformed payloads at the route boundary with a 400.

🔧 Proposed fix
-    if (!body.issue_url || !body.file_path || !body.fix || !body.pr) {
+    const hasRequiredNestedFields =
+      typeof body?.fix?.updated_code === "string" &&
+      body.fix.updated_code.length > 0 &&
+      typeof body?.pr?.branch_name === "string" &&
+      typeof body?.pr?.commit_message === "string" &&
+      typeof body?.pr?.pr_title === "string" &&
+      typeof body?.pr?.pr_body === "string";
+
+    if (!body.issue_url || !body.file_path || !hasRequiredNestedFields) {
       return Response.json(
         {
           success: false,
-          error:
-            "issue_url, file_path, fix, and pr are all required",
+          error:
+            "issue_url, file_path, fix.updated_code and all pr fields are required",
         },
         { status: 400 },
       );
     }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants