feat: Add github-auto-fix-agent AgentKit#87
Conversation
📝 WalkthroughWalkthroughAdds 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
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 Tip CodeRabbit can enforce grammar and style rules using `languagetool`.Configure the |
There was a problem hiding this comment.
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 forresultstate.Using
anytype 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
⛔ Files ignored due to path filters (8)
kits/agentic/github-auto-fix-agent/app/favicon.icois excluded by!**/*.icokits/agentic/github-auto-fix-agent/package-lock.jsonis excluded by!**/package-lock.jsonkits/agentic/github-auto-fix-agent/public/file.svgis excluded by!**/*.svgkits/agentic/github-auto-fix-agent/public/flows.pngis excluded by!**/*.pngkits/agentic/github-auto-fix-agent/public/globe.svgis excluded by!**/*.svgkits/agentic/github-auto-fix-agent/public/next.svgis excluded by!**/*.svgkits/agentic/github-auto-fix-agent/public/vercel.svgis excluded by!**/*.svgkits/agentic/github-auto-fix-agent/public/window.svgis excluded by!**/*.svg
📒 Files selected for processing (24)
kits/agentic/github-auto-fix-agent/.env.examplekits/agentic/github-auto-fix-agent/.gitignorekits/agentic/github-auto-fix-agent/README.mdkits/agentic/github-auto-fix-agent/actions/orchestrate.tskits/agentic/github-auto-fix-agent/app/api/fix/route.tskits/agentic/github-auto-fix-agent/app/globals.csskits/agentic/github-auto-fix-agent/app/layout.tsxkits/agentic/github-auto-fix-agent/app/page.tsxkits/agentic/github-auto-fix-agent/components/BackgroundDecoration.tsxkits/agentic/github-auto-fix-agent/components/ErrorResult.tsxkits/agentic/github-auto-fix-agent/components/Footer.tsxkits/agentic/github-auto-fix-agent/components/Header.tsxkits/agentic/github-auto-fix-agent/components/IssueForm.tsxkits/agentic/github-auto-fix-agent/components/SuccessResult.tsxkits/agentic/github-auto-fix-agent/eslint.config.mjskits/agentic/github-auto-fix-agent/flows/github-issue-solver/README.mdkits/agentic/github-auto-fix-agent/flows/github-issue-solver/config.jsonkits/agentic/github-auto-fix-agent/flows/github-issue-solver/inputs.jsonkits/agentic/github-auto-fix-agent/flows/github-issue-solver/meta.jsonkits/agentic/github-auto-fix-agent/lib/lamatic-client.tskits/agentic/github-auto-fix-agent/next.config.tskits/agentic/github-auto-fix-agent/package.jsonkits/agentic/github-auto-fix-agent/postcss.config.mjskits/agentic/github-auto-fix-agent/tsconfig.json
| 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 |
There was a problem hiding this comment.
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.
| 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)
| # env files (can opt-in for committing if needed) | ||
| .env | ||
|
|
There was a problem hiding this comment.
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.
| # env files (can opt-in for committing if needed) | |
| .env | |
| # env files (can opt-in for committing if needed) | |
| .env* | |
| !.env.example | |
| const repoData = await fetch( | ||
| `https://api.github.com/repos/${owner}/${repo}`, | ||
| { | ||
| headers: { | ||
| Authorization: `Bearer ${process.env.GITHUB_TOKEN}`, | ||
| }, | ||
| }, | ||
| ).then((res) => res.json()); |
There was a problem hiding this comment.
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.
| 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, | ||
| }), | ||
| }); |
There was a problem hiding this comment.
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");
+ }| <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.", | ||
| }} | ||
| /> |
There was a problem hiding this comment.
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, "&")
+ .replace(/</g, "<")
+ .replace(/>/g, ">")
+ .replace(/"/g, """)
+ .replace(/'/g, "'");
+}
+
+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)
| { | ||
| "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}}" | ||
| } |
There was a problem hiding this comment.
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.
| { | |
| "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}}" | |
| } |
| { | ||
| "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}}" | ||
| } |
There was a problem hiding this comment.
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.
| { | |
| "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 |
There was a problem hiding this comment.
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.
| - Check the Lamatic documentation at docs.lamatic.ai | |
| - Check the Lamatic documentation at https://docs.lamatic.ai |
| ## 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 |
There was a problem hiding this comment.
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 permissionsThere was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (4)
kits/agentic/github-auto-fix-agent/actions/orchestrate.ts (3)
76-140:⚠️ Potential issue | 🟠 MajorValidate 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())/uncheckedfetch(...)calls withgithubFetch(...).
100-110:⚠️ Potential issue | 🟠 MajorHandle 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 | 🟠 MajorConfirm 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 | 🔴 CriticalSanitize diff content before
dangerouslySetInnerHTMLto 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, "&") + .replace(/</g, "<") + .replace(/>/g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); +} + +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.successis 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.probject presence; missingbranch_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
📒 Files selected for processing (6)
kits/agentic/github-auto-fix-agent/actions/orchestrate.tskits/agentic/github-auto-fix-agent/app/api/create-pr/route.tskits/agentic/github-auto-fix-agent/app/page.tsxkits/agentic/github-auto-fix-agent/components/Header.tsxkits/agentic/github-auto-fix-agent/components/IssueForm.tsxkits/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
| 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); |
There was a problem hiding this comment.
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.
| 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), | |
| }); |
| const flowId = process.env.GITHUB_AUTO_FIX; | ||
| console.log("FLOW ID:", flowId); | ||
| if (!flowId) throw new Error("Missing flow ID"); | ||
|
|
There was a problem hiding this comment.
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.
| 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"); |
| 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 }, | ||
| ); | ||
| } |
There was a problem hiding this comment.
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 },
);
}
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:
Instead of spending time manually fixing minimal bugs, developers can review AI-suggested changes and create PRs in seconds.
Providers & Prerequisites
Providers
Prerequisites
repopermissionsRequired Environment Variables
How to Run Locally
cd kits/agentic/github-auto-fix-agentnpm installcp .env.example .envand fill in valuesnpm run devLive Preview
https://agent-kit-beta.vercel.app/
Lamatic Flow
Flow ID: b232a0d5-1bbd-44dd-96a1-33a3b98615b8
Checklist
npm run dev.env.examplehas no secrets, only placeholdersREADME.mddocuments setup and usagekits/<category>/<kit-name>/config.jsonis present and validflows/folderOverview
Adds a new "github-auto-fix-agent" kit that automates GitHub issue analysis and code fix generation with PR creation.
Key Additions
Core Functionality
github-issue-solver) with 7 nodes that extracts issue details, analyzes root causes, generates code fixes, and prepares PR metadataactions/orchestrate.ts) that coordinates Lamatic flow execution and GitHub API interactions (issue fetching, branch creation, file updates, PR creation)app/api/fix/route.ts) accepting GitHub issue URLs and optional file pathsFrontend (Next.js)
Configuration & Setup
.env.example) with required variables:GITHUB_AUTO_FIX,LAMATIC_API_URL,LAMATIC_API_KEY,LAMATIC_PROJECT_ID,GITHUB_TOKEN.gitignorefor development artifactsDependencies
File Structure
All files located under
kits/agentic/github-auto-fix-agent/with flows inflows/github-issue-solver/