feat(mod_commit): Add CLI UI helpers and improve commit workflow with progress, recommendations and summary
This commit is contained in:
196
ts/mod_commit/mod.ui.ts
Normal file
196
ts/mod_commit/mod.ui.ts
Normal file
@@ -0,0 +1,196 @@
|
||||
import { logger } from '../gitzone.logging.js';
|
||||
|
||||
/**
|
||||
* UI helper module for beautiful CLI output
|
||||
*/
|
||||
|
||||
interface ICommitSummary {
|
||||
projectType: string;
|
||||
branch: string;
|
||||
commitType: string;
|
||||
commitScope: string;
|
||||
commitMessage: string;
|
||||
newVersion: string;
|
||||
commitSha?: string;
|
||||
pushed: boolean;
|
||||
repoUrl?: string;
|
||||
}
|
||||
|
||||
interface IRecommendation {
|
||||
recommendedNextVersion: string;
|
||||
recommendedNextVersionLevel: string;
|
||||
recommendedNextVersionScope: string;
|
||||
recommendedNextVersionMessage: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a header with a box around it
|
||||
*/
|
||||
export function printHeader(title: string): void {
|
||||
const width = 57;
|
||||
const padding = Math.max(0, width - title.length - 2);
|
||||
const leftPad = Math.floor(padding / 2);
|
||||
const rightPad = padding - leftPad;
|
||||
|
||||
console.log('');
|
||||
console.log('╭─' + '─'.repeat(width) + '─╮');
|
||||
console.log('│ ' + title + ' '.repeat(rightPad + leftPad) + ' │');
|
||||
console.log('╰─' + '─'.repeat(width) + '─╯');
|
||||
console.log('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a section with a border
|
||||
*/
|
||||
export function printSection(title: string, lines: string[]): void {
|
||||
const width = 59;
|
||||
|
||||
console.log('┌─ ' + title + ' ' + '─'.repeat(Math.max(0, width - title.length - 3)) + '┐');
|
||||
console.log('│' + ' '.repeat(width) + '│');
|
||||
|
||||
for (const line of lines) {
|
||||
const padding = width - line.length;
|
||||
console.log('│ ' + line + ' '.repeat(Math.max(0, padding - 2)) + '│');
|
||||
}
|
||||
|
||||
console.log('│' + ' '.repeat(width) + '│');
|
||||
console.log('└─' + '─'.repeat(width) + '─┘');
|
||||
console.log('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Print AI recommendations in a nice box
|
||||
*/
|
||||
export function printRecommendation(recommendation: IRecommendation): void {
|
||||
const lines = [
|
||||
`Suggested Version: v${recommendation.recommendedNextVersion}`,
|
||||
`Suggested Type: ${recommendation.recommendedNextVersionLevel}`,
|
||||
`Suggested Scope: ${recommendation.recommendedNextVersionScope}`,
|
||||
`Suggested Message: ${recommendation.recommendedNextVersionMessage}`,
|
||||
];
|
||||
|
||||
printSection('📊 AI Recommendations', lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a progress step
|
||||
*/
|
||||
export function printStep(
|
||||
current: number,
|
||||
total: number,
|
||||
description: string,
|
||||
status: 'in-progress' | 'done' | 'error'
|
||||
): void {
|
||||
const statusIcon = status === 'done' ? '✓' : status === 'error' ? '✗' : '⏳';
|
||||
const dots = '.'.repeat(Math.max(0, 40 - description.length));
|
||||
|
||||
console.log(` [${current}/${total}] ${description}${dots} ${statusIcon}`);
|
||||
|
||||
// Clear the line on next update if in progress
|
||||
if (status === 'in-progress') {
|
||||
process.stdout.write('\x1b[1A'); // Move cursor up one line
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get emoji for project type
|
||||
*/
|
||||
function getProjectTypeEmoji(projectType: string): string {
|
||||
switch (projectType) {
|
||||
case 'npm':
|
||||
return '📦 npm';
|
||||
case 'deno':
|
||||
return '🦕 Deno';
|
||||
case 'both':
|
||||
return '🔀 npm + Deno';
|
||||
default:
|
||||
return '❓ Unknown';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get emoji for commit type
|
||||
*/
|
||||
function getCommitTypeEmoji(commitType: string): string {
|
||||
switch (commitType) {
|
||||
case 'fix':
|
||||
return '🔧 fix';
|
||||
case 'feat':
|
||||
return '✨ feat';
|
||||
case 'BREAKING CHANGE':
|
||||
return '💥 BREAKING CHANGE';
|
||||
default:
|
||||
return commitType;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print final commit summary
|
||||
*/
|
||||
export function printSummary(summary: ICommitSummary): void {
|
||||
const lines = [
|
||||
`Project Type: ${getProjectTypeEmoji(summary.projectType)}`,
|
||||
`Branch: 🌿 ${summary.branch}`,
|
||||
`Commit Type: ${getCommitTypeEmoji(summary.commitType)}`,
|
||||
`Scope: 📍 ${summary.commitScope}`,
|
||||
`New Version: 🏷️ v${summary.newVersion}`,
|
||||
];
|
||||
|
||||
if (summary.commitSha) {
|
||||
lines.push(`Commit SHA: 📌 ${summary.commitSha}`);
|
||||
}
|
||||
|
||||
if (summary.pushed) {
|
||||
lines.push(`Remote: ✓ Pushed successfully`);
|
||||
} else {
|
||||
lines.push(`Remote: ⊘ Not pushed (local only)`);
|
||||
}
|
||||
|
||||
if (summary.repoUrl && summary.commitSha) {
|
||||
lines.push('');
|
||||
lines.push(`View at: ${summary.repoUrl}/commit/${summary.commitSha}`);
|
||||
}
|
||||
|
||||
printSection('✅ Commit Summary', lines);
|
||||
|
||||
if (summary.pushed) {
|
||||
console.log('🎉 All done! Your changes are committed and pushed.\n');
|
||||
} else {
|
||||
console.log('✓ Commit created successfully.\n');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print an info message with consistent formatting
|
||||
*/
|
||||
export function printInfo(message: string): void {
|
||||
console.log(` ℹ️ ${message}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a success message
|
||||
*/
|
||||
export function printSuccess(message: string): void {
|
||||
console.log(` ✓ ${message}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a warning message
|
||||
*/
|
||||
export function printWarning(message: string): void {
|
||||
logger.log('warn', `⚠️ ${message}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print an error message
|
||||
*/
|
||||
export function printError(message: string): void {
|
||||
logger.log('error', `✗ ${message}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print commit message being created
|
||||
*/
|
||||
export function printCommitMessage(commitString: string): void {
|
||||
console.log(`\n 📝 Commit: ${commitString}\n`);
|
||||
}
|
||||
Reference in New Issue
Block a user