@smooai/utils
Version:
A collection of shared utilities and tools used across SmooAI projects. This package provides common functionality to standardize and simplify development across all SmooAI repositories.
128 lines (125 loc) ⢠6.26 kB
JavaScript
import { s as __toESM } from "../chunk-B6ditiVD.mjs";
import { n as OpenAI, t as require_picocolors } from "../picocolors-ClWS1B-Z.mjs";
import { $$ } from "../utils/zx-factory.mjs";
import { createInterface } from "node:readline";
//#region src/scripts/generate-git-branch.ts
var import_picocolors = /* @__PURE__ */ __toESM(require_picocolors());
async function requestUserInput(prompt) {
const rl = createInterface({
input: process.stdin,
output: process.stdout
});
return new Promise((resolve) => {
rl.question(import_picocolors.default.cyan(prompt), (answer) => {
rl.close();
const trimmedAnswer = answer.trim();
if (trimmedAnswer) console.log(import_picocolors.default.green(`ā ${trimmedAnswer}`));
resolve(trimmedAnswer);
});
});
}
async function generateBranchName(workDescription) {
const openaiApiKey = process.env.OPENAI_API_KEY;
if (!openaiApiKey || typeof openaiApiKey !== "string") throw new Error("OPENAI_API_KEY is not configured");
const openai = new OpenAI({ apiKey: openaiApiKey });
const prompt = `Generate a git branch name for the following work description.
The branch name should be:
- Descriptive but concise (max 40 characters to leave room for date)
- Use kebab-case (lowercase with hyphens)
- Avoid special characters except hyphens
- Be meaningful and related to the work
- DO NOT include any dates, timestamps, or time-related information
- Focus on the feature/change being implemented
Work description: ${workDescription}
Return only the branch name, nothing else.`;
try {
const branchName = (await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [{
role: "user",
content: prompt
}],
max_tokens: 50,
temperature: .3
})).choices[0]?.message?.content?.trim();
if (!branchName) throw new Error("Failed to generate branch name from OpenAI");
return `${branchName.replace(/[^a-zA-Z0-9\-_/]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").replace(/\d{4}-\d{2}-\d{2}/g, "").replace(/\d{2}-\d{2}-\d{4}/g, "").replace(/-+/g, "-").replace(/^-|-$/g, "").toLowerCase()}-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}`;
} catch (_error) {
console.error("Error generating branch name:", _error);
throw _error;
}
}
async function createAndSwitchToBranch(branchName, options = {}) {
const { pullFromMain = true } = options;
let hasStashed = false;
try {
if (pullFromMain) {
console.log(import_picocolors.default.yellow("š„ Updating main branch with latest changes..."));
try {
if ((await $$`git status --porcelain`).stdout.trim().length > 0) {
console.log(import_picocolors.default.yellow("\nā ļø You have uncommitted changes."));
const stashResponse = await requestUserInput("Would you like to stash them and continue? (y/n, default: y): ");
if (stashResponse.toLowerCase() !== "n" && stashResponse.toLowerCase() !== "no") {
console.log(import_picocolors.default.blue("š¦ Stashing uncommitted changes..."));
await $$`git stash push -m "Auto-stash before branch creation"`;
hasStashed = true;
console.log(import_picocolors.default.green("ā
Changes stashed successfully"));
} else {
console.log(import_picocolors.default.red("ā Branch creation cancelled. Please commit or stash your changes manually."));
process.exit(0);
}
}
await $$`git checkout main`;
await $$`git pull origin main`;
console.log(import_picocolors.default.green("ā
Successfully updated main branch"));
} catch (_error) {
console.warn(import_picocolors.default.yellow("ā ļø Warning: Could not update main branch. Continuing with current state."));
}
}
console.log(`\n${import_picocolors.default.blue("š")} Creating branch: ${import_picocolors.default.bold(branchName)}`);
await $$`git checkout -b ${branchName}`;
console.log(`\n${import_picocolors.default.green("š")} Successfully created and switched to branch: ${import_picocolors.default.bold(import_picocolors.default.green(branchName))}`);
if (hasStashed) {
console.log(import_picocolors.default.blue("\nš¦ Restoring stashed changes..."));
try {
await $$`git stash pop`;
console.log(import_picocolors.default.green("ā
Stashed changes restored successfully"));
} catch (_error) {
console.warn(import_picocolors.default.yellow("ā ļø Warning: Could not automatically restore stashed changes. Use \"git stash pop\" manually."));
}
}
console.log(`${import_picocolors.default.cyan("š")} Ready to start working on: ${import_picocolors.default.bold(branchName)}`);
} catch (_error) {
console.error(import_picocolors.default.red(`Git command failed`));
process.exit(1);
}
}
async function main() {
try {
console.log(import_picocolors.default.bold(import_picocolors.default.blue("š Git Branch Generator")));
console.log(import_picocolors.default.blue("======================\n"));
const workDescription = await requestUserInput("Please describe the work you want to do: ");
if (!workDescription) {
console.error(import_picocolors.default.red("ā Work description cannot be empty"));
process.exit(1);
}
const pullFromMainInput = await requestUserInput("\nPull latest changes from main after creating branch? (y/n, default: y): ");
const pullFromMain = pullFromMainInput.toLowerCase() !== "n" && pullFromMainInput.toLowerCase() !== "no";
console.log(`\n${import_picocolors.default.magenta("š¤")} Generating branch name with AI...`);
const branchName = await generateBranchName(workDescription);
console.log(`${import_picocolors.default.green("āØ")} Generated branch name: ${import_picocolors.default.bold(import_picocolors.default.green(branchName))}`);
const confirm = await requestUserInput(`\nCreate branch "${import_picocolors.default.bold(branchName)}"? (y/n, default: y): `);
if (confirm.toLowerCase() === "n" || confirm.toLowerCase() === "no") {
console.log(import_picocolors.default.red("ā Branch creation cancelled"));
process.exit(0);
}
await createAndSwitchToBranch(branchName, { pullFromMain });
} catch (error) {
console.error(import_picocolors.default.red("ā Error:"), error);
process.exit(1);
}
}
main();
//#endregion
export {};
//# sourceMappingURL=generate-git-branch.mjs.map