vigthoria-cli 1.6.1 → 1.6.4

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 (46) hide show
  1. package/README.md +52 -1
  2. package/dist/commands/chat.d.ts +31 -45
  3. package/dist/commands/chat.d.ts.map +1 -1
  4. package/dist/commands/chat.js +374 -855
  5. package/dist/commands/chat.js.map +1 -1
  6. package/dist/commands/repo.d.ts +10 -0
  7. package/dist/commands/repo.d.ts.map +1 -1
  8. package/dist/commands/repo.js +215 -97
  9. package/dist/commands/repo.js.map +1 -1
  10. package/dist/index.js +32 -4
  11. package/dist/index.js.map +1 -1
  12. package/dist/utils/api.d.ts +8 -0
  13. package/dist/utils/api.d.ts.map +1 -1
  14. package/dist/utils/api.js +183 -42
  15. package/dist/utils/api.js.map +1 -1
  16. package/dist/utils/config.d.ts.map +1 -1
  17. package/dist/utils/config.js +2 -1
  18. package/dist/utils/config.js.map +1 -1
  19. package/dist/utils/tools.d.ts +3 -0
  20. package/dist/utils/tools.d.ts.map +1 -1
  21. package/dist/utils/tools.js +252 -14
  22. package/dist/utils/tools.js.map +1 -1
  23. package/package.json +13 -2
  24. package/install.ps1 +0 -290
  25. package/install.sh +0 -307
  26. package/src/commands/auth.ts +0 -226
  27. package/src/commands/chat.ts +0 -1101
  28. package/src/commands/config.ts +0 -306
  29. package/src/commands/deploy.ts +0 -609
  30. package/src/commands/edit.ts +0 -310
  31. package/src/commands/explain.ts +0 -115
  32. package/src/commands/generate.ts +0 -222
  33. package/src/commands/hub.ts +0 -382
  34. package/src/commands/repo.ts +0 -742
  35. package/src/commands/review.ts +0 -186
  36. package/src/index.ts +0 -601
  37. package/src/types/marked-terminal.d.ts +0 -31
  38. package/src/utils/api.ts +0 -526
  39. package/src/utils/config.ts +0 -241
  40. package/src/utils/files.ts +0 -273
  41. package/src/utils/logger.ts +0 -130
  42. package/src/utils/session.ts +0 -179
  43. package/src/utils/tools.ts +0 -1964
  44. package/test-parse.js +0 -105
  45. package/test-parse2.js +0 -35
  46. package/tsconfig.json +0 -20
package/src/utils/api.ts DELETED
@@ -1,526 +0,0 @@
1
- /**
2
- * API Client for Vigthoria Backend
3
- * Connects to coder.vigthoria.io API endpoints
4
- */
5
-
6
- import axios, { AxiosInstance, AxiosError } from 'axios';
7
- import https from 'https';
8
- import WebSocket from 'ws';
9
- import { Config } from './config.js';
10
- import { Logger } from './logger.js';
11
-
12
- export interface ChatMessage {
13
- role: 'user' | 'assistant' | 'system';
14
- content: string;
15
- }
16
-
17
- export interface ChatResponse {
18
- id: string;
19
- message: string;
20
- model: string;
21
- usage?: {
22
- prompt_tokens: number;
23
- completion_tokens: number;
24
- total_tokens: number;
25
- };
26
- }
27
-
28
- export interface StreamChunk {
29
- type: 'content' | 'done' | 'error';
30
- content?: string;
31
- error?: string;
32
- }
33
-
34
- export interface VigthoriUser {
35
- id: string;
36
- username: string;
37
- email: string;
38
- isAdmin: boolean;
39
- subscription: {
40
- plan: string;
41
- projectLimit: number;
42
- storageLimit: number;
43
- viagen6Access: boolean;
44
- aiModelsLimit: number;
45
- prioritySupport: boolean;
46
- teamCollaboration: boolean;
47
- adminAccess: boolean;
48
- };
49
- }
50
-
51
- export class APIClient {
52
- private client: AxiosInstance;
53
- private modelRouterClient: AxiosInstance;
54
- private config: Config;
55
- private logger: Logger;
56
- private ws: WebSocket | null = null;
57
-
58
- constructor(config: Config, logger: Logger) {
59
- this.config = config;
60
- this.logger = logger;
61
-
62
- // Create HTTPS agent with proper settings for cross-platform compatibility
63
- const httpsAgent = new https.Agent({
64
- rejectUnauthorized: true, // Enforce SSL verification
65
- keepAlive: true,
66
- timeout: 30000,
67
- });
68
-
69
- // Main Vigthoria Coder API (coder.vigthoria.io)
70
- this.client = axios.create({
71
- baseURL: config.get('apiUrl'),
72
- timeout: 120000,
73
- httpsAgent,
74
- headers: {
75
- 'Content-Type': 'application/json',
76
- 'User-Agent': `Vigthoria-CLI/${process.env.npm_package_version || '1.5.7'}`,
77
- },
78
- });
79
-
80
- // Direct AI Models API - bypasses Coder for direct model access
81
- // This is the centralized Vigthoria API that routes to Model Router
82
- this.modelRouterClient = axios.create({
83
- baseURL: config.get('modelsApiUrl') || 'https://api.vigthoria.io',
84
- timeout: 180000, // 3 minutes for model inference
85
- httpsAgent,
86
- headers: {
87
- 'Content-Type': 'application/json',
88
- 'User-Agent': `Vigthoria-CLI/${process.env.npm_package_version || '1.5.9'}`,
89
- },
90
- });
91
-
92
- // Add auth interceptor
93
- this.client.interceptors.request.use((req) => {
94
- const token = this.config.get('authToken');
95
- if (token) {
96
- req.headers.Authorization = `Bearer ${token}`;
97
- req.headers.Cookie = `vigthoria-auth-token=${token}`;
98
- }
99
- return req;
100
- });
101
-
102
- this.modelRouterClient.interceptors.request.use((req) => {
103
- const token = this.config.get('authToken');
104
- if (token) {
105
- req.headers.Authorization = `Bearer ${token}`;
106
- req.headers.Cookie = `vigthoria-auth-token=${token}`;
107
- }
108
- return req;
109
- });
110
-
111
- // Add response interceptor for token refresh
112
- this.client.interceptors.response.use(
113
- (res) => res,
114
- async (error: AxiosError) => {
115
- if (error.response?.status === 401) {
116
- const refreshed = await this.refreshToken();
117
- if (refreshed && error.config) {
118
- return this.client.request(error.config);
119
- }
120
- }
121
- throw error;
122
- }
123
- );
124
- }
125
-
126
- // Authentication - Uses Vigthoria Coder /api/login endpoint
127
- async login(email: string, password: string): Promise<boolean> {
128
- try {
129
- const response = await this.client.post('/api/login', { email, password });
130
-
131
- if (!response.data.success) {
132
- throw new Error(response.data.error || 'Login failed');
133
- }
134
-
135
- const { token, user } = response.data as { token: string; user: VigthoriUser };
136
-
137
- this.config.setAuth({
138
- token,
139
- userId: user.id,
140
- email: user.email,
141
- });
142
-
143
- // Set subscription from user data
144
- this.config.setSubscription({
145
- plan: user.subscription?.plan || 'developer',
146
- status: 'active',
147
- expiresAt: undefined,
148
- });
149
-
150
- return true;
151
- } catch (error) {
152
- const axiosError = error as AxiosError;
153
- const message = (axiosError.response?.data as { error?: string })?.error || (error as Error).message;
154
- this.logger.error('Login failed:', message);
155
- return false;
156
- }
157
- }
158
-
159
- async loginWithToken(token: string): Promise<boolean> {
160
- try {
161
- // Validate token by making a request to user info endpoint
162
- this.config.set('authToken', token);
163
-
164
- const response = await this.client.get('/api/user/profile', {
165
- headers: {
166
- Authorization: `Bearer ${token}`,
167
- Cookie: `vigthoria-auth-token=${token}`,
168
- },
169
- });
170
-
171
- if (response.data && response.data.user) {
172
- const user = response.data.user;
173
-
174
- this.config.setAuth({
175
- token,
176
- userId: user.id,
177
- email: user.email,
178
- });
179
-
180
- this.config.setSubscription({
181
- plan: user.subscription?.plan || user.subscription_plan || 'developer',
182
- status: 'active',
183
- expiresAt: undefined,
184
- });
185
-
186
- return true;
187
- }
188
-
189
- return false;
190
- } catch (error) {
191
- this.config.clearAuth();
192
- this.logger.error('Token validation failed:', (error as Error).message);
193
- return false;
194
- }
195
- }
196
-
197
- private async refreshToken(): Promise<boolean> {
198
- const refreshToken = this.config.get('refreshToken');
199
- if (!refreshToken) return false;
200
-
201
- try {
202
- const response = await this.client.post('/api/token/refresh', {
203
- refresh_token: refreshToken
204
- });
205
- const { token, access_token, refresh_token } = response.data;
206
-
207
- this.config.set('authToken', token || access_token);
208
- if (refresh_token) {
209
- this.config.set('refreshToken', refresh_token);
210
- }
211
-
212
- return true;
213
- } catch {
214
- this.config.clearAuth();
215
- return false;
216
- }
217
- }
218
-
219
- async getSubscriptionStatus(): Promise<void> {
220
- try {
221
- const response = await this.client.get('/api/user/subscription');
222
- const data = response.data;
223
-
224
- this.config.setSubscription({
225
- plan: data.plan || data.subscription_plan || 'developer',
226
- status: data.status || 'active',
227
- expiresAt: data.expiresAt || data.expires_at
228
- });
229
- } catch (error) {
230
- this.logger.debug('Failed to get subscription status:', (error as Error).message);
231
- }
232
- }
233
-
234
- /**
235
- * Chat API - Direct Vigthoria Models API Architecture
236
- *
237
- * PRIMARY: api.vigthoria.io - Direct access to Vigthoria Model Router
238
- * This is the centralized public API for all AI operations.
239
- * Works for both authenticated and unauthenticated users.
240
- *
241
- * FALLBACK: Coder Cloud API - For authenticated users only
242
- *
243
- * NO localhost fallbacks - CLI is for external users, not server-side!
244
- */
245
- async chat(messages: ChatMessage[], model: string, useLocal: boolean = false): Promise<ChatResponse> {
246
- const resolvedModel = this.resolveModelId(model);
247
-
248
- // STRATEGY 1: Direct Vigthoria Models API (api.vigthoria.io)
249
- // This is the preferred method - direct access to Model Router
250
- try {
251
- this.logger.debug(`Direct Vigthoria Models API: ${resolvedModel}`);
252
- const token = this.config.get('authToken');
253
- const response = await this.modelRouterClient.post('/v1/chat/completions', {
254
- model: resolvedModel,
255
- messages,
256
- max_tokens: this.config.get('preferences').maxTokens,
257
- temperature: 0.7,
258
- stream: false,
259
- }, {
260
- headers: token ? { Authorization: `Bearer ${token}` } : {},
261
- });
262
-
263
- if (response.data.choices && response.data.choices.length > 0) {
264
- return {
265
- id: response.data.id || `vigthoria-${Date.now()}`,
266
- message: response.data.choices[0].message?.content || response.data.choices[0].text,
267
- model: response.data.model || model,
268
- usage: response.data.usage,
269
- };
270
- }
271
- this.logger.debug('Direct API returned no choices');
272
- } catch (error: any) {
273
- const errMsg = error.response?.data?.error || error.message || 'Unknown error';
274
- this.logger.debug(`Direct Vigthoria Models API failed: ${errMsg}`);
275
- // Continue to fallback
276
- }
277
-
278
- // STRATEGY 2: Vigthoria Cloud API via Coder (authenticated users only)
279
- if (this.config.isAuthenticated()) {
280
- try {
281
- this.logger.debug(`Vigthoria Cloud API fallback: ${resolvedModel}`);
282
- const response = await this.client.post('/api/ai/chat', {
283
- messages,
284
- model: resolvedModel,
285
- maxTokens: this.config.get('preferences').maxTokens,
286
- temperature: 0.7,
287
- });
288
-
289
- if (response.data.success !== false) {
290
- return {
291
- id: response.data.id || `vigthoria-coder-${Date.now()}`,
292
- message: response.data.response || response.data.message || response.data.content,
293
- model: response.data.model || model,
294
- usage: response.data.usage,
295
- };
296
- }
297
- this.logger.debug(`Cloud API returned success=false`);
298
- } catch (error: any) {
299
- const errMsg = error.response?.data?.error || error.message || 'Unknown error';
300
- this.logger.debug(`Vigthoria Cloud API failed: ${errMsg}`);
301
- }
302
- }
303
-
304
- // No more localhost fallbacks - CLI is for external users!
305
- throw new Error('AI service unavailable. Please check your internet connection or try again later.');
306
- }
307
-
308
- // Streaming chat
309
- async *chatStream(
310
- messages: ChatMessage[],
311
- model: string
312
- ): AsyncGenerator<StreamChunk> {
313
- const wsUrl = this.config.get('wsUrl');
314
- const token = this.config.get('authToken');
315
-
316
- return new Promise((resolve, reject) => {
317
- const ws = new WebSocket(`${wsUrl}/chat`, {
318
- headers: { Authorization: `Bearer ${token}` },
319
- });
320
-
321
- ws.on('open', () => {
322
- ws.send(JSON.stringify({
323
- type: 'chat',
324
- messages,
325
- model: this.resolveModelId(model),
326
- stream: true,
327
- }));
328
- });
329
-
330
- ws.on('message', (data) => {
331
- const chunk = JSON.parse(data.toString());
332
- // Yield chunk - but this pattern won't work directly
333
- // Need to use event emitter pattern instead
334
- });
335
-
336
- ws.on('error', (error) => {
337
- reject(error);
338
- });
339
-
340
- ws.on('close', () => {
341
- resolve(undefined);
342
- });
343
- });
344
- }
345
-
346
- // Non-streaming alternative with callback
347
- async chatWithCallback(
348
- messages: ChatMessage[],
349
- model: string,
350
- onChunk: (chunk: string) => void,
351
- onDone: () => void,
352
- onError: (error: Error) => void
353
- ): Promise<void> {
354
- const wsUrl = this.config.get('wsUrl');
355
- const token = this.config.get('authToken');
356
-
357
- return new Promise((resolve, reject) => {
358
- const ws = new WebSocket(`${wsUrl}/chat`, {
359
- headers: { Authorization: `Bearer ${token}` },
360
- });
361
-
362
- ws.on('open', () => {
363
- ws.send(JSON.stringify({
364
- type: 'chat',
365
- messages,
366
- model: this.resolveModelId(model),
367
- stream: true,
368
- }));
369
- });
370
-
371
- ws.on('message', (data) => {
372
- try {
373
- const chunk = JSON.parse(data.toString());
374
- if (chunk.type === 'content') {
375
- onChunk(chunk.content);
376
- } else if (chunk.type === 'done') {
377
- onDone();
378
- ws.close();
379
- resolve();
380
- } else if (chunk.type === 'error') {
381
- onError(new Error(chunk.error));
382
- ws.close();
383
- reject(new Error(chunk.error));
384
- }
385
- } catch (e) {
386
- // Raw text chunk
387
- onChunk(data.toString());
388
- }
389
- });
390
-
391
- ws.on('error', (error) => {
392
- onError(error as Error);
393
- reject(error);
394
- });
395
-
396
- ws.on('close', () => {
397
- resolve();
398
- });
399
- });
400
- }
401
-
402
- // Code operations - Using Vigthoria Centralized API
403
- async generateCode(prompt: string, language: string, model: string): Promise<string> {
404
- const response = await this.client.post('/api/ai/generate', {
405
- prompt,
406
- language,
407
- model: this.resolveModelId(model),
408
- });
409
-
410
- return response.data.code;
411
- }
412
-
413
- // Senior Developer Mode - Planning + Generation + Quality Check
414
- async generateProject(prompt: string, projectType: string, model: string): Promise<{
415
- code: string;
416
- plan?: any;
417
- quality?: {
418
- lineCount: number;
419
- score: number;
420
- checks: {
421
- hasAnimations: boolean;
422
- hasNeonEffects: boolean;
423
- hasResponsive: boolean;
424
- hasFontAwesome: boolean;
425
- hasGoogleFonts: boolean;
426
- };
427
- };
428
- }> {
429
- const response = await this.client.post('/api/ai/generate-project', {
430
- prompt,
431
- projectType,
432
- model: this.resolveModelId(model),
433
- }, {
434
- timeout: 300000, // 5 minutes for complex generation
435
- });
436
-
437
- return {
438
- code: response.data.code,
439
- plan: response.data.plan,
440
- quality: response.data.quality,
441
- };
442
- }
443
-
444
- async explainCode(code: string, language: string): Promise<string> {
445
- const response = await this.client.post('/api/ai/explain', {
446
- code,
447
- language,
448
- });
449
-
450
- return response.data.explanation;
451
- }
452
-
453
- async reviewCode(code: string, language: string): Promise<{
454
- score: number;
455
- issues: { type: string; line: number; message: string; severity: string }[];
456
- suggestions: string[];
457
- }> {
458
- const response = await this.client.post('/api/ai/review', {
459
- code,
460
- language,
461
- });
462
-
463
- return response.data;
464
- }
465
-
466
- async fixCode(code: string, language: string, fixType: string): Promise<{
467
- fixed: string;
468
- changes: { line: number; before: string; after: string; reason: string }[];
469
- }> {
470
- const response = await this.client.post('/api/ai/fix', {
471
- code,
472
- language,
473
- fixType,
474
- });
475
-
476
- return response.data;
477
- }
478
-
479
- // Model resolution - maps Vigthoria model names to internal IDs
480
- // INTERNAL USE ONLY - users see only Vigthoria branding
481
- private resolveModelId(shortName: string): string {
482
- const modelMap: Record<string, string> = {
483
- // ═══════════════════════════════════════════════════════════════
484
- // VIGTHORIA LOCAL - Self-hosted models
485
- // ═══════════════════════════════════════════════════════════════
486
- 'fast': 'vigthoria-fast-1.7b',
487
- 'mini': 'vigthoria-fast-1.7b',
488
- 'balanced': 'vigthoria-balanced-4b',
489
- 'creative': 'vigthoria-creative-9b-v4',
490
-
491
- // Code Models - 30B is the default powerhouse
492
- 'code': 'qwen3-coder:latest', // Internal: qwen3-coder 30B
493
- 'code-30b': 'qwen3-coder:latest',
494
- 'code-8b': 'vigthoria-v2-code-8b',
495
- 'pro': 'qwen3-coder:latest',
496
-
497
- // ═══════════════════════════════════════════════════════════════
498
- // VIGTHORIA CLOUD - Premium cloud models (internal routing)
499
- // ═══════════════════════════════════════════════════════════════
500
- 'cloud': 'deepseek-v3.1:671b-cloud',
501
- 'cloud-reason': 'moonshotai/kimi-k2.5',
502
- 'agent': 'deepseek-v3.1:671b-cloud',
503
- 'ultra': 'deepseek-v3.1:671b-cloud',
504
- };
505
-
506
- // If already a full model ID, return as-is
507
- if (shortName.includes('vigthoria') || shortName.includes('/') || shortName.includes(':')) {
508
- if (modelMap[shortName]) {
509
- return modelMap[shortName];
510
- }
511
- return shortName;
512
- }
513
-
514
- return modelMap[shortName] || 'qwen3-coder:latest'; // Default to 30B
515
- }
516
-
517
- // Health check
518
- async healthCheck(): Promise<boolean> {
519
- try {
520
- const response = await this.client.get('/api/health', { timeout: 10000 });
521
- return response.data?.status === 'ok' || response.data?.healthy === true;
522
- } catch {
523
- return false;
524
- }
525
- }
526
- }