vigthoria-cli 1.9.10 → 1.9.19
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 +4 -4
- package/dist/commands/auth.js +48 -65
- package/dist/commands/bridge.js +12 -19
- package/dist/commands/cancel.js +15 -22
- package/dist/commands/chat.d.ts +11 -0
- package/dist/commands/chat.js +404 -248
- package/dist/commands/config.js +31 -71
- package/dist/commands/deploy.js +83 -123
- package/dist/commands/device.d.ts +35 -0
- package/dist/commands/device.js +239 -0
- package/dist/commands/edit.js +32 -39
- package/dist/commands/explain.js +18 -25
- package/dist/commands/fork.js +22 -27
- package/dist/commands/generate.js +37 -44
- package/dist/commands/history.js +20 -25
- package/dist/commands/hub.js +95 -102
- package/dist/commands/index.js +41 -46
- package/dist/commands/legion.d.ts +1 -0
- package/dist/commands/legion.js +162 -209
- package/dist/commands/preview.js +60 -98
- package/dist/commands/replay.js +27 -32
- package/dist/commands/repo.js +103 -141
- package/dist/commands/review.js +29 -36
- package/dist/commands/security.js +5 -12
- package/dist/commands/update.js +15 -49
- package/dist/commands/workflow.d.ts +8 -1
- package/dist/commands/workflow.js +53 -19
- package/dist/index.js +409 -234
- package/dist/utils/api.d.ts +5 -0
- package/dist/utils/api.js +373 -166
- package/dist/utils/bridge-client.js +11 -52
- package/dist/utils/cli-state.d.ts +54 -0
- package/dist/utils/cli-state.js +185 -0
- package/dist/utils/config.d.ts +5 -0
- package/dist/utils/config.js +35 -14
- package/dist/utils/context-ranker.js +15 -21
- package/dist/utils/files.js +5 -42
- package/dist/utils/logger.js +42 -50
- package/dist/utils/post-write-validator.js +22 -29
- package/dist/utils/project-memory.d.ts +56 -0
- package/dist/utils/project-memory.js +289 -0
- package/dist/utils/session.d.ts +29 -3
- package/dist/utils/session.js +137 -85
- package/dist/utils/task-display.js +13 -20
- package/dist/utils/tools.d.ts +19 -0
- package/dist/utils/tools.js +84 -87
- package/dist/utils/workspace-cache.js +18 -26
- package/dist/utils/workspace-stream.js +26 -64
- package/install.ps1 +14 -0
- package/package.json +5 -3
- package/scripts/release/LOCAL_MACHINE_USER_VERIFICATION.md +1 -1
- package/scripts/release/validate-no-go-gates.sh +2 -2
package/dist/commands/repo.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Vigthoria CLI - Repo Commands
|
|
4
3
|
*
|
|
@@ -13,52 +12,16 @@
|
|
|
13
12
|
* vigthoria repo share <name> - Generate shareable link for a project
|
|
14
13
|
* vigthoria repo delete <name> - Remove a project from your Vigthoria Repo
|
|
15
14
|
*/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}));
|
|
27
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
28
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
29
|
-
}) : function(o, v) {
|
|
30
|
-
o["default"] = v;
|
|
31
|
-
});
|
|
32
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
33
|
-
var ownKeys = function(o) {
|
|
34
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
35
|
-
var ar = [];
|
|
36
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
37
|
-
return ar;
|
|
38
|
-
};
|
|
39
|
-
return ownKeys(o);
|
|
40
|
-
};
|
|
41
|
-
return function (mod) {
|
|
42
|
-
if (mod && mod.__esModule) return mod;
|
|
43
|
-
var result = {};
|
|
44
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
45
|
-
__setModuleDefault(result, mod);
|
|
46
|
-
return result;
|
|
47
|
-
};
|
|
48
|
-
})();
|
|
49
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
50
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
51
|
-
};
|
|
52
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
53
|
-
exports.RepoCommand = void 0;
|
|
54
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
55
|
-
const fs = __importStar(require("fs"));
|
|
56
|
-
const path = __importStar(require("path"));
|
|
57
|
-
const logger_js_1 = require("../utils/logger.js");
|
|
58
|
-
const inquirer_1 = __importDefault(require("inquirer"));
|
|
59
|
-
const archiver_1 = __importDefault(require("archiver"));
|
|
60
|
-
const fs_1 = require("fs");
|
|
61
|
-
class RepoCommand {
|
|
15
|
+
import chalk from 'chalk';
|
|
16
|
+
import * as fs from 'fs';
|
|
17
|
+
import * as path from 'path';
|
|
18
|
+
import { createRequire } from 'node:module';
|
|
19
|
+
import { createSpinner, CH } from '../utils/logger.js';
|
|
20
|
+
const require = createRequire(import.meta.url);
|
|
21
|
+
import inquirer from 'inquirer';
|
|
22
|
+
import archiver from 'archiver';
|
|
23
|
+
import { createWriteStream } from 'fs';
|
|
24
|
+
export class RepoCommand {
|
|
62
25
|
config;
|
|
63
26
|
logger;
|
|
64
27
|
apiBase;
|
|
@@ -204,7 +167,7 @@ class RepoCommand {
|
|
|
204
167
|
}
|
|
205
168
|
requireAuth() {
|
|
206
169
|
if (!this.isAuthenticated()) {
|
|
207
|
-
console.log(
|
|
170
|
+
console.log(chalk.red('\n❌ Authentication required. Run: vigthoria login\n'));
|
|
208
171
|
process.exit(1);
|
|
209
172
|
}
|
|
210
173
|
}
|
|
@@ -279,8 +242,8 @@ class RepoCommand {
|
|
|
279
242
|
fs.mkdirSync(tempDir, { recursive: true });
|
|
280
243
|
}
|
|
281
244
|
const archivePath = path.join(tempDir, `project-${Date.now()}.zip`);
|
|
282
|
-
const output =
|
|
283
|
-
const archive = (
|
|
245
|
+
const output = createWriteStream(archivePath);
|
|
246
|
+
const archive = archiver('zip', { zlib: { level: 9 } });
|
|
284
247
|
return new Promise((resolve, reject) => {
|
|
285
248
|
output.on('close', () => resolve(archivePath));
|
|
286
249
|
archive.on('error', (err) => reject(err));
|
|
@@ -313,16 +276,16 @@ class RepoCommand {
|
|
|
313
276
|
this.requireAuth();
|
|
314
277
|
const projectPath = options.path ? path.resolve(options.path) : process.cwd();
|
|
315
278
|
if (!fs.existsSync(projectPath)) {
|
|
316
|
-
console.log(
|
|
279
|
+
console.log(chalk.red(`\n❌ Path does not exist: ${projectPath}\n`));
|
|
317
280
|
return;
|
|
318
281
|
}
|
|
319
|
-
const spinner =
|
|
282
|
+
const spinner = createSpinner('Analyzing project...').start();
|
|
320
283
|
try {
|
|
321
284
|
const projectInfo = this.detectProjectInfo(projectPath);
|
|
322
|
-
spinner.succeed(`Project detected: ${
|
|
323
|
-
console.log(
|
|
324
|
-
console.log(
|
|
325
|
-
console.log(
|
|
285
|
+
spinner.succeed(`Project detected: ${chalk.cyan(projectInfo.name)}`);
|
|
286
|
+
console.log(chalk.gray(`\n 📁 Path: ${projectPath}`));
|
|
287
|
+
console.log(chalk.gray(` 📝 Description: ${projectInfo.description || '(none)'}`));
|
|
288
|
+
console.log(chalk.gray(` 🔧 Tech Stack: ${projectInfo.techStack.join(', ') || 'Unknown'}`));
|
|
326
289
|
console.log();
|
|
327
290
|
const defaults = {
|
|
328
291
|
name: options.name || projectInfo.name,
|
|
@@ -331,7 +294,7 @@ class RepoCommand {
|
|
|
331
294
|
};
|
|
332
295
|
const answers = options.yes
|
|
333
296
|
? { ...defaults, confirm: true }
|
|
334
|
-
: await
|
|
297
|
+
: await inquirer.prompt([
|
|
335
298
|
{
|
|
336
299
|
type: 'input',
|
|
337
300
|
name: 'name',
|
|
@@ -363,10 +326,10 @@ class RepoCommand {
|
|
|
363
326
|
}
|
|
364
327
|
]);
|
|
365
328
|
if (!answers.confirm) {
|
|
366
|
-
console.log(
|
|
329
|
+
console.log(chalk.yellow(`\n${CH.warnEmoji} Push cancelled.\n`));
|
|
367
330
|
return;
|
|
368
331
|
}
|
|
369
|
-
const uploadSpinner =
|
|
332
|
+
const uploadSpinner = createSpinner('Preparing project files...').start();
|
|
370
333
|
const files = this.collectProjectFiles(projectPath);
|
|
371
334
|
if (files.length === 0) {
|
|
372
335
|
throw new Error('No readable text files found to push');
|
|
@@ -389,23 +352,23 @@ class RepoCommand {
|
|
|
389
352
|
throw new Error(error.error || error.message || 'Failed to push project');
|
|
390
353
|
}
|
|
391
354
|
const registerData = await registerResponse.json();
|
|
392
|
-
uploadSpinner.succeed(
|
|
393
|
-
console.log(
|
|
394
|
-
console.log(
|
|
395
|
-
console.log(
|
|
355
|
+
uploadSpinner.succeed(chalk.green('Project pushed successfully!'));
|
|
356
|
+
console.log(chalk.cyan('\n📦 Project Details:'));
|
|
357
|
+
console.log(chalk.gray(` Name: ${registerData.project?.project_name || registerData.project?.name || answers.name}`));
|
|
358
|
+
console.log(chalk.gray(` Visibility: ${registerData.project?.visibility || answers.visibility}`));
|
|
396
359
|
if (registerData.project?.id || registerData.projectId) {
|
|
397
|
-
console.log(
|
|
360
|
+
console.log(chalk.gray(` ID: ${registerData.project?.id || registerData.projectId}`));
|
|
398
361
|
}
|
|
399
362
|
if ((registerData.project?.visibility || answers.visibility) === 'public') {
|
|
400
|
-
console.log(
|
|
363
|
+
console.log(chalk.cyan(`\n🔗 Public URL: ${registerData.url || `https://community.vigthoria.io/showcase/${registerData.project?.id || registerData.projectId}`}`));
|
|
401
364
|
}
|
|
402
|
-
console.log(
|
|
365
|
+
console.log(chalk.gray('\nTip: Use `vigthoria repo pull <name>` to restore this project anywhere.\n'));
|
|
403
366
|
}
|
|
404
367
|
catch (error) {
|
|
405
368
|
spinner.stop();
|
|
406
369
|
this.logger.error('Push failed');
|
|
407
370
|
const errMsg = this.formatRepoError(error);
|
|
408
|
-
console.log(
|
|
371
|
+
console.log(chalk.red(`\n❌ Error: ${errMsg}\n`));
|
|
409
372
|
}
|
|
410
373
|
}
|
|
411
374
|
/**
|
|
@@ -413,7 +376,7 @@ class RepoCommand {
|
|
|
413
376
|
*/
|
|
414
377
|
async pull(projectName, options = {}) {
|
|
415
378
|
this.requireAuth();
|
|
416
|
-
const spinner =
|
|
379
|
+
const spinner = createSpinner(`Fetching project: ${projectName}...`).start();
|
|
417
380
|
try {
|
|
418
381
|
const repo = await this.resolveRepoByName(projectName);
|
|
419
382
|
const response = await this.repoFetch('/api/repo/pull', {
|
|
@@ -425,23 +388,23 @@ class RepoCommand {
|
|
|
425
388
|
throw new Error(error.error || error.message || 'Project not found');
|
|
426
389
|
}
|
|
427
390
|
const data = await response.json();
|
|
428
|
-
spinner.succeed(`Found project: ${
|
|
391
|
+
spinner.succeed(`Found project: ${chalk.cyan(data.project?.project_name || data.projectName || repo.name || repo.project_name || projectName)}`);
|
|
429
392
|
const outputPath = options.output
|
|
430
393
|
? path.resolve(options.output)
|
|
431
394
|
: path.join(process.cwd(), data.project?.project_name || data.projectName || repo.name || repo.project_name || projectName);
|
|
432
395
|
if (fs.existsSync(outputPath) && !options.force) {
|
|
433
|
-
const { overwrite } = await
|
|
396
|
+
const { overwrite } = await inquirer.prompt([{
|
|
434
397
|
type: 'confirm',
|
|
435
398
|
name: 'overwrite',
|
|
436
399
|
message: `Directory ${outputPath} exists. Overwrite?`,
|
|
437
400
|
default: false
|
|
438
401
|
}]);
|
|
439
402
|
if (!overwrite) {
|
|
440
|
-
console.log(
|
|
403
|
+
console.log(chalk.yellow(`\n${CH.warnEmoji} Pull cancelled.\n`));
|
|
441
404
|
return;
|
|
442
405
|
}
|
|
443
406
|
}
|
|
444
|
-
const downloadSpinner =
|
|
407
|
+
const downloadSpinner = createSpinner('Downloading project files...').start();
|
|
445
408
|
// Create output directory
|
|
446
409
|
fs.mkdirSync(outputPath, { recursive: true });
|
|
447
410
|
// If we have a download URL, fetch and extract
|
|
@@ -482,18 +445,18 @@ class RepoCommand {
|
|
|
482
445
|
fs.writeFileSync(filePath, file.content);
|
|
483
446
|
}
|
|
484
447
|
}
|
|
485
|
-
downloadSpinner.succeed(
|
|
486
|
-
console.log(
|
|
487
|
-
console.log(
|
|
488
|
-
console.log(
|
|
489
|
-
console.log(
|
|
448
|
+
downloadSpinner.succeed(chalk.green('Project pulled successfully!'));
|
|
449
|
+
console.log(chalk.cyan('\n📁 Project extracted to:'));
|
|
450
|
+
console.log(chalk.white(` ${outputPath}`));
|
|
451
|
+
console.log(chalk.gray(`\n Tech Stack: ${data.project?.tech_stack || repo.tech_stack || 'Unknown'}`));
|
|
452
|
+
console.log(chalk.gray(` Description: ${data.project?.description || data.description || repo.description || '(none)'}`));
|
|
490
453
|
console.log();
|
|
491
454
|
}
|
|
492
455
|
catch (error) {
|
|
493
456
|
spinner.stop();
|
|
494
457
|
this.logger.error('Pull failed');
|
|
495
458
|
const errMsg = this.formatRepoError(error);
|
|
496
|
-
console.log(
|
|
459
|
+
console.log(chalk.red(`\n❌ Error: ${errMsg}\n`));
|
|
497
460
|
}
|
|
498
461
|
}
|
|
499
462
|
/**
|
|
@@ -501,7 +464,7 @@ class RepoCommand {
|
|
|
501
464
|
*/
|
|
502
465
|
async list(options = {}) {
|
|
503
466
|
this.requireAuth();
|
|
504
|
-
const spinner =
|
|
467
|
+
const spinner = createSpinner('Fetching your projects...').start();
|
|
505
468
|
try {
|
|
506
469
|
const repos = await this.getMyRepos();
|
|
507
470
|
const filteredRepos = options.visibility
|
|
@@ -515,18 +478,18 @@ class RepoCommand {
|
|
|
515
478
|
};
|
|
516
479
|
spinner.stop();
|
|
517
480
|
if (data.projects.length === 0) {
|
|
518
|
-
console.log(
|
|
519
|
-
console.log(
|
|
481
|
+
console.log(chalk.yellow('\n📦 No projects in your Vigthoria Repo yet.\n'));
|
|
482
|
+
console.log(chalk.gray('Use `vigthoria repo push` to upload your first project.\n'));
|
|
520
483
|
return;
|
|
521
484
|
}
|
|
522
485
|
// Separate owned and shared projects
|
|
523
486
|
const ownedProjects = data.owned || data.projects.filter((p) => p.access_level === 'owner');
|
|
524
487
|
const sharedProjects = data.shared || data.projects.filter((p) => p.access_level !== 'owner');
|
|
525
|
-
console.log(
|
|
488
|
+
console.log(chalk.cyan(`\n📦 Your Vigthoria Repository (${data.total} project${data.total !== 1 ? 's' : ''})\n`));
|
|
526
489
|
// Display owned projects grouped by visibility
|
|
527
490
|
if (ownedProjects.length > 0) {
|
|
528
|
-
console.log(
|
|
529
|
-
console.log(
|
|
491
|
+
console.log(chalk.bold.cyan(' 📁 YOUR PROJECTS'));
|
|
492
|
+
console.log(chalk.gray(' ' + CH.hLine.repeat(50)));
|
|
530
493
|
// Group by visibility
|
|
531
494
|
const grouped = ownedProjects.reduce((acc, project) => {
|
|
532
495
|
const vis = project.visibility || 'private';
|
|
@@ -545,54 +508,54 @@ class RepoCommand {
|
|
|
545
508
|
const projects = grouped[vis];
|
|
546
509
|
if (!projects || projects.length === 0)
|
|
547
510
|
return;
|
|
548
|
-
console.log(
|
|
511
|
+
console.log(chalk.bold.white(` ${visibilityIcons[vis]} ${vis.toUpperCase()}`));
|
|
549
512
|
projects.forEach((project) => {
|
|
550
513
|
const projectName = project.project_name || project.name || 'Unnamed';
|
|
551
514
|
const techStack = project.tech_stack || project.framework || 'Unknown';
|
|
552
515
|
const updatedAt = project.updated_at || project.updatedAt || project.created_at || project.createdAt;
|
|
553
516
|
const syncStatus = (project.last_synced_at || project.lastSyncedAt)
|
|
554
|
-
?
|
|
555
|
-
:
|
|
556
|
-
console.log(
|
|
517
|
+
? chalk.green(`${CH.success} synced`)
|
|
518
|
+
: chalk.yellow('- not synced');
|
|
519
|
+
console.log(chalk.white(` ${projectName.padEnd(30)} ${syncStatus}`));
|
|
557
520
|
if (project.description) {
|
|
558
|
-
console.log(
|
|
521
|
+
console.log(chalk.gray(` ${project.description.substring(0, 50)}${project.description.length > 50 ? '...' : ''}`));
|
|
559
522
|
}
|
|
560
|
-
console.log(
|
|
561
|
-
console.log(
|
|
523
|
+
console.log(chalk.gray(` Tech: ${techStack}`));
|
|
524
|
+
console.log(chalk.gray(` Updated: ${updatedAt ? new Date(updatedAt).toLocaleDateString() : 'Unknown'}`));
|
|
562
525
|
console.log();
|
|
563
526
|
});
|
|
564
527
|
});
|
|
565
528
|
}
|
|
566
529
|
// Display shared projects
|
|
567
530
|
if (sharedProjects.length > 0) {
|
|
568
|
-
console.log(
|
|
569
|
-
console.log(
|
|
531
|
+
console.log(chalk.bold.magenta('\n 🤝 SHARED WITH YOU'));
|
|
532
|
+
console.log(chalk.gray(' ' + CH.hLine.repeat(50)));
|
|
570
533
|
sharedProjects.forEach((project) => {
|
|
571
534
|
const projectName = project.project_name || project.name || 'Unnamed';
|
|
572
535
|
const techStack = project.tech_stack || project.framework || 'Unknown';
|
|
573
536
|
const updatedAt = project.updated_at || project.updatedAt || project.created_at || project.createdAt;
|
|
574
537
|
const accessIcon = project.access_level === 'admin' ? '👑' : project.access_level === 'write' ? '✏️' : '👁️';
|
|
575
|
-
console.log(
|
|
538
|
+
console.log(chalk.white(` ${accessIcon} ${projectName.padEnd(28)} [${project.access_level}]`));
|
|
576
539
|
if (project.description) {
|
|
577
|
-
console.log(
|
|
540
|
+
console.log(chalk.gray(` ${project.description.substring(0, 50)}${project.description.length > 50 ? '...' : ''}`));
|
|
578
541
|
}
|
|
579
|
-
console.log(
|
|
580
|
-
console.log(
|
|
542
|
+
console.log(chalk.gray(` Tech: ${techStack}`));
|
|
543
|
+
console.log(chalk.gray(` Updated: ${updatedAt ? new Date(updatedAt).toLocaleDateString() : 'Unknown'}`));
|
|
581
544
|
console.log();
|
|
582
545
|
});
|
|
583
546
|
}
|
|
584
|
-
console.log(
|
|
585
|
-
console.log(
|
|
586
|
-
console.log(
|
|
587
|
-
console.log(
|
|
588
|
-
console.log(
|
|
589
|
-
console.log(
|
|
547
|
+
console.log(chalk.gray(CH.hLine.repeat(60)));
|
|
548
|
+
console.log(chalk.cyan('\nCommands:'));
|
|
549
|
+
console.log(chalk.gray(' vigthoria repo pull <name> - Download a project'));
|
|
550
|
+
console.log(chalk.gray(' vigthoria repo push - Upload current directory'));
|
|
551
|
+
console.log(chalk.gray(' vigthoria repo status - Check sync status'));
|
|
552
|
+
console.log(chalk.gray(' vigthoria repo share <name> - Share a project\n'));
|
|
590
553
|
}
|
|
591
554
|
catch (error) {
|
|
592
555
|
spinner.stop();
|
|
593
556
|
this.logger.error('List failed');
|
|
594
557
|
const errMsg = this.formatRepoError(error);
|
|
595
|
-
console.log(
|
|
558
|
+
console.log(chalk.red(`\n❌ Error: ${errMsg}\n`));
|
|
596
559
|
}
|
|
597
560
|
}
|
|
598
561
|
/**
|
|
@@ -602,7 +565,7 @@ class RepoCommand {
|
|
|
602
565
|
this.requireAuth();
|
|
603
566
|
const projectPath = process.cwd();
|
|
604
567
|
const projectInfo = this.detectProjectInfo(projectPath);
|
|
605
|
-
const spinner =
|
|
568
|
+
const spinner = createSpinner('Checking sync status...').start();
|
|
606
569
|
try {
|
|
607
570
|
const response = await fetch(`${this.apiBase}/api/repo/status/${encodeURIComponent(projectInfo.name)}`, {
|
|
608
571
|
method: 'GET',
|
|
@@ -610,8 +573,8 @@ class RepoCommand {
|
|
|
610
573
|
});
|
|
611
574
|
if (!response.ok) {
|
|
612
575
|
spinner.succeed('Project not tracked in Vigthoria Repo');
|
|
613
|
-
console.log(
|
|
614
|
-
console.log(
|
|
576
|
+
console.log(chalk.yellow('\n📦 Current project is not synced with Vigthoria Repo.\n'));
|
|
577
|
+
console.log(chalk.gray('Use `vigthoria repo push` to upload it.\n'));
|
|
615
578
|
return;
|
|
616
579
|
}
|
|
617
580
|
const data = await response.json();
|
|
@@ -620,30 +583,30 @@ class RepoCommand {
|
|
|
620
583
|
synced: '✅',
|
|
621
584
|
ahead: '⬆️',
|
|
622
585
|
behind: '⬇️',
|
|
623
|
-
diverged:
|
|
586
|
+
diverged: CH.warnEmoji
|
|
624
587
|
};
|
|
625
|
-
console.log(
|
|
626
|
-
console.log(
|
|
627
|
-
console.log(
|
|
628
|
-
console.log(
|
|
588
|
+
console.log(chalk.cyan(`\n📦 Project: ${chalk.white(data.project.project_name)}\n`));
|
|
589
|
+
console.log(chalk.gray(` Path: ${projectPath}`));
|
|
590
|
+
console.log(chalk.gray(` Visibility: ${data.project.visibility}`));
|
|
591
|
+
console.log(chalk.gray(` Tech Stack: ${data.project.tech_stack || 'Unknown'}`));
|
|
629
592
|
console.log();
|
|
630
593
|
console.log(` Status: ${statusIcons[data.syncStatus]} ${data.syncStatus.toUpperCase()}`);
|
|
631
594
|
if (data.localChanges && data.localChanges > 0) {
|
|
632
|
-
console.log(
|
|
595
|
+
console.log(chalk.yellow(` Local changes: ${data.localChanges} file(s) modified`));
|
|
633
596
|
}
|
|
634
|
-
console.log(
|
|
597
|
+
console.log(chalk.gray(`\n Last synced: ${data.project.last_synced_at
|
|
635
598
|
? new Date(data.project.last_synced_at).toLocaleString()
|
|
636
599
|
: 'Never'}`));
|
|
637
600
|
console.log();
|
|
638
601
|
if (data.syncStatus === 'ahead' || data.syncStatus === 'diverged') {
|
|
639
|
-
console.log(
|
|
602
|
+
console.log(chalk.cyan('Tip: Use `vigthoria repo push` to sync changes.\n'));
|
|
640
603
|
}
|
|
641
604
|
}
|
|
642
605
|
catch (error) {
|
|
643
606
|
spinner.stop();
|
|
644
607
|
this.logger.error('Status check failed');
|
|
645
608
|
const errMsg = error instanceof Error ? error.message : 'Unknown error';
|
|
646
|
-
console.log(
|
|
609
|
+
console.log(chalk.red(`\n❌ Error: ${errMsg}\n`));
|
|
647
610
|
}
|
|
648
611
|
}
|
|
649
612
|
/**
|
|
@@ -651,7 +614,7 @@ class RepoCommand {
|
|
|
651
614
|
*/
|
|
652
615
|
async share(projectName, options = {}) {
|
|
653
616
|
this.requireAuth();
|
|
654
|
-
const spinner =
|
|
617
|
+
const spinner = createSpinner('Generating share link...').start();
|
|
655
618
|
try {
|
|
656
619
|
const response = await fetch(`${this.apiBase}/api/repo/share`, {
|
|
657
620
|
method: 'POST',
|
|
@@ -666,17 +629,17 @@ class RepoCommand {
|
|
|
666
629
|
throw new Error(error.error || 'Failed to generate share link');
|
|
667
630
|
}
|
|
668
631
|
const data = await response.json();
|
|
669
|
-
spinner.succeed(
|
|
670
|
-
console.log(
|
|
671
|
-
console.log(
|
|
672
|
-
console.log(
|
|
673
|
-
console.log(
|
|
632
|
+
spinner.succeed(chalk.green('Share link generated!'));
|
|
633
|
+
console.log(chalk.cyan('\n🔗 Share Link:'));
|
|
634
|
+
console.log(chalk.white(` ${data.shareUrl}`));
|
|
635
|
+
console.log(chalk.gray(`\n Expires: ${new Date(data.expiresAt).toLocaleString()}`));
|
|
636
|
+
console.log(chalk.gray('\n Anyone with this link can view/download the project.\n'));
|
|
674
637
|
}
|
|
675
638
|
catch (error) {
|
|
676
639
|
spinner.stop();
|
|
677
640
|
this.logger.error('Share failed');
|
|
678
641
|
const errMsg = error instanceof Error ? error.message : 'Unknown error';
|
|
679
|
-
console.log(
|
|
642
|
+
console.log(chalk.red(`\n❌ Error: ${errMsg}\n`));
|
|
680
643
|
}
|
|
681
644
|
}
|
|
682
645
|
/**
|
|
@@ -684,17 +647,17 @@ class RepoCommand {
|
|
|
684
647
|
*/
|
|
685
648
|
async delete(projectName) {
|
|
686
649
|
this.requireAuth();
|
|
687
|
-
const { confirm } = await
|
|
650
|
+
const { confirm } = await inquirer.prompt([{
|
|
688
651
|
type: 'confirm',
|
|
689
652
|
name: 'confirm',
|
|
690
|
-
message:
|
|
653
|
+
message: chalk.red(`Are you sure you want to delete "${projectName}" from Vigthoria Repo?`),
|
|
691
654
|
default: false
|
|
692
655
|
}]);
|
|
693
656
|
if (!confirm) {
|
|
694
|
-
console.log(
|
|
657
|
+
console.log(chalk.yellow(`\n${CH.warnEmoji} Delete cancelled.\n`));
|
|
695
658
|
return;
|
|
696
659
|
}
|
|
697
|
-
const spinner =
|
|
660
|
+
const spinner = createSpinner('Deleting project...').start();
|
|
698
661
|
try {
|
|
699
662
|
const response = await fetch(`${this.apiBase}/api/repo/projects/${encodeURIComponent(projectName)}`, {
|
|
700
663
|
method: 'DELETE',
|
|
@@ -704,14 +667,14 @@ class RepoCommand {
|
|
|
704
667
|
const error = await response.json();
|
|
705
668
|
throw new Error(error.error || 'Failed to delete project');
|
|
706
669
|
}
|
|
707
|
-
spinner.succeed(
|
|
708
|
-
console.log(
|
|
670
|
+
spinner.succeed(chalk.green('Project deleted from Vigthoria Repo'));
|
|
671
|
+
console.log(chalk.gray('\nNote: Your local files are not affected.\n'));
|
|
709
672
|
}
|
|
710
673
|
catch (error) {
|
|
711
674
|
spinner.stop();
|
|
712
675
|
this.logger.error('Delete failed');
|
|
713
676
|
const errMsg = error instanceof Error ? error.message : 'Unknown error';
|
|
714
|
-
console.log(
|
|
677
|
+
console.log(chalk.red(`\n❌ Error: ${errMsg}\n`));
|
|
715
678
|
}
|
|
716
679
|
}
|
|
717
680
|
/**
|
|
@@ -728,7 +691,7 @@ class RepoCommand {
|
|
|
728
691
|
const label = engineLabels[engine] || engine;
|
|
729
692
|
// Resolve project name from arg or current directory
|
|
730
693
|
const resolvedName = projectName || this.detectProjectInfo(process.cwd()).name;
|
|
731
|
-
const spinner =
|
|
694
|
+
const spinner = createSpinner(`Opening "${resolvedName}" in ${label}...`).start();
|
|
732
695
|
try {
|
|
733
696
|
const response = await fetch(`${this.apiBase}/api/engine-import`, {
|
|
734
697
|
method: 'POST',
|
|
@@ -745,9 +708,9 @@ class RepoCommand {
|
|
|
745
708
|
throw new Error(err.error || `Engine import failed (${response.status})`);
|
|
746
709
|
}
|
|
747
710
|
const data = await response.json();
|
|
748
|
-
spinner.succeed(
|
|
749
|
-
console.log(
|
|
750
|
-
console.log(
|
|
711
|
+
spinner.succeed(chalk.green(`Project imported into ${label}!`));
|
|
712
|
+
console.log(chalk.cyan(`\n🚀 Open in browser:`));
|
|
713
|
+
console.log(chalk.bold(` ${data.url}\n`));
|
|
751
714
|
if (options.browser) {
|
|
752
715
|
try {
|
|
753
716
|
const { execFileSync } = await import('child_process');
|
|
@@ -768,14 +731,14 @@ class RepoCommand {
|
|
|
768
731
|
catch { /* browser open is optional */ }
|
|
769
732
|
}
|
|
770
733
|
if (data.message) {
|
|
771
|
-
console.log(
|
|
734
|
+
console.log(chalk.gray(` ${data.message}\n`));
|
|
772
735
|
}
|
|
773
736
|
}
|
|
774
737
|
catch (error) {
|
|
775
738
|
spinner.stop();
|
|
776
739
|
const errMsg = error instanceof Error ? error.message : 'Unknown error';
|
|
777
|
-
console.log(
|
|
778
|
-
console.log(
|
|
740
|
+
console.log(chalk.red(`\n❌ ${label} import failed: ${errMsg}\n`));
|
|
741
|
+
console.log(chalk.gray('Tip: Make sure your project is pushed first with `vigthoria repo push`\n'));
|
|
779
742
|
}
|
|
780
743
|
}
|
|
781
744
|
/**
|
|
@@ -785,7 +748,7 @@ class RepoCommand {
|
|
|
785
748
|
// Parse project URL or name
|
|
786
749
|
const projectIdMatch = projectUrl.match(/preview\/(\d+)/);
|
|
787
750
|
const projectId = projectIdMatch ? projectIdMatch[1] : projectUrl;
|
|
788
|
-
const spinner =
|
|
751
|
+
const spinner = createSpinner(`Cloning project...`).start();
|
|
789
752
|
try {
|
|
790
753
|
const response = await fetch(`${this.apiBase}/api/repo/clone/${projectId}`, {
|
|
791
754
|
method: 'GET',
|
|
@@ -796,7 +759,7 @@ class RepoCommand {
|
|
|
796
759
|
throw new Error(error.error || 'Project not found or not public');
|
|
797
760
|
}
|
|
798
761
|
const data = await response.json();
|
|
799
|
-
spinner.succeed(`Found project: ${
|
|
762
|
+
spinner.succeed(`Found project: ${chalk.cyan(data.project.project_name)}`);
|
|
800
763
|
// Use pull logic for the rest
|
|
801
764
|
await this.pull(data.project.project_name, options);
|
|
802
765
|
}
|
|
@@ -804,8 +767,7 @@ class RepoCommand {
|
|
|
804
767
|
spinner.stop();
|
|
805
768
|
this.logger.error('Clone failed');
|
|
806
769
|
const errMsg = error instanceof Error ? error.message : 'Unknown error';
|
|
807
|
-
console.log(
|
|
770
|
+
console.log(chalk.red(`\n❌ Error: ${errMsg}\n`));
|
|
808
771
|
}
|
|
809
772
|
}
|
|
810
773
|
}
|
|
811
|
-
exports.RepoCommand = RepoCommand;
|