UNPKG

termcode

Version:

Superior terminal AI coding agent with enterprise-grade security, intelligent error recovery, performance monitoring, and plugin system - Advanced Claude Code alternative

81 lines (80 loc) 2.68 kB
import { spawnSync } from "node:child_process"; import { CFG } from "../config.js"; import { log } from "../util/logging.js"; function safeGitSync(args, cwd) { try { const result = spawnSync("git", args, { cwd, encoding: "utf8", maxBuffer: 10 * 1024 * 1024, // 10MB buffer timeout: 30000 // 30 second timeout }); if (result.status === 0) { return result.stdout.trim(); } return null; } catch (error) { return null; } } export async function createPullRequest(repoPath, branchName, title, body) { // Get repo info from git remote const remote = safeGitSync(["config", "--get", "remote.origin.url"], repoPath); if (!remote) { throw new Error("No git remote origin found"); } // Parse GitHub repo from remote URL const match = remote.match(/github\.com[:/](.+?)(?:\.git)?$/); if (!match) { throw new Error("Not a GitHub repo or unsupported remote URL"); } const [owner, repo] = match[1].split("/"); if (!CFG.GITHUB_TOKEN) { throw new Error("GITHUB_TOKEN not set in environment"); } // Create PR via GitHub API const url = `https://api.github.com/repos/${owner}/${repo}/pulls`; try { const response = await fetch(url, { method: "POST", headers: { "Authorization": `token ${CFG.GITHUB_TOKEN}`, "Accept": "application/vnd.github+json", "Content-Type": "application/json" }, body: JSON.stringify({ title, head: branchName, base: "main", // Could be configurable body }) }); if (!response.ok) { const error = await response.text(); throw new Error(`GitHub API error (${response.status}): ${error}`); } const data = await response.json(); log.info(`✅ Created PR: ${data.html_url}`); return data.html_url; } catch (error) { if (error instanceof Error) { throw new Error(`Failed to create PR: ${error.message}`); } throw error; } } export function getRepoInfo(repoPath) { const remote = safeGitSync(["config", "--get", "remote.origin.url"], repoPath); if (!remote) return null; const match = remote.match(/github\.com[:/](.+?)(?:\.git)?$/); if (!match) return null; const [owner, repo] = match[1].split("/"); return { owner, repo }; } export function getCurrentBranch(repoPath) { return safeGitSync(["branch", "--show-current"], repoPath); }