git-pr-ai
Version:
A tool to automatically extract JIRA ticket numbers from branch names and create GitHub/GitLab PRs
110 lines (104 loc) • 3.61 kB
JavaScript
import { getLanguage, loadConfig } from "./config-BqoKKiEi.js";
import { $ } from "zx";
//#region src/language-prompts.ts
const LANGUAGE_PROMPTS = {
en: {
systemInstruction: "Please respond in English.",
responseFormat: "Please provide your response in English."
},
"zh-TW": {
systemInstruction: "請用繁體中文回應。",
responseFormat: "請用繁體中文提供你的回應。"
}
};
function createLanguagePrompt(basePrompt, language) {
const languagePrompt = LANGUAGE_PROMPTS[language];
return `${languagePrompt.systemInstruction}
${basePrompt}
${languagePrompt.responseFormat}`;
}
//#endregion
//#region src/ai/internal.ts
async function executeAIInternal(prompt, options = {}) {
const { useLanguage = true, yolo = false, outputType = "inherit" } = options;
const config = await loadConfig();
const language = useLanguage ? await getLanguage() : "en";
const finalPrompt = useLanguage ? createLanguagePrompt(prompt, language) : prompt;
switch (config.agent) {
case "claude":
await checkClaudeCLI();
break;
case "gemini":
await checkGeminiCLI();
break;
default: throw new Error(`Unsupported AI agent: ${config.agent}`);
}
if (outputType === "inherit") {
await runAICommand(config.agent, finalPrompt, yolo);
return;
} else {
const output = await runAICommandWithOutput(config.agent, finalPrompt, yolo);
return outputType === "json" ? extractJsonFromOutput(output) : output;
}
}
async function runAICommand(agent, prompt, yolo) {
if (yolo) if (agent === "claude") await $({ stdio: "inherit" })`claude --dangerously-skip-permissions ${prompt}`;
else await $({ stdio: "inherit" })`gemini --yolo --prompt-interactive ${prompt}`;
else if (agent === "claude") await $({ stdio: "inherit" })`claude ${prompt}`;
else await $({ stdio: "inherit" })`gemini --prompt-interactive ${prompt}`;
}
async function runAICommandWithOutput(agent, prompt, yolo) {
let result;
if (yolo) if (agent === "claude") result = await $({ input: prompt })`claude --dangerously-skip-permissions`.quiet();
else result = await $({ input: prompt })`gemini --yolo -p`.quiet();
else if (agent === "claude") result = await $({ input: prompt })`claude`.quiet();
else result = await $({ input: prompt })`gemini -p`.quiet();
return result.stdout.trim();
}
function extractJsonFromOutput(output) {
const firstBrace = output.indexOf("{");
const lastBrace = output.lastIndexOf("}");
if (firstBrace === -1 || lastBrace === -1 || firstBrace >= lastBrace) throw new Error("No valid JSON object found in AI response");
return output.substring(firstBrace, lastBrace + 1);
}
async function checkClaudeCLI() {
try {
await $`claude --version`.quiet();
} catch {
console.error("🤖 Claude CLI not found");
console.error("Please install Claude Code: https://claude.ai/code");
process.exit(1);
}
}
async function checkGeminiCLI() {
try {
await $`gemini --version`.quiet();
} catch {
console.error("🤖 Gemini CLI not found");
console.error("Please install Gemini CLI");
process.exit(1);
}
}
//#endregion
//#region src/ai/executor.ts
async function executeAICommand(prompt, options = {}) {
await executeAIInternal(prompt, {
...options,
outputType: "inherit"
});
}
async function executeAIWithOutput(prompt, options = {}) {
return await executeAIInternal(prompt, {
...options,
outputType: "capture"
});
}
async function executeAIWithJsonOutput(prompt, options = {}) {
return await executeAIInternal(prompt, {
...options,
outputType: "json"
});
}
//#endregion
export { executeAICommand, executeAIWithJsonOutput, executeAIWithOutput };