@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.
127 lines (124 loc) ⢠6.48 kB
JavaScript
const require_chunk = require("../chunk-CoPdw6nB.cjs");
const require_picocolors$1 = require("../picocolors-Cw2Y0JiP.cjs");
const require_utils_zx_factory = require("../utils/zx-factory.cjs");
let node_readline = require("node:readline");
//#region src/scripts/generate-git-branch.ts
var import_picocolors = /* @__PURE__ */ require_chunk.__toESM(require_picocolors$1.require_picocolors());
async function requestUserInput(prompt) {
const rl = (0, node_readline.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 require_picocolors$1.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 require_utils_zx_factory.$$`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 require_utils_zx_factory.$$`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 require_utils_zx_factory.$$`git checkout main`;
await require_utils_zx_factory.$$`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 require_utils_zx_factory.$$`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 require_utils_zx_factory.$$`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
//# sourceMappingURL=generate-git-branch.cjs.map