version 0.8.1 release, stable release
This commit is contained in:
@@ -7,8 +7,11 @@ class Progress {
|
||||
static spinner = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
||||
static current = 0;
|
||||
static interval = null;
|
||||
static startTime = null;
|
||||
|
||||
static start(message) {
|
||||
this.startTime = Date.now();
|
||||
this.lastMessage = message;
|
||||
process.stdout.write(`${message} ${this.spinner[0]}`);
|
||||
this.interval = setInterval(() => {
|
||||
this.current = (this.current + 1) % this.spinner.length;
|
||||
@@ -21,7 +24,25 @@ class Progress {
|
||||
clearInterval(this.interval);
|
||||
this.interval = null;
|
||||
}
|
||||
process.stdout.write(`\r${finalMessage}\n`);
|
||||
const elapsed = this.getElapsed();
|
||||
const elapsedStr = elapsed ? ` ${color.dim(`(${elapsed})`)}` : '';
|
||||
// Clear the entire line before writing final message
|
||||
const clearLine = '\r\x1b[K'; // Carriage return + clear to end of line
|
||||
if (finalMessage) {
|
||||
process.stdout.write(`${clearLine}${finalMessage}${elapsedStr}\n`);
|
||||
} else {
|
||||
// Just clear the spinner line completely
|
||||
process.stdout.write(`${clearLine}`);
|
||||
}
|
||||
this.startTime = null;
|
||||
this.lastMessage = null;
|
||||
}
|
||||
|
||||
static getElapsed() {
|
||||
if (!this.startTime) return null;
|
||||
const ms = Date.now() - this.startTime;
|
||||
if (ms < 1000) return `${ms}ms`;
|
||||
return `${(ms / 1000).toFixed(1)}s`;
|
||||
}
|
||||
|
||||
static success(message) {
|
||||
@@ -44,6 +65,54 @@ class Progress {
|
||||
const progress = `[${step}/${total}]`;
|
||||
console.log(`${color.dim(progress)} ${message}`);
|
||||
}
|
||||
|
||||
static cached(message) {
|
||||
console.log(`${color.magenta('⚡')} ${message} ${color.dim('(cached)')}`);
|
||||
}
|
||||
|
||||
static tip(message) {
|
||||
console.log(`${color.blue('💡')} ${color.dim('Tip:')} ${message}`);
|
||||
}
|
||||
|
||||
static box(title, lines) {
|
||||
const maxLen = Math.max(title.length, ...lines.map(l => l.replace(/\x1b\[[0-9;]*m/g, '').length));
|
||||
const top = `┌${'─'.repeat(maxLen + 2)}┐`;
|
||||
const bottom = `└${'─'.repeat(maxLen + 2)}┘`;
|
||||
const titleLine = `│ ${color.bold(title.padEnd(maxLen))} │`;
|
||||
|
||||
console.log(top);
|
||||
console.log(titleLine);
|
||||
console.log(`├${'─'.repeat(maxLen + 2)}┤`);
|
||||
lines.forEach(line => {
|
||||
const plainLen = line.replace(/\x1b\[[0-9;]*m/g, '').length;
|
||||
const padding = ' '.repeat(maxLen - plainLen);
|
||||
console.log(`│ ${line}${padding} │`);
|
||||
});
|
||||
console.log(bottom);
|
||||
}
|
||||
|
||||
// Random tips for contextual help
|
||||
static tips = [
|
||||
'Use `g int` for interactive commit wizard with multiple AI suggestions',
|
||||
'Use `g o` to commit and push in one command',
|
||||
'Use `g sg --multiple` to get 3 different commit message suggestions',
|
||||
'Configure your preferences with `g config --set key=value`',
|
||||
'Use `--all` flag to auto-stage all changes',
|
||||
'Use `g a` to amend your last commit',
|
||||
'Use `g sync --rebase` for cleaner history',
|
||||
'Set GEMINI_API_KEY for free AI-powered commits',
|
||||
'Use `g wip` for quick work-in-progress commits',
|
||||
'Use `g stats` to see your commit statistics',
|
||||
];
|
||||
|
||||
static showRandomTip() {
|
||||
const shouldShow = Math.random() < 0.15; // 15% chance
|
||||
if (shouldShow) {
|
||||
const tip = this.tips[Math.floor(Math.random() * this.tips.length)];
|
||||
console.log();
|
||||
this.tip(tip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { Progress };
|
||||
Reference in New Issue
Block a user