arela
Version:
AI-powered CTO with multi-agent orchestration, code summarization, visual testing (web + mobile) for blazing fast development.
140 lines • 4.17 kB
JavaScript
/**
* Git operations for slice extraction
*/
import { execa } from "execa";
export class GitManager {
/**
* Stage all files in a list
*/
async stageFiles(filePaths, cwd = process.cwd()) {
if (filePaths.length === 0) {
return;
}
for (const filePath of filePaths) {
try {
await execa("git", ["add", filePath], { cwd });
}
catch (error) {
// Continue even if one file fails to stage
}
}
}
/**
* Unstage all files in a list
*/
async unstageFiles(filePaths, cwd = process.cwd()) {
if (filePaths.length === 0) {
return;
}
for (const filePath of filePaths) {
try {
await execa("git", ["reset", "HEAD", filePath], { cwd });
}
catch (error) {
// Continue even if one file fails
}
}
}
/**
* Commit extracted slice
*/
async commitSlice(slice, stagedFiles, cwd = process.cwd()) {
const commitMessage = this.generateCommitMessage(slice, stagedFiles);
return this.commitWithMessage(commitMessage, cwd);
}
/**
* Commit with a custom message
*/
async commitWithMessage(message, cwd = process.cwd()) {
try {
// Stage all changes (new files in features/ and deletions in src/)
await execa("git", ["add", "-A"], { cwd });
const result = await execa("git", ["commit", "-m", message], {
cwd,
});
return result.stdout;
}
catch (error) {
throw new Error(`Failed to commit: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Create git tag
*/
async createTag(tagName, message, cwd = process.cwd()) {
try {
await execa("git", ["tag", "-a", tagName, "-m", message], {
cwd,
});
}
catch (error) {
throw new Error(`Failed to create tag ${tagName}: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Reset to HEAD (undo all changes)
*/
async resetToHead(cwd = process.cwd()) {
try {
await execa("git", ["reset", "--hard", "HEAD"], { cwd });
}
catch (error) {
throw new Error(`Failed to reset to HEAD: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Clean untracked files
*/
async cleanUntracked(cwd = process.cwd()) {
try {
await execa("git", ["clean", "-fd"], { cwd });
}
catch (error) {
throw new Error(`Failed to clean untracked files: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Get current branch name
*/
async getCurrentBranch(cwd = process.cwd()) {
try {
const result = await execa("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
cwd,
});
return result.stdout.trim();
}
catch {
return "main";
}
}
/**
* Check if there are uncommitted changes
*/
async hasUncommittedChanges(cwd = process.cwd()) {
try {
const result = await execa("git", ["status", "--porcelain"], {
cwd,
});
return result.stdout.trim().length > 0;
}
catch {
return false;
}
}
/**
* Generate commit message for slice extraction
*/
generateCommitMessage(slice, stagedFiles) {
const title = `feat: extract ${slice.name} slice`;
const details = [
"",
`- Moved ${slice.fileCount} files`,
`- Updated imports: ${slice.internalImports} internal, ${slice.externalImports} external`,
`- Cohesion score: ${Math.round(slice.cohesion)}%`,
"",
"Generated by Arela v4.0.0",
];
return [title, ...details].join("\n");
}
}
//# sourceMappingURL=git-manager.js.map