fix: Add command source files
Some checks failed
CI / test (push) Failing after 5s

This commit is contained in:
2026-02-03 08:07:32 +00:00
parent 51ff46f3c6
commit 1157e0a8fa

141
src/commands/diff.ts Normal file
View File

@@ -0,0 +1,141 @@
import * as path from 'path';
import { Command } from 'commander';
import chalk from 'chalk';
import {
getWorkspacePath,
loadWorkspaceConfig,
sanitizeAgentName
} from '../utils/file-utils';
import {
generateDiff,
createGit,
getCurrentBranch
} from '../utils/git-utils';
import { DiffLine } from '../types/index';
import {
formatDiffAsMarkdown,
formatDiffAsJson,
formatDiffAsText,
exportDiffToFile,
generateShortDiffSummary
} from '../utils/diff-utils';
import { GitAgentSyncError, WorkspaceNotFoundError } from '../utils/errors';
export function createDiffCommand(): Command {
const cmd = new Command('diff')
.description('Generate unified diffs for code review')
.argument('[agent-name]', 'Agent name (defaults to current workspace)')
.option('-o, --output <file>', 'Export diff to file')
.option('--short', 'Show short summary only')
.option('--json', 'Output as JSON')
.option('--text', 'Output as plain text')
.option('--compare <branch>', 'Compare to a specific branch (default: main)')
.action(async (agentName, options) => {
try {
const currentPath = process.cwd();
let workspacePath: string;
let targetAgentName: string;
if (agentName) {
targetAgentName = sanitizeAgentName(agentName);
workspacePath = getWorkspacePath(currentPath, targetAgentName);
} else {
const workspaceResult = await detectCurrentWorkspace(currentPath);
workspacePath = workspaceResult.path;
targetAgentName = workspaceResult.agentName;
}
const config = await loadWorkspaceConfig(workspacePath);
if (!config) {
throw new WorkspaceNotFoundError(targetAgentName);
}
const compareBranch = options.compare || config.mainBranch;
const diffResult = await generateDiff(currentPath, workspacePath, targetAgentName, compareBranch);
if (options.short) {
const summary = generateShortDiffSummary(diffResult);
console.log(chalk.white(`${targetAgentName}: ${summary}`));
return;
}
if (options.json) {
console.log(formatDiffAsJson(diffResult));
return;
}
if (options.text) {
console.log(formatDiffAsText(diffResult));
return;
}
if (options.output) {
await exportDiffToFile(diffResult, options.output, 'markdown');
console.log(chalk.green(`\n✓ Diff exported to ${options.output}`));
return;
}
console.log(chalk.cyan(`\n📝 Diff: ${targetAgentName}`));
console.log(chalk.gray(`Branch: ${diffResult.branch}${diffResult.comparedBranch}`));
console.log(chalk.gray('─'.repeat(60)));
if (diffResult.files.length === 0) {
console.log(chalk.yellow('\n No differences found.'));
return;
}
console.log(chalk.cyan('\n📊 Summary:'));
console.log(` Files: ${chalk.white(diffResult.summary.filesChanged)}`);
console.log(` Additions: ${chalk.green(`+${diffResult.summary.additions}`)}`);
console.log(` Deletions: ${chalk.red(`-${diffResult.summary.deletions}`)}`);
console.log(chalk.gray('─'.repeat(60)));
for (const file of diffResult.files) {
console.log(chalk.cyan(`\n📄 ${file.file}`));
console.log(` +${file.additions} / -${file.deletions}`);
const relevantChanges = file.changes.filter((c: DiffLine) => c.type !== 'context').slice(0, 20);
if (relevantChanges.length > 0) {
console.log(' Preview:');
for (const line of relevantChanges) {
if (line.type === 'added') {
console.log(` ${chalk.green(line.content)}`);
} else if (line.type === 'deleted') {
console.log(` ${chalk.red(line.content)}`);
}
}
if (file.changes.filter((c: DiffLine) => c.type !== 'context').length > 20) {
console.log(` ${chalk.gray('... and more changes (use --output to see full diff)')}`);
}
}
}
console.log(chalk.cyan('\n💡 Use --output to export full diff to a file'));
} catch (error) {
const gitError = error instanceof GitAgentSyncError ? error : new GitAgentSyncError(String(error));
console.error(chalk.red(`\n❌ Error: ${gitError.message}`));
process.exit(1);
}
});
return cmd;
}
async function detectCurrentWorkspace(currentPath: string): Promise<{ path: string; agentName: string }> {
const git = createGit(currentPath);
const branch = await getCurrentBranch(git);
if (branch.startsWith('agent-')) {
const agentName = branch.replace(/^agent-/, '');
const { getWorkspacePath } = await import('../utils/file-utils');
return {
agentName,
path: getWorkspacePath(currentPath, agentName)
};
}
throw new GitAgentSyncError('Not in an agent workspace. Please specify an agent name.');
}