vigthoria-cli 1.10.47 → 1.10.48
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/dist/commands/auth.js +51 -68
- package/dist/commands/bridge.js +12 -19
- package/dist/commands/cancel.js +15 -22
- package/dist/commands/chat.d.ts +28 -0
- package/dist/commands/config.js +33 -73
- package/dist/commands/deploy.js +83 -123
- package/dist/commands/device.js +21 -61
- package/dist/commands/edit.js +32 -39
- package/dist/commands/explain.js +18 -25
- package/dist/commands/fork.d.ts +17 -0
- package/dist/commands/fork.js +164 -0
- package/dist/commands/generate.js +37 -44
- package/dist/commands/history.d.ts +17 -0
- package/dist/commands/history.js +113 -0
- package/dist/commands/hub.js +95 -102
- package/dist/commands/index.js +41 -46
- package/dist/commands/legion.js +146 -186
- package/dist/commands/preview.d.ts +55 -0
- package/dist/commands/preview.js +467 -0
- package/dist/commands/replay.d.ts +18 -0
- package/dist/commands/replay.js +156 -0
- package/dist/commands/repo.d.ts +97 -0
- package/dist/commands/repo.js +773 -0
- package/dist/commands/review.js +29 -36
- package/dist/commands/security.js +5 -12
- package/dist/commands/update.d.ts +9 -0
- package/dist/commands/update.js +201 -0
- package/dist/commands/wallet.js +28 -35
- package/dist/commands/workflow.js +13 -20
- package/dist/index.d.ts +21 -0
- package/dist/index.js +1826 -0
- package/dist/utils/api.d.ts +572 -0
- package/dist/utils/api.js +6629 -0
- package/dist/utils/brain-hub-client.js +1 -5
- 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/codebase-indexer.js +4 -41
- package/dist/utils/config.d.ts +85 -0
- package/dist/utils/config.js +267 -0
- 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/persona.js +3 -8
- package/dist/utils/post-write-validator.js +22 -29
- package/dist/utils/project-memory.js +16 -23
- package/dist/utils/session.d.ts +118 -0
- package/dist/utils/session.js +423 -0
- package/dist/utils/task-display.js +13 -20
- package/dist/utils/tools.d.ts +276 -0
- package/dist/utils/tools.js +3522 -0
- package/dist/utils/workspace-brain-service.js +8 -45
- package/dist/utils/workspace-cache.js +18 -26
- package/dist/utils/workspace-stream.js +21 -63
- package/package.json +1 -1
|
@@ -1,20 +1,14 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Generate Command - Generate code from description
|
|
4
3
|
*
|
|
5
4
|
* Now with Senior Developer Mode (--pro) for impressive, production-ready output
|
|
6
5
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const inquirer_1 = __importDefault(require("inquirer"));
|
|
14
|
-
const logger_js_1 = require("../utils/logger.js");
|
|
15
|
-
const api_js_1 = require("../utils/api.js");
|
|
16
|
-
const files_js_1 = require("../utils/files.js");
|
|
17
|
-
class GenerateCommand {
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import inquirer from 'inquirer';
|
|
8
|
+
import { createSpinner, CH } from '../utils/logger.js';
|
|
9
|
+
import { APIClient, CLIError, classifyError, formatCLIError } from '../utils/api.js';
|
|
10
|
+
import { FileUtils } from '../utils/files.js';
|
|
11
|
+
export class GenerateCommand {
|
|
18
12
|
config;
|
|
19
13
|
logger;
|
|
20
14
|
api;
|
|
@@ -22,8 +16,8 @@ class GenerateCommand {
|
|
|
22
16
|
constructor(config, logger) {
|
|
23
17
|
this.config = config;
|
|
24
18
|
this.logger = logger;
|
|
25
|
-
this.api = new
|
|
26
|
-
this.fileUtils = new
|
|
19
|
+
this.api = new APIClient(config, logger);
|
|
20
|
+
this.fileUtils = new FileUtils(process.cwd(), config.get('project').ignorePatterns);
|
|
27
21
|
}
|
|
28
22
|
async run(description, options) {
|
|
29
23
|
// Check auth
|
|
@@ -43,14 +37,14 @@ class GenerateCommand {
|
|
|
43
37
|
if (!options.language) {
|
|
44
38
|
options.language = this.detectLanguageFromDescription(description);
|
|
45
39
|
}
|
|
46
|
-
this.logger.section(proMode ? `${
|
|
47
|
-
console.log(
|
|
48
|
-
console.log(
|
|
40
|
+
this.logger.section(proMode ? `${CH.rocket} Senior Developer Mode` : 'Code Generation');
|
|
41
|
+
console.log(chalk.gray(`Language: ${options.language}`));
|
|
42
|
+
console.log(chalk.gray(`Description: ${description}`));
|
|
49
43
|
if (proMode) {
|
|
50
|
-
console.log(
|
|
44
|
+
console.log(chalk.cyan('Pro Mode: Planning → Generating → Quality Check'));
|
|
51
45
|
}
|
|
52
46
|
console.log();
|
|
53
|
-
const spinner =
|
|
47
|
+
const spinner = createSpinner({
|
|
54
48
|
text: proMode ? 'Phase 1: Planning project structure...' : 'Generating code...',
|
|
55
49
|
spinner: 'dots',
|
|
56
50
|
}).start();
|
|
@@ -69,20 +63,20 @@ class GenerateCommand {
|
|
|
69
63
|
if (quality) {
|
|
70
64
|
console.log();
|
|
71
65
|
this.logger.section('Quality Report');
|
|
72
|
-
console.log(
|
|
73
|
-
console.log(
|
|
66
|
+
console.log(chalk.gray(`Lines of code: ${quality.lineCount}`));
|
|
67
|
+
console.log(chalk.gray(`Quality score: ${quality.score}/5`));
|
|
74
68
|
console.log();
|
|
75
|
-
console.log(
|
|
76
|
-
console.log(` ${quality.checks?.hasAnimations ?
|
|
77
|
-
console.log(` ${quality.checks?.hasNeonEffects ?
|
|
78
|
-
console.log(` ${quality.checks?.hasResponsive ?
|
|
79
|
-
console.log(` ${quality.checks?.hasFontAwesome ?
|
|
80
|
-
console.log(` ${quality.checks?.hasGoogleFonts ?
|
|
69
|
+
console.log(chalk.gray('Visual Checks:'));
|
|
70
|
+
console.log(` ${quality.checks?.hasAnimations ? chalk.green('✓') : chalk.red('✗')} CSS Animations (@keyframes)`);
|
|
71
|
+
console.log(` ${quality.checks?.hasNeonEffects ? chalk.green('✓') : chalk.red('✗')} Neon/Glow Effects`);
|
|
72
|
+
console.log(` ${quality.checks?.hasResponsive ? chalk.green('✓') : chalk.red('✗')} Responsive Design (@media)`);
|
|
73
|
+
console.log(` ${quality.checks?.hasFontAwesome ? chalk.green('✓') : chalk.red('✗')} Font Awesome Icons`);
|
|
74
|
+
console.log(` ${quality.checks?.hasGoogleFonts ? chalk.green('✓') : chalk.red('✗')} Google Fonts`);
|
|
81
75
|
console.log();
|
|
82
|
-
console.log(
|
|
83
|
-
console.log(` ${quality.checks?.hasEmbeddedCSS ?
|
|
84
|
-
console.log(` ${quality.checks?.hasEmbeddedJS ?
|
|
85
|
-
console.log(` ${quality.checks?.singleFile ?
|
|
76
|
+
console.log(chalk.gray('Structure Checks:'));
|
|
77
|
+
console.log(` ${quality.checks?.hasEmbeddedCSS ? chalk.green('✓') : chalk.red('✗')} Embedded CSS (<style> tag)`);
|
|
78
|
+
console.log(` ${quality.checks?.hasEmbeddedJS ? chalk.green('✓') : chalk.red('✗')} Embedded JavaScript (<script> tag)`);
|
|
79
|
+
console.log(` ${quality.checks?.singleFile ? chalk.green('✓') : chalk.red('✗')} Single-file (no external CSS/JS)`);
|
|
86
80
|
console.log();
|
|
87
81
|
}
|
|
88
82
|
}
|
|
@@ -96,9 +90,9 @@ class GenerateCommand {
|
|
|
96
90
|
// Display generated code (skip display when --output is set to avoid noise)
|
|
97
91
|
if (!options.output) {
|
|
98
92
|
this.logger.section('Generated Code');
|
|
99
|
-
console.log(
|
|
93
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
100
94
|
console.log(this.highlightCode(code, options.language));
|
|
101
|
-
console.log(
|
|
95
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
102
96
|
console.log();
|
|
103
97
|
}
|
|
104
98
|
// Save options — when --output is specified, save directly (non-interactive)
|
|
@@ -112,8 +106,8 @@ class GenerateCommand {
|
|
|
112
106
|
}
|
|
113
107
|
catch (error) {
|
|
114
108
|
spinner.stop();
|
|
115
|
-
const cliErr = error instanceof
|
|
116
|
-
this.logger.error(
|
|
109
|
+
const cliErr = error instanceof CLIError ? error : classifyError(error);
|
|
110
|
+
this.logger.error(formatCLIError(cliErr));
|
|
117
111
|
}
|
|
118
112
|
}
|
|
119
113
|
/**
|
|
@@ -140,7 +134,7 @@ class GenerateCommand {
|
|
|
140
134
|
// In production, use a proper library like highlight.js
|
|
141
135
|
const lines = code.split('\n');
|
|
142
136
|
return lines.map((line, i) => {
|
|
143
|
-
const lineNum =
|
|
137
|
+
const lineNum = chalk.gray(String(i + 1).padStart(4, ' ') + ' │ ');
|
|
144
138
|
return lineNum + this.highlightLine(line, language);
|
|
145
139
|
}).join('\n');
|
|
146
140
|
}
|
|
@@ -158,14 +152,14 @@ class GenerateCommand {
|
|
|
158
152
|
// Highlight keywords
|
|
159
153
|
langKeywords.forEach(kw => {
|
|
160
154
|
const regex = new RegExp(`\\b${kw}\\b`, 'g');
|
|
161
|
-
highlighted = highlighted.replace(regex,
|
|
155
|
+
highlighted = highlighted.replace(regex, chalk.magenta(kw));
|
|
162
156
|
});
|
|
163
157
|
// Highlight strings
|
|
164
|
-
highlighted = highlighted.replace(/(["'`])(?:(?!\1)[^\\]|\\.)*\1/g, (match) =>
|
|
158
|
+
highlighted = highlighted.replace(/(["'`])(?:(?!\1)[^\\]|\\.)*\1/g, (match) => chalk.green(match));
|
|
165
159
|
// Highlight comments
|
|
166
|
-
highlighted = highlighted.replace(/(\/\/.*$|#.*$)/g, (match) =>
|
|
160
|
+
highlighted = highlighted.replace(/(\/\/.*$|#.*$)/g, (match) => chalk.gray(match));
|
|
167
161
|
// Highlight numbers
|
|
168
|
-
highlighted = highlighted.replace(/\b(\d+)\b/g, (match) =>
|
|
162
|
+
highlighted = highlighted.replace(/\b(\d+)\b/g, (match) => chalk.yellow(match));
|
|
169
163
|
return highlighted;
|
|
170
164
|
}
|
|
171
165
|
async saveToFile(filePath, code) {
|
|
@@ -177,7 +171,7 @@ class GenerateCommand {
|
|
|
177
171
|
}
|
|
178
172
|
}
|
|
179
173
|
async promptForAction(code, language) {
|
|
180
|
-
const { action } = await
|
|
174
|
+
const { action } = await inquirer.prompt([
|
|
181
175
|
{
|
|
182
176
|
type: 'list',
|
|
183
177
|
name: 'action',
|
|
@@ -194,10 +188,10 @@ class GenerateCommand {
|
|
|
194
188
|
case 'copy':
|
|
195
189
|
// Note: Clipboard access requires additional setup
|
|
196
190
|
this.logger.info('Code copied to clipboard');
|
|
197
|
-
console.log(
|
|
191
|
+
console.log(chalk.gray('(Note: Clipboard access may require additional permissions)'));
|
|
198
192
|
break;
|
|
199
193
|
case 'save':
|
|
200
|
-
const { filename } = await
|
|
194
|
+
const { filename } = await inquirer.prompt([
|
|
201
195
|
{
|
|
202
196
|
type: 'input',
|
|
203
197
|
name: 'filename',
|
|
@@ -262,4 +256,3 @@ class GenerateCommand {
|
|
|
262
256
|
return 'javascript';
|
|
263
257
|
}
|
|
264
258
|
}
|
|
265
|
-
exports.GenerateCommand = GenerateCommand;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Config } from '../utils/config.js';
|
|
2
|
+
import { Logger } from '../utils/logger.js';
|
|
3
|
+
interface HistoryOptions {
|
|
4
|
+
limit?: number;
|
|
5
|
+
json?: boolean;
|
|
6
|
+
project?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class HistoryCommand {
|
|
9
|
+
private config;
|
|
10
|
+
private logger;
|
|
11
|
+
constructor(config: Config, logger: Logger);
|
|
12
|
+
private getHeaders;
|
|
13
|
+
private getBaseUrl;
|
|
14
|
+
private resolveWorkspaceRoot;
|
|
15
|
+
run(options: HistoryOptions): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { isServerRuntime } from '../utils/api.js';
|
|
2
|
+
/**
|
|
3
|
+
* history.ts — List recent V3 agent runs with summaries.
|
|
4
|
+
*/
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { createRequire } from 'node:module';
|
|
7
|
+
import { createSpinner, CH } from '../utils/logger.js';
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
export class HistoryCommand {
|
|
10
|
+
config;
|
|
11
|
+
logger;
|
|
12
|
+
constructor(config, logger) {
|
|
13
|
+
this.config = config;
|
|
14
|
+
this.logger = logger;
|
|
15
|
+
}
|
|
16
|
+
getHeaders() {
|
|
17
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
18
|
+
const token = process.env.VIGTHORIA_TOKEN ||
|
|
19
|
+
process.env.VIGTHORIA_AUTH_TOKEN ||
|
|
20
|
+
this.config.get('authToken');
|
|
21
|
+
if (token) {
|
|
22
|
+
headers['Authorization'] = `Bearer ${token}`;
|
|
23
|
+
headers['Cookie'] = `vigthoria-auth-token=${token}`;
|
|
24
|
+
}
|
|
25
|
+
const serviceKey = process.env.VIGTHORIA_V3_SERVICE_KEY;
|
|
26
|
+
if (serviceKey)
|
|
27
|
+
headers['X-Service-Key'] = serviceKey;
|
|
28
|
+
return headers;
|
|
29
|
+
}
|
|
30
|
+
getBaseUrl() {
|
|
31
|
+
const configuredApiUrl = String(this.config.get('apiUrl') || 'https://coder.vigthoria.io').replace(/\/$/, '');
|
|
32
|
+
const allowLocal = !isServerRuntime() || process.env.VIGTHORIA_ALLOW_LOCAL_V3_AGENT === '1';
|
|
33
|
+
return (process.env.VIGTHORIA_V3_AGENT_URL ||
|
|
34
|
+
process.env.V3_AGENT_URL ||
|
|
35
|
+
(allowLocal ? 'http://127.0.0.1:8030' : null) ||
|
|
36
|
+
configuredApiUrl);
|
|
37
|
+
}
|
|
38
|
+
resolveWorkspaceRoot(project) {
|
|
39
|
+
// On Windows or non-absolute paths, send empty so the server uses its fallback root
|
|
40
|
+
if (/^[a-zA-Z]:[\\/]/.test(project) || /^\\\\/.test(project))
|
|
41
|
+
return '';
|
|
42
|
+
if (typeof require !== 'undefined') {
|
|
43
|
+
try {
|
|
44
|
+
const path = require('path');
|
|
45
|
+
if (!path.isAbsolute(project))
|
|
46
|
+
return '';
|
|
47
|
+
}
|
|
48
|
+
catch { }
|
|
49
|
+
}
|
|
50
|
+
return project;
|
|
51
|
+
}
|
|
52
|
+
async run(options) {
|
|
53
|
+
const limit = options.limit || 20;
|
|
54
|
+
const project = options.project || process.cwd();
|
|
55
|
+
const workspace = this.resolveWorkspaceRoot(project);
|
|
56
|
+
const spinner = createSpinner('Loading run history...').start();
|
|
57
|
+
try {
|
|
58
|
+
const baseUrl = this.getBaseUrl();
|
|
59
|
+
const params = new URLSearchParams({
|
|
60
|
+
limit: String(limit),
|
|
61
|
+
workspace_root: workspace,
|
|
62
|
+
local_workspace_path: project,
|
|
63
|
+
project_path: project,
|
|
64
|
+
});
|
|
65
|
+
const resp = await fetch(`${baseUrl}/api/runs?${params}`, {
|
|
66
|
+
headers: this.getHeaders(),
|
|
67
|
+
});
|
|
68
|
+
if (!resp.ok) {
|
|
69
|
+
spinner.stop();
|
|
70
|
+
if (resp.status === 404 || resp.status === 502 || resp.status === 503) {
|
|
71
|
+
this.logger.error(`V3 run-history route is not available on ${baseUrl}. Backend may not expose /api/runs.`);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
this.logger.error(`Failed to fetch runs: ${resp.status} ${resp.statusText}`);
|
|
75
|
+
}
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const data = (await resp.json());
|
|
79
|
+
spinner.stop();
|
|
80
|
+
if (options.json) {
|
|
81
|
+
console.log(JSON.stringify(data, null, 2));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (data.runs.length === 0) {
|
|
85
|
+
this.logger.info(chalk.dim('No runs found.'));
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
console.log(chalk.bold(`\n${CH.success} Recent Runs (${data.count})\n`));
|
|
89
|
+
for (const run of data.runs) {
|
|
90
|
+
const tier = run.seal_score?.tier || 'unknown';
|
|
91
|
+
const tierColor = tier === 'gold' ? chalk.yellow :
|
|
92
|
+
tier === 'silver' ? chalk.white :
|
|
93
|
+
tier === 'bronze' ? chalk.hex('#cd7f32') :
|
|
94
|
+
tier === 'failed' ? chalk.red :
|
|
95
|
+
chalk.dim;
|
|
96
|
+
const score = run.seal_score?.overall != null ? `${run.seal_score.overall}` : '—';
|
|
97
|
+
const status = run.failed > 0
|
|
98
|
+
? chalk.red(`${run.completed}/${run.task_count} ✗`)
|
|
99
|
+
: chalk.green(`${run.completed}/${run.task_count} ✓`);
|
|
100
|
+
console.log(` ${chalk.cyan(run.run_id.substring(0, 16))} ` +
|
|
101
|
+
`${chalk.dim(run.archived_at || '?')} ` +
|
|
102
|
+
`${status} ` +
|
|
103
|
+
`${tierColor(`[${tier} ${score}]`)} ` +
|
|
104
|
+
`${chalk.white(run.request?.substring(0, 60) || '(no request)')}`);
|
|
105
|
+
}
|
|
106
|
+
console.log();
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
spinner.stop();
|
|
110
|
+
this.logger.error(`History error: ${err.message}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|