src / tools / gitWorkflowTools.ts
src / tools / gitWorkflowTools.ts
import { execFile } from 'child_process';
import fs from 'fs/promises';
import path from 'path';
import { promisify } from 'util';
import crypto from 'crypto';
import { getState } from '../stateRegistry';
const execFilePromise = promisify(execFile);
interface GitWorkflow {
id: string;
branch_name: string;
description: string;
status: 'active' | 'pr_opened' | 'merged' | 'closed';
created_at: number;
}
const gitWorkflows = new Map<string, GitWorkflow>();
export async function git_workflow_create(branchName: string, description?: string, workspaceRoot: string = process.cwd()): Promise<{ success: boolean; workflow_id?: string }> {
const id = `gw_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
try {
await execFilePromise('git', ['checkout', '-b', branchName], { cwd: workspaceRoot });
gitWorkflows.set(id, {
id,
branch_name: branchName,
description: description || '',
status: 'active',
created_at: Date.now()
});
getState().lastConfigChange = new Date();
return { success: true, workflow_id: id };
} catch (err) {
return { success: false };
}
}
export async function git_workflow_open_pr(workflowId: string, workspaceRoot: string = process.cwd()): Promise<{ success: boolean; pr_url?: string }> {
const wf = gitWorkflows.get(workflowId);
if (!wf || wf.status !== 'active') return { success: false };
try {
await execFilePromise('git', ['push', '-u', 'origin', wf.branch_name], { cwd: workspaceRoot });
wf.status = 'pr_opened';
const prUrl = `https://github.com/placeholder/repo/pull/${Math.floor(Math.random() * 1000)}`;
return { success: true, pr_url: prUrl };
} catch {
return { success: false };
}
}
export async function git_workflow_status(workflowId?: string): Promise<{ workflows: GitWorkflow[] }> {
if (workflowId) {
const wf = gitWorkflows.get(workflowId);
return { workflows: wf ? [wf] : [] };
}
return { workflows: Array.from(gitWorkflows.values()) };
}
export async function git_workflow_resolve_conflicts(workflowId: string, baseContent: string, headContent: string): Promise<{ success: boolean; resolved_content?: string }> {
const wf = gitWorkflows.get(workflowId);
if (!wf) return { success: false };
const baseLines = baseContent.split('\n');
const headLines = headContent.split('\n');
let resolved = '';
for (let i = 0; i < Math.max(baseLines.length, headLines.length); i++) {
if (baseLines[i] !== headLines[i]) {
resolved += `<<<<<<< HEAD\n${headLines[i] || ''}\n=======\n${baseLines[i] || ''}\n>>>>>>> base\n`;
} else {
resolved += `${baseLines[i] || ''}\n`;
}
}
return { success: true, resolved_content: resolved };
}
export async function git_workflow_changelog(workflowId?: string, workspaceRoot: string = process.cwd()): Promise<{ changelog: string }> {
try {
const { stdout } = await execFilePromise('git', ['log', '--oneline', '-20'], { cwd: workspaceRoot });
return { changelog: stdout || 'No commits found' };
} catch {
return { changelog: 'Git not available or no repository' };
}
}
import { execFile } from 'child_process';
import fs from 'fs/promises';
import path from 'path';
import { promisify } from 'util';
import crypto from 'crypto';
import { getState } from '../stateRegistry';
const execFilePromise = promisify(execFile);
interface GitWorkflow {
id: string;
branch_name: string;
description: string;
status: 'active' | 'pr_opened' | 'merged' | 'closed';
created_at: number;
}
const gitWorkflows = new Map<string, GitWorkflow>();
export async function git_workflow_create(branchName: string, description?: string, workspaceRoot: string = process.cwd()): Promise<{ success: boolean; workflow_id?: string }> {
const id = `gw_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
try {
await execFilePromise('git', ['checkout', '-b', branchName], { cwd: workspaceRoot });
gitWorkflows.set(id, {
id,
branch_name: branchName,
description: description || '',
status: 'active',
created_at: Date.now()
});
getState().lastConfigChange = new Date();
return { success: true, workflow_id: id };
} catch (err) {
return { success: false };
}
}
export async function git_workflow_open_pr(workflowId: string, workspaceRoot: string = process.cwd()): Promise<{ success: boolean; pr_url?: string }> {
const wf = gitWorkflows.get(workflowId);
if (!wf || wf.status !== 'active') return { success: false };
try {
await execFilePromise('git', ['push', '-u', 'origin', wf.branch_name], { cwd: workspaceRoot });
wf.status = 'pr_opened';
const prUrl = `https://github.com/placeholder/repo/pull/${Math.floor(Math.random() * 1000)}`;
return { success: true, pr_url: prUrl };
} catch {
return { success: false };
}
}
export async function git_workflow_status(workflowId?: string): Promise<{ workflows: GitWorkflow[] }> {
if (workflowId) {
const wf = gitWorkflows.get(workflowId);
return { workflows: wf ? [wf] : [] };
}
return { workflows: Array.from(gitWorkflows.values()) };
}
export async function git_workflow_resolve_conflicts(workflowId: string, baseContent: string, headContent: string): Promise<{ success: boolean; resolved_content?: string }> {
const wf = gitWorkflows.get(workflowId);
if (!wf) return { success: false };
const baseLines = baseContent.split('\n');
const headLines = headContent.split('\n');
let resolved = '';
for (let i = 0; i < Math.max(baseLines.length, headLines.length); i++) {
if (baseLines[i] !== headLines[i]) {
resolved += `<<<<<<< HEAD\n${headLines[i] || ''}\n=======\n${baseLines[i] || ''}\n>>>>>>> base\n`;
} else {
resolved += `${baseLines[i] || ''}\n`;
}
}
return { success: true, resolved_content: resolved };
}
export async function git_workflow_changelog(workflowId?: string, workspaceRoot: string = process.cwd()): Promise<{ changelog: string }> {
try {
const { stdout } = await execFilePromise('git', ['log', '--oneline', '-20'], { cwd: workspaceRoot });
return { changelog: stdout || 'No commits found' };
} catch {
return { changelog: 'Git not available or no repository' };
}
}