UNPKG

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
#!/usr/bin/env node 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 };