@nclamvn/vibecode-cli 2.2.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/vibecode.js +86 -0
- package/package.json +1 -1
- package/src/commands/config.js +42 -4
- package/src/commands/deploy.js +728 -0
- package/src/commands/favorite.js +412 -0
- package/src/commands/feedback.js +473 -0
- package/src/commands/go.js +128 -0
- package/src/commands/history.js +249 -0
- package/src/commands/images.js +465 -0
- package/src/commands/voice.js +580 -0
- package/src/commands/watch.js +3 -20
- package/src/index.js +46 -1
- package/src/services/image-service.js +513 -0
- package/src/utils/history.js +357 -0
- package/src/utils/notifications.js +343 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
2
|
+
// VIBECODE CLI - History Command
|
|
3
|
+
// View and manage command history
|
|
4
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
5
|
+
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import inquirer from 'inquirer';
|
|
8
|
+
import { spawn } from 'child_process';
|
|
9
|
+
import {
|
|
10
|
+
loadHistory,
|
|
11
|
+
clearHistory,
|
|
12
|
+
searchHistory,
|
|
13
|
+
getHistoryItem,
|
|
14
|
+
getHistoryStats
|
|
15
|
+
} from '../utils/history.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* History command entry point
|
|
19
|
+
*/
|
|
20
|
+
export async function historyCommand(options = {}) {
|
|
21
|
+
// Clear history
|
|
22
|
+
if (options.clear) {
|
|
23
|
+
const { confirm } = await inquirer.prompt([{
|
|
24
|
+
type: 'confirm',
|
|
25
|
+
name: 'confirm',
|
|
26
|
+
message: 'Clear all command history?',
|
|
27
|
+
default: false
|
|
28
|
+
}]);
|
|
29
|
+
|
|
30
|
+
if (confirm) {
|
|
31
|
+
await clearHistory();
|
|
32
|
+
console.log(chalk.green('\n ✅ History cleared\n'));
|
|
33
|
+
}
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Search history
|
|
38
|
+
if (options.search) {
|
|
39
|
+
return searchHistoryCommand(options.search);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Run command from history
|
|
43
|
+
if (options.run) {
|
|
44
|
+
return runFromHistory(options.run);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Show stats
|
|
48
|
+
if (options.stats) {
|
|
49
|
+
return showHistoryStats();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Show history (default)
|
|
53
|
+
return showHistory(options);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Display command history
|
|
58
|
+
*/
|
|
59
|
+
async function showHistory(options) {
|
|
60
|
+
const history = await loadHistory();
|
|
61
|
+
const limit = parseInt(options.limit) || 20;
|
|
62
|
+
|
|
63
|
+
console.log(chalk.cyan(`
|
|
64
|
+
╭────────────────────────────────────────────────────────────────────╮
|
|
65
|
+
│ 📜 COMMAND HISTORY │
|
|
66
|
+
╰────────────────────────────────────────────────────────────────────╯
|
|
67
|
+
`));
|
|
68
|
+
|
|
69
|
+
if (history.length === 0) {
|
|
70
|
+
console.log(chalk.gray(' No history yet.\n'));
|
|
71
|
+
console.log(chalk.gray(' Run some commands first:\n'));
|
|
72
|
+
console.log(chalk.gray(' vibecode go "Your project description"\n'));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const items = history.slice(0, limit);
|
|
77
|
+
|
|
78
|
+
for (let i = 0; i < items.length; i++) {
|
|
79
|
+
const item = items[i];
|
|
80
|
+
const date = new Date(item.timestamp).toLocaleDateString();
|
|
81
|
+
const time = new Date(item.timestamp).toLocaleTimeString([], {
|
|
82
|
+
hour: '2-digit',
|
|
83
|
+
minute: '2-digit'
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Truncate long commands
|
|
87
|
+
const displayCmd = item.command.length > 60
|
|
88
|
+
? item.command.substring(0, 57) + '...'
|
|
89
|
+
: item.command;
|
|
90
|
+
|
|
91
|
+
console.log(
|
|
92
|
+
chalk.yellow(` ${(i + 1).toString().padStart(2)}. `) +
|
|
93
|
+
chalk.white(displayCmd)
|
|
94
|
+
);
|
|
95
|
+
console.log(chalk.gray(` ${date} ${time}`));
|
|
96
|
+
|
|
97
|
+
if (item.description && item.description !== item.command) {
|
|
98
|
+
const displayDesc = item.description.length > 50
|
|
99
|
+
? item.description.substring(0, 47) + '...'
|
|
100
|
+
: item.description;
|
|
101
|
+
console.log(chalk.gray(` ${displayDesc}`));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (item.projectName) {
|
|
105
|
+
console.log(chalk.gray(` → ${item.projectName}`));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
console.log('');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
console.log(chalk.gray(` Showing ${items.length} of ${history.length} items\n`));
|
|
112
|
+
console.log(chalk.gray(` Commands:`));
|
|
113
|
+
console.log(chalk.gray(` ${chalk.cyan('vibecode history --run <n>')} Re-run command`));
|
|
114
|
+
console.log(chalk.gray(` ${chalk.cyan('vibecode history --search <q>')} Search history`));
|
|
115
|
+
console.log(chalk.gray(` ${chalk.cyan('vibecode history --clear')} Clear history\n`));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Search history and display results
|
|
120
|
+
*/
|
|
121
|
+
async function searchHistoryCommand(query) {
|
|
122
|
+
const results = await searchHistory(query);
|
|
123
|
+
|
|
124
|
+
console.log(chalk.cyan(`\n 🔍 Search results for "${query}":\n`));
|
|
125
|
+
|
|
126
|
+
if (results.length === 0) {
|
|
127
|
+
console.log(chalk.gray(' No matches found.\n'));
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
for (let i = 0; i < Math.min(results.length, 20); i++) {
|
|
132
|
+
const item = results[i];
|
|
133
|
+
const date = new Date(item.timestamp).toLocaleDateString();
|
|
134
|
+
|
|
135
|
+
const displayCmd = item.command.length > 55
|
|
136
|
+
? item.command.substring(0, 52) + '...'
|
|
137
|
+
: item.command;
|
|
138
|
+
|
|
139
|
+
console.log(chalk.yellow(` ${i + 1}. `) + chalk.white(displayCmd));
|
|
140
|
+
console.log(chalk.gray(` ${date}`));
|
|
141
|
+
|
|
142
|
+
if (item.description && item.description !== item.command) {
|
|
143
|
+
const displayDesc = item.description.length > 50
|
|
144
|
+
? item.description.substring(0, 47) + '...'
|
|
145
|
+
: item.description;
|
|
146
|
+
console.log(chalk.gray(` ${displayDesc}`));
|
|
147
|
+
}
|
|
148
|
+
console.log('');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (results.length > 20) {
|
|
152
|
+
console.log(chalk.gray(` ... and ${results.length - 20} more\n`));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Re-run a command from history
|
|
158
|
+
*/
|
|
159
|
+
async function runFromHistory(index) {
|
|
160
|
+
const item = await getHistoryItem(parseInt(index));
|
|
161
|
+
|
|
162
|
+
if (!item) {
|
|
163
|
+
console.log(chalk.red(`\n ❌ History item #${index} not found.\n`));
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
console.log(chalk.cyan(`\n 🔄 Re-running command:\n`));
|
|
168
|
+
console.log(chalk.white(` ${item.command}\n`));
|
|
169
|
+
|
|
170
|
+
if (item.description) {
|
|
171
|
+
console.log(chalk.gray(` ${item.description}\n`));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const { confirm } = await inquirer.prompt([{
|
|
175
|
+
type: 'confirm',
|
|
176
|
+
name: 'confirm',
|
|
177
|
+
message: 'Execute this command?',
|
|
178
|
+
default: true
|
|
179
|
+
}]);
|
|
180
|
+
|
|
181
|
+
if (!confirm) {
|
|
182
|
+
console.log(chalk.gray('\n Cancelled.\n'));
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
console.log(chalk.cyan('\n Executing...\n'));
|
|
187
|
+
|
|
188
|
+
const child = spawn('sh', ['-c', item.command], {
|
|
189
|
+
stdio: 'inherit',
|
|
190
|
+
cwd: process.cwd(),
|
|
191
|
+
shell: true
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
child.on('close', (code) => {
|
|
195
|
+
if (code === 0) {
|
|
196
|
+
console.log(chalk.green('\n ✅ Command completed successfully\n'));
|
|
197
|
+
} else {
|
|
198
|
+
console.log(chalk.yellow(`\n ⚠️ Command exited with code ${code}\n`));
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
child.on('error', (error) => {
|
|
203
|
+
console.log(chalk.red(`\n ❌ Error: ${error.message}\n`));
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Show history statistics
|
|
209
|
+
*/
|
|
210
|
+
async function showHistoryStats() {
|
|
211
|
+
const stats = await getHistoryStats();
|
|
212
|
+
const history = await loadHistory();
|
|
213
|
+
|
|
214
|
+
console.log(chalk.cyan(`
|
|
215
|
+
╭────────────────────────────────────────────────────────────────────╮
|
|
216
|
+
│ 📊 HISTORY STATISTICS │
|
|
217
|
+
╰────────────────────────────────────────────────────────────────────╯
|
|
218
|
+
`));
|
|
219
|
+
|
|
220
|
+
console.log(chalk.white(` Total commands: ${stats.total}`));
|
|
221
|
+
|
|
222
|
+
if (stats.oldest) {
|
|
223
|
+
console.log(chalk.gray(` Oldest: ${new Date(stats.oldest).toLocaleString()}`));
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (stats.newest) {
|
|
227
|
+
console.log(chalk.gray(` Newest: ${new Date(stats.newest).toLocaleString()}`));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Count command types
|
|
231
|
+
if (history.length > 0) {
|
|
232
|
+
const types = {};
|
|
233
|
+
for (const item of history) {
|
|
234
|
+
const cmd = item.command.split(' ')[1] || 'other';
|
|
235
|
+
types[cmd] = (types[cmd] || 0) + 1;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
console.log(chalk.white('\n Command breakdown:'));
|
|
239
|
+
const sorted = Object.entries(types).sort((a, b) => b[1] - a[1]);
|
|
240
|
+
for (const [cmd, count] of sorted.slice(0, 5)) {
|
|
241
|
+
const bar = '█'.repeat(Math.min(count, 20));
|
|
242
|
+
console.log(chalk.gray(` ${cmd.padEnd(12)} ${chalk.cyan(bar)} ${count}`));
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
console.log('');
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export default historyCommand;
|