prab-cli 1.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/LICENSE +15 -0
- package/README.md +272 -0
- package/dist/index.js +374 -0
- package/dist/lib/chat-handler.js +219 -0
- package/dist/lib/config.js +156 -0
- package/dist/lib/context.js +44 -0
- package/dist/lib/groq-models.js +53 -0
- package/dist/lib/groq.js +33 -0
- package/dist/lib/models/groq-provider.js +82 -0
- package/dist/lib/models/provider.js +10 -0
- package/dist/lib/models/registry.js +101 -0
- package/dist/lib/safety.js +109 -0
- package/dist/lib/tools/base.js +115 -0
- package/dist/lib/tools/executor.js +127 -0
- package/dist/lib/tools/file-tools.js +283 -0
- package/dist/lib/tools/git-tools.js +280 -0
- package/dist/lib/tools/shell-tools.js +73 -0
- package/dist/lib/tools/todo-tool.js +105 -0
- package/dist/lib/tracker.js +314 -0
- package/dist/lib/ui.js +578 -0
- package/dist/log-viewer.js +374 -0
- package/dist/types/index.js +5 -0
- package/package.json +75 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const os_1 = __importDefault(require("os"));
|
|
10
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
11
|
+
const LOG_DIR = path_1.default.join(os_1.default.homedir(), '.config', 'groq-cli-tool', 'logs');
|
|
12
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
13
|
+
// STYLING
|
|
14
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
15
|
+
const ICONS = {
|
|
16
|
+
SESSION_START: '🚀',
|
|
17
|
+
PROMPT_RECEIVED: '💬',
|
|
18
|
+
API_REQUEST: '📡',
|
|
19
|
+
API_RESPONSE: '📥',
|
|
20
|
+
API_ERROR: '💥',
|
|
21
|
+
AI_RESPONSE: '🤖',
|
|
22
|
+
AI_TOOL_DECISION: '🧠',
|
|
23
|
+
TOOL_START: '⚙️ ',
|
|
24
|
+
TOOL_SUCCESS: '✅',
|
|
25
|
+
TOOL_ERROR: '❌',
|
|
26
|
+
TOOL_CANCELLED: '🚫',
|
|
27
|
+
MODEL_INIT: '🔌',
|
|
28
|
+
MODEL_SWITCH: '🔄',
|
|
29
|
+
PROMPT_COMPLETE: '✨',
|
|
30
|
+
PROMPT_FAILED: '💔',
|
|
31
|
+
STREAM_CHUNK: '📦',
|
|
32
|
+
ITERATION: '🔁',
|
|
33
|
+
CONTEXT_ATTACHED: '📎',
|
|
34
|
+
DEBUG: '🔍',
|
|
35
|
+
WARNING: '⚠️ ',
|
|
36
|
+
ERROR: '🔥',
|
|
37
|
+
};
|
|
38
|
+
const COLORS = {
|
|
39
|
+
info: chalk_1.default.blue,
|
|
40
|
+
success: chalk_1.default.green,
|
|
41
|
+
error: chalk_1.default.red,
|
|
42
|
+
warn: chalk_1.default.yellow,
|
|
43
|
+
debug: chalk_1.default.gray,
|
|
44
|
+
api: chalk_1.default.magenta,
|
|
45
|
+
ai: chalk_1.default.cyan,
|
|
46
|
+
};
|
|
47
|
+
const BOX = {
|
|
48
|
+
topLeft: '╭',
|
|
49
|
+
topRight: '╮',
|
|
50
|
+
bottomLeft: '╰',
|
|
51
|
+
bottomRight: '╯',
|
|
52
|
+
horizontal: '─',
|
|
53
|
+
vertical: '│',
|
|
54
|
+
cross: '┼',
|
|
55
|
+
};
|
|
56
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
57
|
+
// FORMATTING
|
|
58
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
59
|
+
function formatTime(timestamp) {
|
|
60
|
+
const date = new Date(timestamp);
|
|
61
|
+
const time = date.toLocaleTimeString('en-US', {
|
|
62
|
+
hour12: false,
|
|
63
|
+
hour: '2-digit',
|
|
64
|
+
minute: '2-digit',
|
|
65
|
+
second: '2-digit'
|
|
66
|
+
});
|
|
67
|
+
const ms = String(date.getMilliseconds()).padStart(3, '0');
|
|
68
|
+
return chalk_1.default.dim(`${time}.${ms}`);
|
|
69
|
+
}
|
|
70
|
+
function formatDuration(ms) {
|
|
71
|
+
if (ms < 1000)
|
|
72
|
+
return chalk_1.default.dim(`${ms}ms`);
|
|
73
|
+
return chalk_1.default.dim(`${(ms / 1000).toFixed(2)}s`);
|
|
74
|
+
}
|
|
75
|
+
function formatEntry(entry, verbose) {
|
|
76
|
+
const lines = [];
|
|
77
|
+
const icon = ICONS[entry.event] || '•';
|
|
78
|
+
const color = COLORS[entry.level] || chalk_1.default.white;
|
|
79
|
+
const time = formatTime(entry.timestamp);
|
|
80
|
+
const duration = entry.duration ? ` ${formatDuration(entry.duration)}` : '';
|
|
81
|
+
// Main line
|
|
82
|
+
const mainLine = `${time} ${icon} ${color(entry.message)}${duration}`;
|
|
83
|
+
lines.push(mainLine);
|
|
84
|
+
// Add details for important events
|
|
85
|
+
if (verbose && entry.data) {
|
|
86
|
+
const indent = ' ';
|
|
87
|
+
switch (entry.event) {
|
|
88
|
+
case 'PROMPT_RECEIVED':
|
|
89
|
+
if (entry.data.prompt && entry.data.prompt.length > 100) {
|
|
90
|
+
lines.push(chalk_1.default.dim(`${indent}Full prompt: "${entry.data.prompt.substring(0, 300)}..."`));
|
|
91
|
+
}
|
|
92
|
+
break;
|
|
93
|
+
case 'AI_TOOL_DECISION':
|
|
94
|
+
if (entry.data.toolCalls) {
|
|
95
|
+
entry.data.toolCalls.forEach((tc) => {
|
|
96
|
+
const argsStr = JSON.stringify(tc.args || {});
|
|
97
|
+
lines.push(chalk_1.default.dim(`${indent}→ ${chalk_1.default.cyan(tc.name)}(${argsStr.substring(0, 80)}${argsStr.length > 80 ? '...' : ''})`));
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
break;
|
|
101
|
+
case 'TOOL_START':
|
|
102
|
+
if (entry.data.args && Object.keys(entry.data.args).length > 0) {
|
|
103
|
+
const argsStr = JSON.stringify(entry.data.args);
|
|
104
|
+
lines.push(chalk_1.default.dim(`${indent}Args: ${argsStr.substring(0, 100)}${argsStr.length > 100 ? '...' : ''}`));
|
|
105
|
+
}
|
|
106
|
+
break;
|
|
107
|
+
case 'TOOL_SUCCESS':
|
|
108
|
+
if (entry.data.outputPreview) {
|
|
109
|
+
const preview = entry.data.outputPreview.replace(/\n/g, ' ').substring(0, 80);
|
|
110
|
+
lines.push(chalk_1.default.dim(`${indent}Output: "${preview}${entry.data.outputLength > 80 ? '...' : ''}"`));
|
|
111
|
+
}
|
|
112
|
+
break;
|
|
113
|
+
case 'TOOL_ERROR':
|
|
114
|
+
if (entry.data.error || entry.data.errorMessage) {
|
|
115
|
+
lines.push(chalk_1.default.red(`${indent}Error: ${entry.data.errorMessage || entry.data.error}`));
|
|
116
|
+
}
|
|
117
|
+
if (entry.data.args) {
|
|
118
|
+
const argsStr = JSON.stringify(entry.data.args);
|
|
119
|
+
lines.push(chalk_1.default.dim(`${indent}Args: ${argsStr.substring(0, 150)}${argsStr.length > 150 ? '...' : ''}`));
|
|
120
|
+
}
|
|
121
|
+
break;
|
|
122
|
+
case 'API_ERROR':
|
|
123
|
+
case 'PROMPT_FAILED':
|
|
124
|
+
if (entry.data.error) {
|
|
125
|
+
lines.push(chalk_1.default.red(`${indent}Error: ${entry.data.error}`));
|
|
126
|
+
}
|
|
127
|
+
if (entry.data.stack) {
|
|
128
|
+
const stackLines = entry.data.stack.split('\n').slice(0, 3);
|
|
129
|
+
stackLines.forEach((line) => {
|
|
130
|
+
lines.push(chalk_1.default.dim(`${indent}${line.trim()}`));
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
break;
|
|
134
|
+
case 'API_REQUEST':
|
|
135
|
+
lines.push(chalk_1.default.dim(`${indent}Model: ${entry.data.model}, Messages: ${entry.data.messageCount}, Tools: ${entry.data.toolCount}`));
|
|
136
|
+
break;
|
|
137
|
+
case 'API_RESPONSE':
|
|
138
|
+
lines.push(chalk_1.default.dim(`${indent}Content: ${entry.data.hasContent}, Tool calls: ${entry.data.toolCallCount}`));
|
|
139
|
+
break;
|
|
140
|
+
case 'AI_RESPONSE':
|
|
141
|
+
if (entry.data.content && entry.data.length > 150) {
|
|
142
|
+
lines.push(chalk_1.default.dim(`${indent}(${entry.data.length} chars total)`));
|
|
143
|
+
}
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return lines;
|
|
148
|
+
}
|
|
149
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
150
|
+
// DISPLAY
|
|
151
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
152
|
+
function displayBanner() {
|
|
153
|
+
console.clear();
|
|
154
|
+
console.log('');
|
|
155
|
+
console.log(chalk_1.default.cyan.bold(' ╭─────────────────────────────────────────────────────────────╮'));
|
|
156
|
+
console.log(chalk_1.default.cyan.bold(' │') + chalk_1.default.white.bold(' GROQ CLI - Real-time Logger ') + chalk_1.default.cyan.bold('│'));
|
|
157
|
+
console.log(chalk_1.default.cyan.bold(' │') + chalk_1.default.dim(' Watching all CLI events live ') + chalk_1.default.cyan.bold('│'));
|
|
158
|
+
console.log(chalk_1.default.cyan.bold(' ╰─────────────────────────────────────────────────────────────╯'));
|
|
159
|
+
console.log('');
|
|
160
|
+
}
|
|
161
|
+
function displayWaiting(logFile) {
|
|
162
|
+
const fileName = path_1.default.basename(logFile);
|
|
163
|
+
console.log(chalk_1.default.dim(` Watching: ${fileName}`));
|
|
164
|
+
console.log(chalk_1.default.dim(' Waiting for events... (Press Ctrl+C to exit)'));
|
|
165
|
+
console.log('');
|
|
166
|
+
console.log(chalk_1.default.dim(' ' + '─'.repeat(60)));
|
|
167
|
+
console.log('');
|
|
168
|
+
}
|
|
169
|
+
function displayStats(stats) {
|
|
170
|
+
console.log('');
|
|
171
|
+
console.log(chalk_1.default.cyan.bold(' ╭─────────────────────────────────────────────────────────────╮'));
|
|
172
|
+
console.log(chalk_1.default.cyan.bold(' │') + chalk_1.default.white.bold(' SESSION SUMMARY ') + chalk_1.default.cyan.bold('│'));
|
|
173
|
+
console.log(chalk_1.default.cyan.bold(' ├─────────────────────────────────────────────────────────────┤'));
|
|
174
|
+
console.log(chalk_1.default.cyan.bold(' │') + ` 💬 Prompts: ${String(stats.prompts).padStart(5)} ` + chalk_1.default.cyan.bold('│'));
|
|
175
|
+
console.log(chalk_1.default.cyan.bold(' │') + ` 📡 API Requests: ${String(stats.apiRequests).padStart(5)} ` + chalk_1.default.cyan.bold('│'));
|
|
176
|
+
console.log(chalk_1.default.cyan.bold(' │') + ` 🤖 AI Responses: ${String(stats.aiResponses).padStart(5)} ` + chalk_1.default.cyan.bold('│'));
|
|
177
|
+
console.log(chalk_1.default.cyan.bold(' │') + ` ⚙️ Tool Calls: ${String(stats.toolCalls).padStart(5)} ` + chalk_1.default.cyan.bold('│'));
|
|
178
|
+
console.log(chalk_1.default.cyan.bold(' │') + ` ${stats.errors > 0 ? chalk_1.default.red('❌') : '✅'} Errors: ${String(stats.errors).padStart(5)} ` + chalk_1.default.cyan.bold('│'));
|
|
179
|
+
console.log(chalk_1.default.cyan.bold(' ╰─────────────────────────────────────────────────────────────╯'));
|
|
180
|
+
console.log('');
|
|
181
|
+
}
|
|
182
|
+
function displayHelp() {
|
|
183
|
+
console.log('');
|
|
184
|
+
console.log(chalk_1.default.cyan.bold(' GROQ CLI - Real-time Logger'));
|
|
185
|
+
console.log('');
|
|
186
|
+
console.log(chalk_1.default.white(' Usage:'));
|
|
187
|
+
console.log(chalk_1.default.dim(' npm run log ') + 'Watch latest session (real-time)');
|
|
188
|
+
console.log(chalk_1.default.dim(' npm run log -- -v ') + 'Verbose mode (show details)');
|
|
189
|
+
console.log(chalk_1.default.dim(' npm run log:list ') + 'List all sessions');
|
|
190
|
+
console.log(chalk_1.default.dim(' npm run log:help ') + 'Show this help');
|
|
191
|
+
console.log('');
|
|
192
|
+
console.log(chalk_1.default.white(' Legend:'));
|
|
193
|
+
console.log(` ${ICONS.PROMPT_RECEIVED} User prompt ${ICONS.API_REQUEST} API request ${ICONS.AI_RESPONSE} AI response`);
|
|
194
|
+
console.log(` ${ICONS.AI_TOOL_DECISION} AI decision ${ICONS.TOOL_START} Tool start ${ICONS.TOOL_SUCCESS} Tool success`);
|
|
195
|
+
console.log(` ${ICONS.TOOL_ERROR} Tool error ${ICONS.MODEL_SWITCH} Model switch ${ICONS.PROMPT_COMPLETE} Complete`);
|
|
196
|
+
console.log('');
|
|
197
|
+
console.log(chalk_1.default.white(' Run in two terminals:'));
|
|
198
|
+
console.log(chalk_1.default.dim(' Terminal 1: ') + chalk_1.default.green('npm run dev'));
|
|
199
|
+
console.log(chalk_1.default.dim(' Terminal 2: ') + chalk_1.default.green('npm run log'));
|
|
200
|
+
console.log('');
|
|
201
|
+
}
|
|
202
|
+
function displaySessions() {
|
|
203
|
+
if (!fs_1.default.existsSync(LOG_DIR)) {
|
|
204
|
+
console.log(chalk_1.default.yellow('\n No log directory found. Start the CLI first.\n'));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const files = fs_1.default.readdirSync(LOG_DIR)
|
|
208
|
+
.filter(f => f.endsWith('.jsonl'))
|
|
209
|
+
.map(f => ({
|
|
210
|
+
name: f,
|
|
211
|
+
path: path_1.default.join(LOG_DIR, f),
|
|
212
|
+
stat: fs_1.default.statSync(path_1.default.join(LOG_DIR, f))
|
|
213
|
+
}))
|
|
214
|
+
.sort((a, b) => b.stat.mtime.getTime() - a.stat.mtime.getTime());
|
|
215
|
+
console.log('');
|
|
216
|
+
console.log(chalk_1.default.cyan.bold(' Recent Sessions'));
|
|
217
|
+
console.log(chalk_1.default.dim(' ' + '─'.repeat(50)));
|
|
218
|
+
console.log('');
|
|
219
|
+
if (files.length === 0) {
|
|
220
|
+
console.log(chalk_1.default.yellow(' No sessions found. Start the CLI with `npm run dev`'));
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
files.slice(0, 10).forEach((file, index) => {
|
|
224
|
+
const name = file.name.replace('session-', '').replace('.jsonl', '');
|
|
225
|
+
const date = file.stat.mtime.toLocaleString();
|
|
226
|
+
const size = (file.stat.size / 1024).toFixed(1);
|
|
227
|
+
const latest = index === 0 ? chalk_1.default.green(' (latest)') : '';
|
|
228
|
+
console.log(` ${chalk_1.default.cyan((index + 1) + '.')} ${name}${latest}`);
|
|
229
|
+
console.log(chalk_1.default.dim(` ${date} - ${size} KB`));
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
console.log('');
|
|
233
|
+
}
|
|
234
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
235
|
+
// MAIN WATCHER
|
|
236
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
237
|
+
async function watchLogs(verbose) {
|
|
238
|
+
// Find latest log file
|
|
239
|
+
if (!fs_1.default.existsSync(LOG_DIR)) {
|
|
240
|
+
fs_1.default.mkdirSync(LOG_DIR, { recursive: true });
|
|
241
|
+
}
|
|
242
|
+
const files = fs_1.default.readdirSync(LOG_DIR)
|
|
243
|
+
.filter(f => f.endsWith('.jsonl'))
|
|
244
|
+
.map(f => ({
|
|
245
|
+
name: f,
|
|
246
|
+
path: path_1.default.join(LOG_DIR, f),
|
|
247
|
+
mtime: fs_1.default.statSync(path_1.default.join(LOG_DIR, f)).mtime.getTime()
|
|
248
|
+
}))
|
|
249
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
250
|
+
let logFile = files.length > 0 ? files[0].path : null;
|
|
251
|
+
let lastSize = logFile && fs_1.default.existsSync(logFile) ? fs_1.default.statSync(logFile).size : 0;
|
|
252
|
+
const stats = {
|
|
253
|
+
prompts: 0,
|
|
254
|
+
toolCalls: 0,
|
|
255
|
+
apiRequests: 0,
|
|
256
|
+
errors: 0,
|
|
257
|
+
aiResponses: 0
|
|
258
|
+
};
|
|
259
|
+
displayBanner();
|
|
260
|
+
if (logFile) {
|
|
261
|
+
displayWaiting(logFile);
|
|
262
|
+
// Read existing entries
|
|
263
|
+
const content = fs_1.default.readFileSync(logFile, 'utf-8');
|
|
264
|
+
const lines = content.trim().split('\n').filter(l => l.trim());
|
|
265
|
+
// Show last 15 entries
|
|
266
|
+
const recentLines = lines.slice(-15);
|
|
267
|
+
recentLines.forEach(line => {
|
|
268
|
+
try {
|
|
269
|
+
const entry = JSON.parse(line);
|
|
270
|
+
updateStats(stats, entry);
|
|
271
|
+
formatEntry(entry, verbose).forEach(l => console.log(l));
|
|
272
|
+
}
|
|
273
|
+
catch { }
|
|
274
|
+
});
|
|
275
|
+
if (lines.length > 15) {
|
|
276
|
+
console.log(chalk_1.default.dim(`\n ... ${lines.length - 15} earlier entries hidden\n`));
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
console.log(chalk_1.default.dim(' Waiting for CLI to start...\n'));
|
|
281
|
+
}
|
|
282
|
+
// Watch for new entries
|
|
283
|
+
const interval = setInterval(() => {
|
|
284
|
+
// Check for new log files
|
|
285
|
+
const currentFiles = fs_1.default.readdirSync(LOG_DIR)
|
|
286
|
+
.filter(f => f.endsWith('.jsonl'))
|
|
287
|
+
.map(f => ({
|
|
288
|
+
name: f,
|
|
289
|
+
path: path_1.default.join(LOG_DIR, f),
|
|
290
|
+
mtime: fs_1.default.statSync(path_1.default.join(LOG_DIR, f)).mtime.getTime()
|
|
291
|
+
}))
|
|
292
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
293
|
+
if (currentFiles.length > 0) {
|
|
294
|
+
const latestFile = currentFiles[0].path;
|
|
295
|
+
// If new session started
|
|
296
|
+
if (latestFile !== logFile) {
|
|
297
|
+
logFile = latestFile;
|
|
298
|
+
lastSize = 0;
|
|
299
|
+
console.log('');
|
|
300
|
+
console.log(chalk_1.default.cyan.bold(' ═══ New Session Started ═══'));
|
|
301
|
+
console.log('');
|
|
302
|
+
}
|
|
303
|
+
// Read new content
|
|
304
|
+
if (logFile && fs_1.default.existsSync(logFile)) {
|
|
305
|
+
const stat = fs_1.default.statSync(logFile);
|
|
306
|
+
if (stat.size > lastSize) {
|
|
307
|
+
const content = fs_1.default.readFileSync(logFile, 'utf-8');
|
|
308
|
+
const allLines = content.split('\n').filter(l => l.trim());
|
|
309
|
+
// Calculate how many new lines
|
|
310
|
+
const oldContent = content.substring(0, lastSize);
|
|
311
|
+
const oldLineCount = oldContent.split('\n').filter(l => l.trim()).length;
|
|
312
|
+
const newLines = allLines.slice(oldLineCount);
|
|
313
|
+
newLines.forEach(line => {
|
|
314
|
+
try {
|
|
315
|
+
const entry = JSON.parse(line);
|
|
316
|
+
updateStats(stats, entry);
|
|
317
|
+
formatEntry(entry, verbose).forEach(l => console.log(l));
|
|
318
|
+
}
|
|
319
|
+
catch { }
|
|
320
|
+
});
|
|
321
|
+
lastSize = stat.size;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}, 200);
|
|
326
|
+
// Handle exit
|
|
327
|
+
process.on('SIGINT', () => {
|
|
328
|
+
clearInterval(interval);
|
|
329
|
+
displayStats(stats);
|
|
330
|
+
console.log(chalk_1.default.dim(' Logger stopped.\n'));
|
|
331
|
+
process.exit(0);
|
|
332
|
+
});
|
|
333
|
+
// Keep alive
|
|
334
|
+
await new Promise(() => { });
|
|
335
|
+
}
|
|
336
|
+
function updateStats(stats, entry) {
|
|
337
|
+
switch (entry.event) {
|
|
338
|
+
case 'PROMPT_RECEIVED':
|
|
339
|
+
stats.prompts++;
|
|
340
|
+
break;
|
|
341
|
+
case 'API_REQUEST':
|
|
342
|
+
stats.apiRequests++;
|
|
343
|
+
break;
|
|
344
|
+
case 'AI_RESPONSE':
|
|
345
|
+
stats.aiResponses++;
|
|
346
|
+
break;
|
|
347
|
+
case 'TOOL_START':
|
|
348
|
+
stats.toolCalls++;
|
|
349
|
+
break;
|
|
350
|
+
case 'TOOL_ERROR':
|
|
351
|
+
case 'API_ERROR':
|
|
352
|
+
case 'PROMPT_FAILED':
|
|
353
|
+
case 'ERROR':
|
|
354
|
+
stats.errors++;
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
359
|
+
// ENTRY POINT
|
|
360
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
361
|
+
async function main() {
|
|
362
|
+
const args = process.argv.slice(2);
|
|
363
|
+
if (args.includes('help') || args.includes('-h') || args.includes('--help')) {
|
|
364
|
+
displayHelp();
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
if (args.includes('list') || args.includes('-l')) {
|
|
368
|
+
displaySessions();
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
const verbose = args.includes('-v') || args.includes('--verbose');
|
|
372
|
+
await watchLogs(verbose);
|
|
373
|
+
}
|
|
374
|
+
main().catch(console.error);
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "prab-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "AI-powered coding assistant for your terminal. Built with Groq's lightning-fast LLMs, featuring autonomous tool execution, syntax-highlighted output, and git integration.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"prab-cli": "./dist/index.js",
|
|
8
|
+
"groq-cli": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"start": "node dist/index.js",
|
|
13
|
+
"dev": "ts-node src/index.ts",
|
|
14
|
+
"dev:watch": "nodemon --exec ts-node src/index.ts",
|
|
15
|
+
"log": "ts-node src/log-viewer.ts",
|
|
16
|
+
"log:list": "ts-node src/log-viewer.ts list",
|
|
17
|
+
"log:help": "ts-node src/log-viewer.ts help",
|
|
18
|
+
"prepublishOnly": "npm run build",
|
|
19
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"cli",
|
|
23
|
+
"ai",
|
|
24
|
+
"groq",
|
|
25
|
+
"llm",
|
|
26
|
+
"coding-assistant",
|
|
27
|
+
"terminal",
|
|
28
|
+
"developer-tools",
|
|
29
|
+
"git",
|
|
30
|
+
"code-generation",
|
|
31
|
+
"langchain"
|
|
32
|
+
],
|
|
33
|
+
"author": "Prabhanjan Sharma",
|
|
34
|
+
"license": "ISC",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/prab002/prab-cli.git"
|
|
38
|
+
},
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/prab002/prab-cli/issues"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/prab002/prab-cli#readme",
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18.0.0"
|
|
45
|
+
},
|
|
46
|
+
"files": [
|
|
47
|
+
"dist",
|
|
48
|
+
"README.md",
|
|
49
|
+
"LICENSE"
|
|
50
|
+
],
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@langchain/core": "^1.1.11",
|
|
53
|
+
"@langchain/groq": "^1.0.2",
|
|
54
|
+
"@langchain/openai": "^1.2.2",
|
|
55
|
+
"chalk": "^5.6.2",
|
|
56
|
+
"commander": "^14.0.2",
|
|
57
|
+
"diff": "^8.0.2",
|
|
58
|
+
"dotenv": "^17.2.3",
|
|
59
|
+
"glob": "^13.0.0",
|
|
60
|
+
"groq-sdk": "^0.37.0",
|
|
61
|
+
"inquirer": "^13.1.0",
|
|
62
|
+
"ora": "^9.0.0",
|
|
63
|
+
"simple-git": "^3.30.0",
|
|
64
|
+
"zod": "^4.3.5"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@types/diff": "^7.0.2",
|
|
68
|
+
"@types/glob": "^8.1.0",
|
|
69
|
+
"@types/inquirer": "^9.0.9",
|
|
70
|
+
"@types/node": "^25.0.3",
|
|
71
|
+
"nodemon": "^3.1.11",
|
|
72
|
+
"ts-node": "^10.9.2",
|
|
73
|
+
"typescript": "^5.9.3"
|
|
74
|
+
}
|
|
75
|
+
}
|