slek-ai-cli 1.1.4 → 1.1.6

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.
Files changed (4) hide show
  1. package/auth.js +1 -2
  2. package/cli.js +89 -163
  3. package/package.json +1 -1
  4. package/.env +0 -18
package/auth.js CHANGED
@@ -14,8 +14,7 @@ const boxen = require('boxen');
14
14
  // FIREBASE_API_KEY and GOOGLE_CLIENT_ID are public-safe values.
15
15
  // We use Firebase's signInWithIdp flow, so GOOGLE_CLIENT_SECRET is NOT needed.
16
16
  const FIREBASE_API_KEY = 'AIzaSyBoQHn_adTTj1ZaYZBMHCMSAblCGCIbQG4';
17
- const GOOGLE_CLIENT_ID = '763614479011-32ci230ubh0kuvg1g1ie3jtoeir9orap.apps.googleusercontent.com
18
- '; // e.g. 123456.apps.googleusercontent.com
17
+ const GOOGLE_CLIENT_ID = 'YOUR_GOOGLE_CLIENT_ID'; // e.g. 123456.apps.googleusercontent.com
19
18
 
20
19
  // Additional Firebase config (for future SDK use if needed)
21
20
  const FIREBASE_CONFIG = {
package/cli.js CHANGED
@@ -1,28 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
- require('dotenv').config({
5
- path: require('path').join(__dirname, '.env')
6
- });
7
-
8
- // ─── Auth check ───────────────────────────────────────────────────────────────
4
+ // ─── Auth ─────────────────────────────────────────────────────────────────────
9
5
  const auth = require('./auth');
10
6
 
11
7
  const arg = process.argv[2];
12
8
 
13
- // Handle: slek login / slek logout / slek status
14
- if (arg === 'login') {
15
- auth.login().catch(() => process.exit(1));
16
- return;
17
- }
18
- if (arg === 'logout') {
19
- auth.logout();
20
- process.exit(0);
21
- }
22
- if (arg === 'status') {
23
- auth.status();
24
- process.exit(0);
25
- }
9
+ if (arg === 'login') { auth.login().catch(() => process.exit(1)); return; }
10
+ if (arg === 'logout') { auth.logout(); process.exit(0); }
11
+ if (arg === 'status') { auth.status(); process.exit(0); }
26
12
 
27
13
  // Block access if not logged in
28
14
  if (!auth.isLoggedIn()) {
@@ -40,31 +26,31 @@ if (!auth.isLoggedIn()) {
40
26
  }
41
27
 
42
28
  const readline = require('readline');
43
- const axios = require('axios');
44
- const chalk = require('chalk');
45
- const boxen = require('boxen');
29
+ const axios = require('axios');
30
+ const chalk = require('chalk');
31
+ const boxen = require('boxen');
46
32
  const gradient = require('gradient-string');
47
- const figlet = require('figlet');
33
+ const figlet = require('figlet');
48
34
 
49
- // ─── NOTE: ora v5 is required (CommonJS compatible) ──────────────────────────
50
- // If ora gives errors, run: npm install ora@5
51
35
  let ora;
52
36
  try {
53
37
  ora = require('ora');
54
38
  } catch {
55
- // Fallback spinner if ora fails
56
39
  ora = (opts) => ({
57
- start: () => { process.stdout.write(chalk.cyan(' ⏳ ' + (opts.text || 'Loading...') + '\n')); return { stop: () => {}, fail: () => {} }; },
40
+ start: () => {
41
+ process.stdout.write(chalk.cyan(' ⏳ ' + (opts.text || 'Loading...') + '\n'));
42
+ return { stop: () => {}, fail: () => {} };
43
+ },
58
44
  stop: () => {},
59
45
  fail: () => {},
60
46
  });
61
47
  }
62
48
 
63
- // ─── NVIDIA API Config ────────────────────────────────────────────────────────
49
+ // ─── API Config ───────────────────────────────────────────────────────────────
64
50
  const NVIDIA_API_BASE = 'https://slek-ai-portal.vercel.app/api';
65
- const DEFAULT_MODEL = 'qwen/qwen3.5-122b-a10b';
51
+ const DEFAULT_MODEL = 'qwen/qwen3.5-122b-a10b';
66
52
 
67
- // ─── User config path (stored in user's home, not in project) ─────────────────
53
+ // ─── User config path ─────────────────────────────────────────────────────────
68
54
  const CONFIG_PATH = require('path').join(
69
55
  process.env.APPDATA || process.env.HOME || __dirname,
70
56
  '.slek-config.json'
@@ -75,24 +61,28 @@ function loadConfig() {
75
61
  if (require('fs').existsSync(CONFIG_PATH)) {
76
62
  return JSON.parse(require('fs').readFileSync(CONFIG_PATH, 'utf8'));
77
63
  }
78
- } catch { }
64
+ } catch (_) {}
79
65
  return {};
80
66
  }
81
67
 
82
68
  function saveConfig(data) {
83
69
  const current = loadConfig();
84
- require('fs').writeFileSync(CONFIG_PATH, JSON.stringify({ ...current, ...data }, null, 2), 'utf8');
70
+ require('fs').writeFileSync(
71
+ CONFIG_PATH,
72
+ JSON.stringify({ ...current, ...data }, null, 2),
73
+ 'utf8'
74
+ );
85
75
  }
86
76
 
87
- // ─── Gradient Colors ─────────────────────────────────────────────────────────
77
+ // ─── Gradients ────────────────────────────────────────────────────────────────
88
78
  const nvidiaGradient = gradient(['#76b900', '#00c8ff']);
89
- const userGradient = gradient(['#ff6b6b', '#feca57']);
90
- const aiGradient = gradient(['#48dbfb', '#ff9ff3']);
91
- const thinkGradient = gradient(['#f7971e', '#ffd200']);
79
+ const userGradient = gradient(['#ff6b6b', '#feca57']);
80
+ const aiGradient = gradient(['#48dbfb', '#ff9ff3']);
81
+ const thinkGradient = gradient(['#f7971e', '#ffd200']);
92
82
 
93
- // ─── State ───────────────────────────────────────────────────────────────────
94
- let chatHistory = [];
95
- let apiKey = process.env.NVIDIA_API_KEY || '';
83
+ // ─── State ────────────────────────────────────────────────────────────────────
84
+ let chatHistory = [];
85
+ let apiKey = loadConfig().apiKey || '';
96
86
  const currentUser = auth.getUser();
97
87
 
98
88
  // ─── Helpers ──────────────────────────────────────────────────────────────────
@@ -103,17 +93,14 @@ function clearLine() {
103
93
  // ─── Banner ───────────────────────────────────────────────────────────────────
104
94
  async function showBanner() {
105
95
  console.clear();
106
- const banner = figlet.textSync('SLEK AI', {
107
- font: 'ANSI Shadow',
108
- horizontalLayout: 'default',
109
- });
96
+ const banner = figlet.textSync('SLEK AI', { font: 'ANSI Shadow' });
110
97
  console.log(nvidiaGradient(banner));
111
98
  console.log(
112
99
  boxen(
113
100
  chalk.bold.white('🚀 SLEK AI CLI') + chalk.gray(' — Powered by NVIDIA API\n') +
114
- chalk.gray(''.repeat(42)) + '\n' +
101
+ chalk.gray(''.repeat(42)) + '\n' +
115
102
  chalk.cyan(' User : ') + chalk.green(currentUser ? currentUser.name : 'Unknown') + '\n' +
116
- chalk.gray(''.repeat(42)) + '\n' +
103
+ chalk.gray(''.repeat(42)) + '\n' +
117
104
  chalk.white(' Type ') + chalk.yellow('/help') + chalk.white(' for available commands'),
118
105
  {
119
106
  padding: 1,
@@ -128,87 +115,37 @@ async function showBanner() {
128
115
 
129
116
  // ─── Help ─────────────────────────────────────────────────────────────────────
130
117
  function showHelp() {
131
- const helpBox = boxen(
132
- chalk.bold.cyan('📋 Available Commands\n') +
133
- chalk.gray('═'.repeat(42)) + '\n\n' +
134
- chalk.yellow('/help ') + chalk.white('Show this help menu\n') +
135
- chalk.yellow('/clear ') + chalk.white('Clear chat history\n') +
136
- chalk.yellow('/history ') + chalk.white('Show chat history\n') +
137
- chalk.yellow('/save ') + chalk.white('Save chat to file\n') +
138
- chalk.yellow('/info ') + chalk.white('Show current settings\n') +
139
- chalk.yellow('/exit ') + chalk.white('Exit the CLI\n\n') +
140
- chalk.gray('Or just type anything to chat with AI!'),
141
- {
142
- padding: 1,
143
- margin: { left: 2 },
144
- borderStyle: 'round',
145
- borderColor: 'cyan',
146
- }
118
+ console.log(
119
+ boxen(
120
+ chalk.bold.cyan('📋 Available Commands\n') +
121
+ chalk.gray(''.repeat(42)) + '\n\n' +
122
+ chalk.yellow('/help ') + chalk.white('Show this help menu\n') +
123
+ chalk.yellow('/clear ') + chalk.white('Clear chat history\n') +
124
+ chalk.yellow('/history ') + chalk.white('Show chat history\n') +
125
+ chalk.yellow('/save ') + chalk.white('Save chat to file\n') +
126
+ chalk.yellow('/info ') + chalk.white('Show current settings\n') +
127
+ chalk.yellow('/exit ') + chalk.white('Exit the CLI\n\n') +
128
+ chalk.gray('Or just type anything to chat with AI!'),
129
+ { padding: 1, margin: { left: 2 }, borderStyle: 'round', borderColor: 'cyan' }
130
+ )
147
131
  );
148
- console.log(helpBox);
149
- }
150
-
151
- // ─── Show Models ──────────────────────────────────────────────────────────────
152
- function showModels() {
153
- console.log('\n' + chalk.bold.cyan(' 🤖 Available Models:\n'));
154
- Object.entries(MODELS).forEach(([key, model]) => {
155
- const active = model.id === currentModel ? chalk.green(' ◄ ACTIVE') : '';
156
- const thinking = model.thinking ? chalk.yellow(' [🧠 Thinking]') : '';
157
- console.log(` ${chalk.yellow(key + '.')} ${chalk.white(model.name)}${thinking}${active}`);
158
- });
159
- console.log();
160
- }
161
-
162
- // ─── Change Model ─────────────────────────────────────────────────────────────
163
- async function changeModel(rl) {
164
- showModels();
165
- return new Promise(resolve => {
166
- rl.question(chalk.cyan(' Enter model number (1-7): '), answer => {
167
- const chosen = MODELS[answer.trim()];
168
- if (chosen) {
169
- currentModel = chosen.id;
170
- enableThinking = chosen.thinking || false;
171
- const thinkNote = chosen.thinking ? chalk.yellow(' (Thinking mode ON)') : '';
172
- console.log(chalk.green(`\n ✓ Model: ${chalk.yellow(chosen.name.trim())}${thinkNote}\n`));
173
- } else {
174
- console.log(chalk.red('\n ✗ Invalid choice\n'));
175
- }
176
- resolve();
177
- });
178
- });
179
- }
180
-
181
- // ─── Toggle Thinking ──────────────────────────────────────────────────────────
182
- function toggleThinking() {
183
- enableThinking = !enableThinking;
184
- if (enableThinking) {
185
- console.log(chalk.green('\n 🧠 Thinking mode: ON\n'));
186
- } else {
187
- console.log(chalk.gray('\n 💤 Thinking mode: OFF\n'));
188
- }
189
132
  }
190
133
 
191
-
192
-
193
- // ─── Show Info ────────────────────────────────────────────────────────────────
134
+ // ─── Info ─────────────────────────────────────────────────────────────────────
194
135
  function showInfo() {
195
- const infoBox = boxen(
196
- chalk.bold.white('⚙ Current Settings\n') +
197
- chalk.gray('─'.repeat(40)) + '\n\n' +
198
- chalk.cyan('User : ') + chalk.green(currentUser ? currentUser.name : 'Unknown') + '\n' +
199
- chalk.cyan('Messages : ') + chalk.white(chatHistory.length + ' in history') + '\n' +
200
- chalk.cyan('API URL : ') + chalk.gray(NVIDIA_API_BASE),
201
- {
202
- padding: 1,
203
- margin: { left: 2 },
204
- borderStyle: 'single',
205
- borderColor: 'yellow',
206
- }
136
+ console.log(
137
+ '\n' + boxen(
138
+ chalk.bold.white('⚙ Current Settings\n') +
139
+ chalk.gray(''.repeat(40)) + '\n\n' +
140
+ chalk.cyan('User : ') + chalk.green(currentUser ? currentUser.name : 'Unknown') + '\n' +
141
+ chalk.cyan('Messages : ') + chalk.white(chatHistory.length + ' in history') + '\n' +
142
+ chalk.cyan('API URL : ') + chalk.gray(NVIDIA_API_BASE),
143
+ { padding: 1, margin: { left: 2 }, borderStyle: 'single', borderColor: 'yellow' }
144
+ )
207
145
  );
208
- console.log('\n' + infoBox);
209
146
  }
210
147
 
211
- // ─── Show History ─────────────────────────────────────────────────────────────
148
+ // ─── History ──────────────────────────────────────────────────────────────────
212
149
  function showHistory() {
213
150
  if (chatHistory.length === 0) {
214
151
  console.log(chalk.yellow('\n No chat history yet.\n'));
@@ -239,7 +176,7 @@ async function saveChat() {
239
176
 
240
177
  let content = `SLEK AI CLI - Chat Log\n`;
241
178
  content += `Date: ${new Date().toLocaleString()}\n`;
242
- content += `Model: ${currentModel}\n`;
179
+ content += `Model: ${DEFAULT_MODEL}\n`;
243
180
  content += `${'═'.repeat(50)}\n\n`;
244
181
 
245
182
  chatHistory.forEach(msg => {
@@ -252,13 +189,13 @@ async function saveChat() {
252
189
  });
253
190
 
254
191
  fs.writeFileSync(filepath, content, 'utf8');
255
- console.log(chalk.green(`\n Chat saved to: ${chalk.yellow(filename)}\n`));
192
+ console.log(chalk.green(`\n Chat saved to: ${chalk.yellow(filename)}\n`));
256
193
  }
257
194
 
258
195
  // ─── Stream API Call ──────────────────────────────────────────────────────────
259
196
  async function callNvidiaAPIStream(userMessage) {
260
197
  if (!apiKey) {
261
- throw new Error('API key not configured. Please set NVIDIA_API_KEY in your .env file.');
198
+ throw new Error('API key not set. Ask the admin for your SLEK API key.');
262
199
  }
263
200
 
264
201
  chatHistory.push({ role: 'user', content: userMessage });
@@ -273,19 +210,17 @@ async function callNvidiaAPIStream(userMessage) {
273
210
  ...chatHistory,
274
211
  ];
275
212
 
276
- const payload = {
277
- model: DEFAULT_MODEL,
278
- messages,
279
- max_tokens: 16384,
280
- temperature: 0.60,
281
- top_p: 0.95,
282
- stream: true,
283
- chat_template_kwargs: { enable_thinking: true },
284
- };
285
-
286
213
  const response = await axios.post(
287
214
  `${NVIDIA_API_BASE}/chat-free`,
288
- payload,
215
+ {
216
+ model: DEFAULT_MODEL,
217
+ messages,
218
+ max_tokens: 16384,
219
+ temperature: 0.60,
220
+ top_p: 0.95,
221
+ stream: true,
222
+ chat_template_kwargs: { enable_thinking: true },
223
+ },
289
224
  {
290
225
  headers: {
291
226
  Authorization: `Bearer ${apiKey}`,
@@ -298,8 +233,8 @@ async function callNvidiaAPIStream(userMessage) {
298
233
  );
299
234
 
300
235
  return new Promise((resolve, reject) => {
301
- let fullResponse = '';
302
- let inThinkBlock = false;
236
+ let fullResponse = '';
237
+ let inThinkBlock = false;
303
238
 
304
239
  process.stdout.write('\n ' + aiGradient('✦ SLEK AI: ') + '\n\n ');
305
240
 
@@ -325,12 +260,10 @@ async function callNvidiaAPIStream(userMessage) {
325
260
  continue;
326
261
  }
327
262
 
328
- if (inThinkBlock) {
329
- process.stdout.write(chalk.dim.yellow(token));
330
- } else {
331
- process.stdout.write(chalk.white(token));
332
- }
333
- } catch { /* ignore malformed SSE lines */ }
263
+ process.stdout.write(
264
+ inThinkBlock ? chalk.dim.yellow(token) : chalk.white(token)
265
+ );
266
+ } catch (_) { /* ignore malformed SSE lines */ }
334
267
  }
335
268
  }
336
269
  });
@@ -346,7 +279,7 @@ async function callNvidiaAPIStream(userMessage) {
346
279
  });
347
280
  }
348
281
 
349
- // ─── Process User Input ───────────────────────────────────────────────────────
282
+ // ─── Process Input ────────────────────────────────────────────────────────────
350
283
  async function processInput(input, rl) {
351
284
  const trimmed = input.trim();
352
285
  if (!trimmed) return;
@@ -354,14 +287,14 @@ async function processInput(input, rl) {
354
287
  if (trimmed.startsWith('/')) {
355
288
  const cmd = trimmed.toLowerCase().split(' ')[0];
356
289
  switch (cmd) {
357
- case '/help': showHelp(); break;
290
+ case '/help': showHelp(); break;
358
291
  case '/clear':
359
292
  chatHistory = [];
360
- console.log(chalk.green('\n Chat history cleared!\n'));
293
+ console.log(chalk.green('\n Chat history cleared!\n'));
361
294
  break;
362
- case '/history': showHistory(); break;
363
- case '/save': await saveChat(); break;
364
- case '/info': showInfo(); break;
295
+ case '/history': showHistory(); break;
296
+ case '/save': await saveChat(); break;
297
+ case '/info': showInfo(); break;
365
298
  case '/exit':
366
299
  case '/quit':
367
300
  console.log('\n' + nvidiaGradient(' 👋 Goodbye! Thanks for using SLEK AI CLI\n'));
@@ -375,9 +308,9 @@ async function processInput(input, rl) {
375
308
  }
376
309
 
377
310
  const spinner = ora({
378
- text: chalk.cyan(' Connecting to NVIDIA API...'),
379
- spinner: 'dots',
380
- color: 'cyan',
311
+ text: chalk.cyan(' Connecting to NVIDIA API...'),
312
+ spinner: 'dots',
313
+ color: 'cyan',
381
314
  prefixText: ' ',
382
315
  }).start();
383
316
 
@@ -393,13 +326,10 @@ async function processInput(input, rl) {
393
326
  err.message ||
394
327
  'Unknown error';
395
328
  console.log(
396
- '\n' +
397
- boxen(chalk.red('✗ Error: ') + chalk.white(errMsg), {
398
- padding: 1,
399
- margin: { left: 2 },
400
- borderStyle: 'round',
401
- borderColor: 'red',
402
- }) + '\n'
329
+ '\n' + boxen(
330
+ chalk.red('✗ Error: ') + chalk.white(errMsg),
331
+ { padding: 1, margin: { left: 2 }, borderStyle: 'round', borderColor: 'red' }
332
+ ) + '\n'
403
333
  );
404
334
  }
405
335
  }
@@ -408,9 +338,7 @@ async function processInput(input, rl) {
408
338
  function showPrompt(rl) {
409
339
  const prompt =
410
340
  '\n' +
411
- chalk.gray(' ┌─') +
412
- userGradient(' You ') +
413
- chalk.gray('─────────────────────────────────\n') +
341
+ chalk.gray(' ┌─') + userGradient(' You ') + chalk.gray('─────────────────────────────────\n') +
414
342
  chalk.gray(' └▶ ');
415
343
  rl.setPrompt(prompt);
416
344
  rl.prompt();
@@ -420,11 +348,9 @@ function showPrompt(rl) {
420
348
  async function main() {
421
349
  await showBanner();
422
350
 
423
-
424
-
425
351
  const rl = readline.createInterface({
426
- input: process.stdin,
427
- output: process.stdout,
352
+ input: process.stdin,
353
+ output: process.stdout,
428
354
  terminal: true,
429
355
  });
430
356
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slek-ai-cli",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "description": "SLEK AI CLI — Powered by NVIDIA API",
5
5
  "main": "cli.js",
6
6
  "bin": {
package/.env DELETED
@@ -1,18 +0,0 @@
1
- # NVIDIA API Key (get from https://build.nvidia.com)
2
- NVIDIA_API_KEY=slek-key-98ab6e89f8b636bed33a2cb08148c0b6
3
-
4
- # ─── Firebase Config ───────────────────────────────────────
5
- FIREBASE_API_KEY=AIzaSyBoQHn_adTTj1ZaYZBMHCMSAblCGCIbQG4
6
- FIREBASE_AUTH_DOMAIN=charm-f004f.firebaseapp.com
7
- FIREBASE_PROJECT_ID=charm-f004f
8
- FIREBASE_STORAGE_BUCKET=charm-f004f.firebasestorage.app
9
- FIREBASE_MESSAGING_SENDER_ID=763614479011
10
- FIREBASE_APP_ID=1:763614479011:web:5cd0082b14b78b9c5eb516
11
- FIREBASE_MEASUREMENT_ID=G-0G0F5DT6PC
12
-
13
- # ─── Google OAuth (from Google Cloud Console) ─────────────
14
- # https://console.cloud.google.com → APIs & Services → Credentials → Create OAuth 2.0 Client ID
15
- # Application type: Web application
16
- # Authorized redirect URI: http://localhost:9876/callback
17
- GOOGLE_CLIENT_ID=763614479011-32ci230ubh0kuvg1g1ie3jtoeir9orap.apps.googleusercontent.com
18
- GOOGLE_CLIENT_SECRET=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