vigthoria-cli 1.0.2 ā 1.3.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/README.md +122 -8
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +14 -5
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/deploy.d.ts +80 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +514 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/hub.d.ts +40 -0
- package/dist/commands/hub.d.ts.map +1 -0
- package/dist/commands/hub.js +289 -0
- package/dist/commands/hub.js.map +1 -0
- package/dist/commands/repo.d.ts +80 -0
- package/dist/commands/repo.d.ts.map +1 -0
- package/dist/commands/repo.js +585 -0
- package/dist/commands/repo.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +302 -4
- package/dist/index.js.map +1 -1
- package/dist/utils/api.d.ts.map +1 -1
- package/dist/utils/api.js +37 -27
- package/dist/utils/api.js.map +1 -1
- package/dist/utils/tools.d.ts +6 -0
- package/dist/utils/tools.d.ts.map +1 -1
- package/dist/utils/tools.js +269 -15
- package/dist/utils/tools.js.map +1 -1
- package/package.json +5 -2
- package/src/commands/config.ts +14 -5
- package/src/commands/deploy.ts +609 -0
- package/src/commands/hub.ts +382 -0
- package/src/commands/repo.ts +701 -0
- package/src/index.ts +343 -4
- package/src/utils/api.ts +44 -28
- package/src/utils/tools.ts +283 -16
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vigthoria CLI - Hub/Marketplace Commands
|
|
3
|
+
*
|
|
4
|
+
* In-flow marketplace discovery and module activation
|
|
5
|
+
* Enables pay-as-you-go module usage directly from the terminal
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import { Config } from '../utils/config.js';
|
|
10
|
+
import { Logger } from '../utils/logger.js';
|
|
11
|
+
|
|
12
|
+
const API_BASE = 'https://api.vigthoria.io';
|
|
13
|
+
|
|
14
|
+
interface Module {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
endpoint: string;
|
|
19
|
+
documentation: string;
|
|
20
|
+
pricing: {
|
|
21
|
+
unit: string;
|
|
22
|
+
cost: number;
|
|
23
|
+
example: string;
|
|
24
|
+
};
|
|
25
|
+
status: string;
|
|
26
|
+
category: string;
|
|
27
|
+
tags: string[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface SearchResult extends Module {
|
|
31
|
+
score: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface ModulesResponse {
|
|
35
|
+
modules: Module[];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface SearchResponse {
|
|
39
|
+
results: SearchResult[];
|
|
40
|
+
suggestion?: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface ActiveModulesResponse {
|
|
44
|
+
allAccess: boolean;
|
|
45
|
+
tier: string;
|
|
46
|
+
activeModules: Module[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface ActivateResponse {
|
|
50
|
+
message: string;
|
|
51
|
+
documentation: string;
|
|
52
|
+
endpoints: Array<{ method: string; path: string; description: string }>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
interface ModuleDetailResponse extends Module {
|
|
56
|
+
rateLimits: Record<string, number>;
|
|
57
|
+
endpoints: Array<{ method: string; path: string; description: string }>;
|
|
58
|
+
codeExamples?: { curl?: string; node?: string };
|
|
59
|
+
external: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export class HubCommand {
|
|
63
|
+
private config: Config;
|
|
64
|
+
private logger: Logger;
|
|
65
|
+
|
|
66
|
+
constructor(config: Config, logger: Logger) {
|
|
67
|
+
this.config = config;
|
|
68
|
+
this.logger = logger;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Search for modules by natural language query
|
|
73
|
+
*/
|
|
74
|
+
async search(query: string): Promise<void> {
|
|
75
|
+
console.log(chalk.cyan('\nš Searching Vigthoria Module Hub...\n'));
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
const response = await fetch(`${API_BASE}/api/modules/search`, {
|
|
79
|
+
method: 'POST',
|
|
80
|
+
headers: {
|
|
81
|
+
'Content-Type': 'application/json'
|
|
82
|
+
},
|
|
83
|
+
body: JSON.stringify({ query })
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
if (!response.ok) {
|
|
87
|
+
throw new Error(`Search failed: ${response.statusText}`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const data = await response.json() as SearchResponse;
|
|
91
|
+
|
|
92
|
+
if (data.results.length === 0) {
|
|
93
|
+
console.log(chalk.yellow('No modules found matching your query.'));
|
|
94
|
+
console.log(chalk.gray('Try: vigthoria hub list to see all available modules\n'));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
console.log(chalk.green(`Found ${data.results.length} module(s):\n`));
|
|
99
|
+
|
|
100
|
+
data.results.forEach((module: SearchResult, index: number) => {
|
|
101
|
+
const statusColor = module.status === 'active' ? chalk.green : chalk.gray;
|
|
102
|
+
console.log(chalk.bold.white(` ${index + 1}. ${module.name}`));
|
|
103
|
+
console.log(chalk.gray(` ${module.description.substring(0, 80)}...`));
|
|
104
|
+
console.log(chalk.cyan(` š° ${module.pricing.example}`));
|
|
105
|
+
console.log(statusColor(` š Status: ${module.status.toUpperCase()}`));
|
|
106
|
+
console.log(chalk.gray(` š ${module.documentation}`));
|
|
107
|
+
console.log();
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
if (data.suggestion) {
|
|
111
|
+
console.log(chalk.cyan(`š” ${data.suggestion}`));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
console.log(chalk.gray('\nTo activate a module: vigthoria hub activate <module-name>'));
|
|
115
|
+
console.log(chalk.gray('Example: vigthoria hub activate music\n'));
|
|
116
|
+
|
|
117
|
+
} catch (error) {
|
|
118
|
+
const errMsg = error instanceof Error ? error.message : 'Unknown error';
|
|
119
|
+
console.log(chalk.red(`Error: ${errMsg}`));
|
|
120
|
+
console.log(chalk.gray('Make sure you have an active internet connection.'));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* List all available modules
|
|
126
|
+
*/
|
|
127
|
+
async list(options: { category?: string }): Promise<void> {
|
|
128
|
+
console.log(chalk.cyan('\nš¦ Vigthoria Module Hub\n'));
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
let url = `${API_BASE}/api/modules`;
|
|
132
|
+
if (options.category) {
|
|
133
|
+
url += `?category=${options.category}`;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const response = await fetch(url);
|
|
137
|
+
const data = await response.json() as ModulesResponse;
|
|
138
|
+
|
|
139
|
+
console.log(chalk.bold.white('Available Modules:\n'));
|
|
140
|
+
|
|
141
|
+
// Group by category
|
|
142
|
+
const grouped = data.modules.reduce((acc: Record<string, Module[]>, module: Module) => {
|
|
143
|
+
if (!acc[module.category]) acc[module.category] = [];
|
|
144
|
+
acc[module.category].push(module);
|
|
145
|
+
return acc;
|
|
146
|
+
}, {});
|
|
147
|
+
|
|
148
|
+
Object.entries(grouped).forEach(([category, modules]) => {
|
|
149
|
+
console.log(chalk.cyan.bold(` ${category.toUpperCase()}`));
|
|
150
|
+
console.log(chalk.gray(' ' + 'ā'.repeat(50)));
|
|
151
|
+
|
|
152
|
+
modules.forEach((module: Module) => {
|
|
153
|
+
console.log(chalk.white(` š¦ ${module.name.padEnd(25)} ${chalk.gray(module.id)}`));
|
|
154
|
+
console.log(chalk.gray(` ${module.description.substring(0, 60)}...`));
|
|
155
|
+
console.log(chalk.yellow(` ${module.pricing.example}`));
|
|
156
|
+
console.log();
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
console.log(chalk.gray('ā'.repeat(60)));
|
|
161
|
+
console.log(chalk.cyan('\nCommands:'));
|
|
162
|
+
console.log(chalk.gray(' vigthoria hub search "generate music" - Semantic search'));
|
|
163
|
+
console.log(chalk.gray(' vigthoria hub activate <module> - Activate module'));
|
|
164
|
+
console.log(chalk.gray(' vigthoria hub active - Show active modules'));
|
|
165
|
+
console.log(chalk.gray(' vigthoria hub info <module> - Module details\n'));
|
|
166
|
+
|
|
167
|
+
} catch (error) {
|
|
168
|
+
const errMsg = error instanceof Error ? error.message : 'Unknown error';
|
|
169
|
+
console.log(chalk.red(`Error: ${errMsg}`));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Activate a module for the current user
|
|
175
|
+
*/
|
|
176
|
+
async activate(moduleId: string): Promise<void> {
|
|
177
|
+
const authToken = this.config.get('authToken');
|
|
178
|
+
|
|
179
|
+
if (!authToken) {
|
|
180
|
+
console.log(chalk.red('\nā Not authenticated. Run: vigthoria login\n'));
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
console.log(chalk.cyan(`\nš Activating module: ${moduleId}...\n`));
|
|
185
|
+
|
|
186
|
+
try {
|
|
187
|
+
const response = await fetch(`${API_BASE}/api/modules/${moduleId}/activate`, {
|
|
188
|
+
method: 'POST',
|
|
189
|
+
headers: {
|
|
190
|
+
'Authorization': `Bearer ${authToken}`,
|
|
191
|
+
'Content-Type': 'application/json'
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
if (!response.ok) {
|
|
196
|
+
const errorData = await response.json() as { error?: string };
|
|
197
|
+
throw new Error(errorData.error || response.statusText);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const data = await response.json() as ActivateResponse;
|
|
201
|
+
|
|
202
|
+
console.log(chalk.green(`ā
${data.message}`));
|
|
203
|
+
console.log();
|
|
204
|
+
console.log(chalk.white('š Documentation:'));
|
|
205
|
+
console.log(chalk.gray(` ${data.documentation}`));
|
|
206
|
+
console.log();
|
|
207
|
+
console.log(chalk.white('š Available Endpoints:'));
|
|
208
|
+
data.endpoints.forEach((ep) => {
|
|
209
|
+
console.log(chalk.gray(` ${ep.method.padEnd(6)} ${ep.path}`));
|
|
210
|
+
console.log(chalk.gray(` ${ep.description}`));
|
|
211
|
+
});
|
|
212
|
+
console.log();
|
|
213
|
+
console.log(chalk.cyan('š” Quick Start:'));
|
|
214
|
+
console.log(chalk.gray(` Use your API key in requests:`));
|
|
215
|
+
console.log(chalk.gray(` Authorization: Bearer ${authToken.substring(0, 8)}...`));
|
|
216
|
+
console.log();
|
|
217
|
+
|
|
218
|
+
} catch (error) {
|
|
219
|
+
const errMsg = error instanceof Error ? error.message : 'Unknown error';
|
|
220
|
+
console.log(chalk.red(`ā Activation failed: ${errMsg}`));
|
|
221
|
+
console.log(chalk.gray('\nMake sure the module ID is correct.'));
|
|
222
|
+
console.log(chalk.gray('Run: vigthoria hub list to see available modules.'));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Show currently active modules for user
|
|
228
|
+
*/
|
|
229
|
+
async active(): Promise<void> {
|
|
230
|
+
const authToken = this.config.get('authToken');
|
|
231
|
+
|
|
232
|
+
if (!authToken) {
|
|
233
|
+
console.log(chalk.red('\nā Not authenticated. Run: vigthoria login\n'));
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
console.log(chalk.cyan('\nš¦ Your Active Modules\n'));
|
|
238
|
+
|
|
239
|
+
try {
|
|
240
|
+
const response = await fetch(`${API_BASE}/api/modules/active`, {
|
|
241
|
+
headers: {
|
|
242
|
+
'Authorization': `Bearer ${authToken}`
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
if (!response.ok) {
|
|
247
|
+
throw new Error(`Failed to fetch: ${response.statusText}`);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const data = await response.json() as ActiveModulesResponse;
|
|
251
|
+
|
|
252
|
+
if (data.allAccess) {
|
|
253
|
+
console.log(chalk.green('š You have access to ALL modules!\n'));
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
console.log(chalk.white(`Tier: ${chalk.cyan.bold(data.tier.toUpperCase())}`));
|
|
257
|
+
console.log();
|
|
258
|
+
|
|
259
|
+
if (data.activeModules.length === 0) {
|
|
260
|
+
console.log(chalk.yellow('No modules activated yet.'));
|
|
261
|
+
console.log(chalk.gray('\nActivate modules with: vigthoria hub activate <module>'));
|
|
262
|
+
} else {
|
|
263
|
+
console.log(chalk.white('Active modules:'));
|
|
264
|
+
data.activeModules.forEach((module: Module) => {
|
|
265
|
+
console.log(chalk.green(` ā
${module.name}`));
|
|
266
|
+
console.log(chalk.gray(` Endpoint: ${module.endpoint}`));
|
|
267
|
+
console.log(chalk.yellow(` Cost: ${module.pricing.example}`));
|
|
268
|
+
console.log();
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
} catch (error) {
|
|
273
|
+
const errMsg = error instanceof Error ? error.message : 'Unknown error';
|
|
274
|
+
console.log(chalk.red(`Error: ${errMsg}`));
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Get detailed info about a specific module
|
|
280
|
+
*/
|
|
281
|
+
async info(moduleId: string): Promise<void> {
|
|
282
|
+
console.log(chalk.cyan(`\nš Module Info: ${moduleId}\n`));
|
|
283
|
+
|
|
284
|
+
try {
|
|
285
|
+
const response = await fetch(`${API_BASE}/api/modules/${moduleId}`);
|
|
286
|
+
|
|
287
|
+
if (!response.ok) {
|
|
288
|
+
throw new Error('Module not found');
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const module = await response.json() as ModuleDetailResponse;
|
|
292
|
+
|
|
293
|
+
console.log(chalk.bold.white(`${module.name}`));
|
|
294
|
+
console.log(chalk.gray('ā'.repeat(50)));
|
|
295
|
+
console.log();
|
|
296
|
+
console.log(chalk.white('Description:'));
|
|
297
|
+
console.log(chalk.gray(` ${module.description}`));
|
|
298
|
+
console.log();
|
|
299
|
+
console.log(chalk.white('Category:'), chalk.cyan(module.category));
|
|
300
|
+
console.log(chalk.white('Tags:'), chalk.gray(module.tags.join(', ')));
|
|
301
|
+
console.log();
|
|
302
|
+
|
|
303
|
+
console.log(chalk.white('š° Pricing:'));
|
|
304
|
+
console.log(chalk.yellow(` ${module.pricing.example}`));
|
|
305
|
+
console.log(chalk.gray(` Billed per ${module.pricing.unit}`));
|
|
306
|
+
console.log();
|
|
307
|
+
|
|
308
|
+
if (module.rateLimits) {
|
|
309
|
+
console.log(chalk.white('š Rate Limits:'));
|
|
310
|
+
Object.entries(module.rateLimits).forEach(([tier, limit]) => {
|
|
311
|
+
console.log(chalk.gray(` ${tier.padEnd(12)} ${limit} requests/minute`));
|
|
312
|
+
});
|
|
313
|
+
console.log();
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (module.endpoints) {
|
|
317
|
+
console.log(chalk.white('š Endpoints:'));
|
|
318
|
+
module.endpoints.forEach((ep) => {
|
|
319
|
+
console.log(chalk.cyan(` ${ep.method.padEnd(6)} ${ep.path}`));
|
|
320
|
+
console.log(chalk.gray(` ${ep.description}`));
|
|
321
|
+
});
|
|
322
|
+
console.log();
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Show code examples if available
|
|
326
|
+
if (module.codeExamples && Object.keys(module.codeExamples).length > 0) {
|
|
327
|
+
console.log(chalk.white('š Code Examples:'));
|
|
328
|
+
|
|
329
|
+
if (module.codeExamples.curl) {
|
|
330
|
+
console.log(chalk.cyan('\n cURL:'));
|
|
331
|
+
console.log(chalk.gray(' ' + module.codeExamples.curl.split('\n').join('\n ')));
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (module.codeExamples.node) {
|
|
335
|
+
console.log(chalk.cyan('\n Node.js:'));
|
|
336
|
+
console.log(chalk.gray(' ' + module.codeExamples.node.split('\n').join('\n ')));
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
console.log();
|
|
341
|
+
console.log(chalk.gray(`Documentation: ${module.documentation}`));
|
|
342
|
+
if (module.external) {
|
|
343
|
+
console.log(chalk.gray(`External URL: ${module.external}`));
|
|
344
|
+
}
|
|
345
|
+
console.log();
|
|
346
|
+
console.log(chalk.cyan('To activate: ') + chalk.white(`vigthoria hub activate ${moduleId}`));
|
|
347
|
+
console.log();
|
|
348
|
+
|
|
349
|
+
} catch (error) {
|
|
350
|
+
const errMsg = error instanceof Error ? error.message : 'Unknown error';
|
|
351
|
+
console.log(chalk.red(`Error: ${errMsg}`));
|
|
352
|
+
console.log(chalk.gray('\nAvailable modules: pay, meet, llm, music, voice, images'));
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Interactive discover mode - prompts user with suggestions
|
|
358
|
+
*/
|
|
359
|
+
async discover(): Promise<void> {
|
|
360
|
+
console.log(chalk.cyan('\nš Vigthoria Module Discovery\n'));
|
|
361
|
+
console.log(chalk.white('What are you building? Describe your project:\n'));
|
|
362
|
+
|
|
363
|
+
// Show common use cases
|
|
364
|
+
console.log(chalk.gray('Examples of what you can build:'));
|
|
365
|
+
console.log(chalk.gray(' ⢠"I need background music for my app"'));
|
|
366
|
+
console.log(chalk.gray(' ⢠"voice narration for videos"'));
|
|
367
|
+
console.log(chalk.gray(' ⢠"AI chatbot for customer support"'));
|
|
368
|
+
console.log(chalk.gray(' ⢠"payment processing for my SaaS"'));
|
|
369
|
+
console.log(chalk.gray(' ⢠"image generation for social media"\n'));
|
|
370
|
+
|
|
371
|
+
console.log(chalk.cyan('Use: vigthoria hub search "<your use case>"'));
|
|
372
|
+
console.log(chalk.gray('The AI will find the best modules for your needs.\n'));
|
|
373
|
+
|
|
374
|
+
// Show pricing tiers
|
|
375
|
+
console.log(chalk.white('š³ Subscription Tiers:'));
|
|
376
|
+
console.log(chalk.gray(' Starter ā¬49/mo 50 credits'));
|
|
377
|
+
console.log(chalk.gray(' Business ā¬199/mo 500 credits'));
|
|
378
|
+
console.log(chalk.gray(' Enterprise ā¬499/mo 2000 credits'));
|
|
379
|
+
console.log();
|
|
380
|
+
console.log(chalk.cyan('Get started: https://landing.vigthoria.io/api-keys.html\n'));
|
|
381
|
+
}
|
|
382
|
+
}
|