vigthoria-cli 1.10.36 → 1.10.47

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 (62) hide show
  1. package/dist/commands/agent-session-menu.d.ts +19 -0
  2. package/dist/commands/agent-session-menu.js +155 -0
  3. package/dist/commands/auth.js +68 -51
  4. package/dist/commands/bridge.js +19 -12
  5. package/dist/commands/cancel.js +22 -15
  6. package/dist/commands/chat.d.ts +0 -22
  7. package/dist/commands/chat.js +402 -1084
  8. package/dist/commands/config.js +73 -33
  9. package/dist/commands/deploy.js +123 -83
  10. package/dist/commands/device.js +61 -21
  11. package/dist/commands/edit.js +39 -32
  12. package/dist/commands/explain.js +25 -18
  13. package/dist/commands/generate.js +44 -37
  14. package/dist/commands/hub.js +102 -95
  15. package/dist/commands/index.js +46 -41
  16. package/dist/commands/legion.js +186 -146
  17. package/dist/commands/review.js +36 -29
  18. package/dist/commands/security.js +12 -5
  19. package/dist/commands/wallet.js +35 -28
  20. package/dist/commands/workflow.js +20 -13
  21. package/dist/utils/brain-hub-client.d.ts +32 -0
  22. package/dist/utils/brain-hub-client.js +52 -0
  23. package/dist/utils/bridge-client.js +52 -11
  24. package/dist/utils/codebase-indexer.d.ts +59 -0
  25. package/dist/utils/codebase-indexer.js +351 -0
  26. package/dist/utils/context-ranker.js +21 -15
  27. package/dist/utils/files.js +42 -5
  28. package/dist/utils/logger.js +50 -42
  29. package/dist/utils/persona.js +8 -3
  30. package/dist/utils/post-write-validator.js +29 -22
  31. package/dist/utils/project-memory.js +23 -16
  32. package/dist/utils/task-display.js +20 -13
  33. package/dist/utils/workspace-brain-service.d.ts +43 -0
  34. package/dist/utils/workspace-brain-service.js +158 -0
  35. package/dist/utils/workspace-cache.js +26 -18
  36. package/dist/utils/workspace-stream.js +63 -21
  37. package/package.json +3 -6
  38. package/scripts/release/validate-no-go-gates.sh +1 -1
  39. package/dist/commands/fork.d.ts +0 -17
  40. package/dist/commands/fork.js +0 -164
  41. package/dist/commands/history.d.ts +0 -17
  42. package/dist/commands/history.js +0 -113
  43. package/dist/commands/preview.d.ts +0 -55
  44. package/dist/commands/preview.js +0 -467
  45. package/dist/commands/replay.d.ts +0 -18
  46. package/dist/commands/replay.js +0 -156
  47. package/dist/commands/repo.d.ts +0 -97
  48. package/dist/commands/repo.js +0 -773
  49. package/dist/commands/update.d.ts +0 -9
  50. package/dist/commands/update.js +0 -201
  51. package/dist/index.d.ts +0 -21
  52. package/dist/index.js +0 -1823
  53. package/dist/utils/api.d.ts +0 -572
  54. package/dist/utils/api.js +0 -6548
  55. package/dist/utils/cli-state.d.ts +0 -54
  56. package/dist/utils/cli-state.js +0 -185
  57. package/dist/utils/config.d.ts +0 -85
  58. package/dist/utils/config.js +0 -267
  59. package/dist/utils/session.d.ts +0 -118
  60. package/dist/utils/session.js +0 -423
  61. package/dist/utils/tools.d.ts +0 -274
  62. package/dist/utils/tools.js +0 -3502
@@ -1,113 +0,0 @@
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
- }
@@ -1,55 +0,0 @@
1
- /**
2
- * Vigthoria CLI - Preview Command
3
- *
4
- * Local preview server + consolidated visual diffs + Template Service proof gate
5
- *
6
- * Usage:
7
- * vigthoria preview - Preview project in browser
8
- * vigthoria preview --diff - Show consolidated diff of recent agent changes
9
- * vigthoria preview --proof - Run Template Service preview gate
10
- * vigthoria preview -p /path/to/project - Preview specific project
11
- */
12
- import { Config } from '../utils/config.js';
13
- import { Logger } from '../utils/logger.js';
14
- interface PreviewOptions {
15
- project: string;
16
- entry?: string;
17
- port?: number;
18
- open?: boolean;
19
- diff?: boolean;
20
- proof?: boolean;
21
- screenshot?: boolean;
22
- }
23
- export declare class PreviewCommand {
24
- private config;
25
- private logger;
26
- private api;
27
- private server;
28
- constructor(config: Config, logger: Logger);
29
- run(options: PreviewOptions): Promise<void>;
30
- /**
31
- * Detect the HTML entry file in the project
32
- */
33
- private detectEntryFile;
34
- /**
35
- * Find an available port starting from the given number
36
- */
37
- private findAvailablePort;
38
- /**
39
- * Start a local HTTP server for preview
40
- */
41
- private startServer;
42
- /**
43
- * Open URL in default browser
44
- */
45
- private openBrowser;
46
- /**
47
- * Show consolidated diff of recent agent changes using git
48
- */
49
- showConsolidatedDiff(projectPath: string): Promise<void>;
50
- /**
51
- * Run Template Service preview gate and persist proof bundle
52
- */
53
- private runProofGate;
54
- }
55
- export {};
@@ -1,467 +0,0 @@
1
- /**
2
- * Vigthoria CLI - Preview Command
3
- *
4
- * Local preview server + consolidated visual diffs + Template Service proof gate
5
- *
6
- * Usage:
7
- * vigthoria preview - Preview project in browser
8
- * vigthoria preview --diff - Show consolidated diff of recent agent changes
9
- * vigthoria preview --proof - Run Template Service preview gate
10
- * vigthoria preview -p /path/to/project - Preview specific project
11
- */
12
- import chalk from 'chalk';
13
- import * as fs from 'fs';
14
- import * as path from 'path';
15
- import * as http from 'http';
16
- import { createRequire } from 'node:module';
17
- import { structuredPatch } from 'diff';
18
- import { createSpinner, CH } from '../utils/logger.js';
19
- import { APIClient } from '../utils/api.js';
20
- const require = createRequire(import.meta.url);
21
- // Common MIME types for static file serving
22
- const MIME_TYPES = {
23
- '.html': 'text/html',
24
- '.htm': 'text/html',
25
- '.css': 'text/css',
26
- '.js': 'application/javascript',
27
- '.mjs': 'application/javascript',
28
- '.json': 'application/json',
29
- '.png': 'image/png',
30
- '.jpg': 'image/jpeg',
31
- '.jpeg': 'image/jpeg',
32
- '.gif': 'image/gif',
33
- '.svg': 'image/svg+xml',
34
- '.ico': 'image/x-icon',
35
- '.webp': 'image/webp',
36
- '.woff': 'font/woff',
37
- '.woff2': 'font/woff2',
38
- '.ttf': 'font/ttf',
39
- '.eot': 'application/vnd.ms-fontobject',
40
- '.mp4': 'video/mp4',
41
- '.webm': 'video/webm',
42
- '.mp3': 'audio/mpeg',
43
- '.wav': 'audio/wav',
44
- '.pdf': 'application/pdf',
45
- '.xml': 'application/xml',
46
- '.txt': 'text/plain',
47
- '.map': 'application/json',
48
- };
49
- export class PreviewCommand {
50
- config;
51
- logger;
52
- api;
53
- server = null;
54
- constructor(config, logger) {
55
- this.config = config;
56
- this.logger = logger;
57
- this.api = new APIClient(config, logger);
58
- }
59
- async run(options) {
60
- const projectPath = path.resolve(options.project || process.cwd());
61
- if (!fs.existsSync(projectPath) || !fs.statSync(projectPath).isDirectory()) {
62
- this.logger.error(`Project directory not found: ${projectPath}`);
63
- this.api.destroy();
64
- return;
65
- }
66
- console.log();
67
- console.log(chalk.bold.white(` ${CH.hLine.repeat(3)} Vigthoria Preview ${CH.hLine.repeat(40)}`));
68
- console.log(chalk.gray(` Project: ${projectPath}`));
69
- console.log();
70
- // Show consolidated diff of recent agent changes
71
- if (options.diff) {
72
- await this.showConsolidatedDiff(projectPath);
73
- }
74
- // Run Template Service preview proof gate
75
- if (options.proof) {
76
- await this.runProofGate(projectPath, options.screenshot);
77
- }
78
- // If only --diff or --proof was requested (no explicit entry/port), just exit
79
- if (options.diff || options.proof) {
80
- if (!options.entry && !options.port) {
81
- this.api.destroy();
82
- return;
83
- }
84
- }
85
- // Detect entry file
86
- const entryFile = this.detectEntryFile(projectPath, options.entry);
87
- if (!entryFile) {
88
- this.logger.warn('No HTML entry file found. Use --entry <file> to specify one.');
89
- if (!options.diff && !options.proof) {
90
- this.api.destroy();
91
- return;
92
- }
93
- this.api.destroy();
94
- return;
95
- }
96
- // Start local preview server
97
- const port = options.port || (await this.findAvailablePort(3500));
98
- await this.startServer(projectPath, entryFile, port, options.open !== false);
99
- }
100
- /**
101
- * Detect the HTML entry file in the project
102
- */
103
- detectEntryFile(projectPath, specified) {
104
- if (specified) {
105
- const fullPath = path.join(projectPath, specified);
106
- if (fs.existsSync(fullPath))
107
- return specified;
108
- this.logger.warn(`Specified entry file not found: ${specified}`);
109
- return null;
110
- }
111
- // Common entry point candidates
112
- const candidates = [
113
- 'index.html',
114
- 'public/index.html',
115
- 'dist/index.html',
116
- 'build/index.html',
117
- 'src/index.html',
118
- 'out/index.html',
119
- ];
120
- for (const candidate of candidates) {
121
- if (fs.existsSync(path.join(projectPath, candidate))) {
122
- return candidate;
123
- }
124
- }
125
- // Fallback: find any .html file at root
126
- try {
127
- const rootFiles = fs.readdirSync(projectPath);
128
- const htmlFile = rootFiles.find(f => f.endsWith('.html'));
129
- if (htmlFile)
130
- return htmlFile;
131
- }
132
- catch { /* ignore */ }
133
- return null;
134
- }
135
- /**
136
- * Find an available port starting from the given number
137
- */
138
- findAvailablePort(startPort) {
139
- return new Promise((resolve) => {
140
- const testServer = http.createServer();
141
- testServer.on('error', () => {
142
- resolve(this.findAvailablePort(startPort + 1));
143
- });
144
- testServer.listen(startPort, () => {
145
- testServer.close(() => resolve(startPort));
146
- });
147
- });
148
- }
149
- /**
150
- * Start a local HTTP server for preview
151
- */
152
- async startServer(projectPath, entryFile, port, autoOpen) {
153
- return new Promise((resolve) => {
154
- this.server = http.createServer((req, res) => {
155
- // Sanitize URL to prevent path traversal
156
- const urlPath = decodeURIComponent(new URL(req.url || '/', `http://localhost:${port}`).pathname);
157
- const safePath = path.normalize(urlPath).replace(/^(\.\.[/\\])+/, '');
158
- let filePath = path.join(projectPath, safePath);
159
- // Ensure the resolved path is within the project directory
160
- const resolvedPath = path.resolve(filePath);
161
- if (!resolvedPath.startsWith(path.resolve(projectPath))) {
162
- res.writeHead(403);
163
- res.end('Forbidden');
164
- return;
165
- }
166
- // Directory → serve index.html
167
- if (fs.existsSync(filePath) && fs.statSync(filePath).isDirectory()) {
168
- filePath = path.join(filePath, 'index.html');
169
- }
170
- // SPA fallback
171
- if (!fs.existsSync(filePath)) {
172
- const spaFallback = path.join(projectPath, entryFile);
173
- if (fs.existsSync(spaFallback)) {
174
- filePath = spaFallback;
175
- }
176
- else {
177
- res.writeHead(404);
178
- res.end('Not found');
179
- return;
180
- }
181
- }
182
- const ext = path.extname(filePath).toLowerCase();
183
- const contentType = MIME_TYPES[ext] || 'application/octet-stream';
184
- try {
185
- const content = fs.readFileSync(filePath);
186
- res.writeHead(200, { 'Content-Type': contentType });
187
- res.end(content);
188
- }
189
- catch {
190
- res.writeHead(500);
191
- res.end('Internal server error');
192
- }
193
- });
194
- this.server.listen(port, () => {
195
- const url = `http://localhost:${port}/${entryFile}`;
196
- console.log(chalk.green(` ${CH.success} Preview server running`));
197
- console.log(chalk.gray(` URL: `) + chalk.cyan.underline(url));
198
- console.log(chalk.gray(` Entry: ${entryFile}`));
199
- console.log(chalk.gray(` Press Ctrl+C to stop`));
200
- console.log();
201
- if (autoOpen) {
202
- this.openBrowser(url);
203
- }
204
- });
205
- // Handle graceful shutdown
206
- const shutdown = () => {
207
- console.log(chalk.gray('\n Stopping preview server...'));
208
- this.server?.close();
209
- this.api.destroy();
210
- resolve();
211
- };
212
- process.on('SIGINT', shutdown);
213
- process.on('SIGTERM', shutdown);
214
- });
215
- }
216
- /**
217
- * Open URL in default browser
218
- */
219
- openBrowser(url) {
220
- const { execFile } = require('child_process');
221
- const platform = process.platform;
222
- // Validate URL scheme before passing to OS — prevents shell injection via crafted URLs
223
- try {
224
- const parsed = new URL(url);
225
- if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:')
226
- return;
227
- const safeUrl = parsed.href;
228
- if (platform === 'darwin') {
229
- execFile('open', [safeUrl], (err) => {
230
- if (err)
231
- this.logger.debug(`Could not auto-open browser: ${err.message}`);
232
- });
233
- }
234
- else if (platform === 'win32') {
235
- execFile('cmd', ['/c', 'start', '', safeUrl], (err) => {
236
- if (err)
237
- this.logger.debug(`Could not auto-open browser: ${err.message}`);
238
- });
239
- }
240
- else {
241
- execFile('xdg-open', [safeUrl], (err) => {
242
- if (err)
243
- this.logger.debug(`Could not auto-open browser: ${err.message}`);
244
- });
245
- }
246
- }
247
- catch {
248
- this.logger.debug(`Skipping browser open — invalid URL: ${url}`);
249
- }
250
- }
251
- /**
252
- * Show consolidated diff of recent agent changes using git
253
- */
254
- async showConsolidatedDiff(projectPath) {
255
- console.log(chalk.bold.white(` ${CH.hLine.repeat(3)} Change Summary ${CH.hLine.repeat(43)}`));
256
- console.log();
257
- const proofDir = path.join(projectPath, '.vigthoria', 'proof', 'preview');
258
- const hasProof = fs.existsSync(proofDir);
259
- // Try git diff first (most reliable)
260
- try {
261
- const { execSync } = require('child_process');
262
- const isGit = fs.existsSync(path.join(projectPath, '.git'));
263
- if (isGit) {
264
- // Get list of changed files (unstaged + staged)
265
- const statusOutput = execSync('git status --porcelain', { cwd: projectPath, encoding: 'utf-8' }).trim();
266
- if (!statusOutput) {
267
- console.log(chalk.gray(' No changes detected (working tree clean).'));
268
- console.log();
269
- return;
270
- }
271
- const changedLines = statusOutput.split('\n').filter(Boolean);
272
- const created = [];
273
- const modified = [];
274
- const deleted = [];
275
- for (const line of changedLines) {
276
- const status = line.substring(0, 2).trim();
277
- const filePath = line.substring(3);
278
- if (status === '??' || status === 'A')
279
- created.push(filePath);
280
- else if (status === 'D')
281
- deleted.push(filePath);
282
- else
283
- modified.push(filePath);
284
- }
285
- // Summary header
286
- const total = created.length + modified.length + deleted.length;
287
- console.log(chalk.white(` ${total} file${total !== 1 ? 's' : ''} changed:`));
288
- for (const f of created)
289
- console.log(chalk.green(` + ${f}`));
290
- for (const f of modified)
291
- console.log(chalk.yellow(` ~ ${f}`));
292
- for (const f of deleted)
293
- console.log(chalk.red(` - ${f}`));
294
- console.log();
295
- // Show unified diffs for modified and created files (limit to keep terminal manageable)
296
- const diffTargets = [...modified, ...created].slice(0, 20);
297
- for (const relPath of diffTargets) {
298
- const absPath = path.join(projectPath, relPath);
299
- if (!fs.existsSync(absPath))
300
- continue;
301
- const ext = path.extname(relPath).toLowerCase();
302
- const textExts = ['.html', '.css', '.js', '.ts', '.jsx', '.tsx', '.json', '.md', '.yml', '.yaml', '.txt', '.xml', '.svg', '.py', '.sh', '.env'];
303
- if (!textExts.includes(ext))
304
- continue;
305
- try {
306
- const newContent = fs.readFileSync(absPath, 'utf-8');
307
- let oldContent = '';
308
- if (modified.includes(relPath)) {
309
- try {
310
- // Validate relPath is a safe relative path before interpolating — prevents injection
311
- if (/^[a-zA-Z0-9_\-./]+$/.test(relPath) && !relPath.includes('..')) {
312
- oldContent = execSync(`git show HEAD:${relPath}`, { cwd: projectPath, encoding: 'utf-8' });
313
- }
314
- }
315
- catch {
316
- // File is new or not tracked
317
- }
318
- }
319
- const patch = structuredPatch(relPath, relPath, oldContent, newContent, 'before', 'after', { context: 3 });
320
- if (patch.hunks.length === 0)
321
- continue;
322
- console.log(chalk.bold.white(` ${CH.hLine.repeat(3)} ${relPath} ${CH.hLine.repeat(Math.max(1, 50 - relPath.length))}`));
323
- console.log(chalk.gray(` --- a/${relPath}`));
324
- console.log(chalk.gray(` +++ b/${relPath}`));
325
- for (const hunk of patch.hunks) {
326
- console.log(chalk.cyan(` @@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`));
327
- for (const line of hunk.lines) {
328
- if (line.startsWith('+')) {
329
- console.log(chalk.green(` ${line}`));
330
- }
331
- else if (line.startsWith('-')) {
332
- console.log(chalk.red(` ${line}`));
333
- }
334
- else {
335
- console.log(chalk.gray(` ${line}`));
336
- }
337
- }
338
- }
339
- console.log();
340
- }
341
- catch {
342
- // Skip files that can't be diffed
343
- }
344
- }
345
- if (diffTargets.length < modified.length + created.length) {
346
- console.log(chalk.gray(` ... and ${modified.length + created.length - diffTargets.length} more files`));
347
- console.log();
348
- }
349
- return;
350
- }
351
- }
352
- catch {
353
- // git not available, fall through
354
- }
355
- // Fallback: list .vigthoria/proof manifests
356
- if (hasProof) {
357
- const manifests = fs.readdirSync(proofDir)
358
- .filter(f => f.endsWith('.json'))
359
- .sort()
360
- .reverse()
361
- .slice(0, 5);
362
- if (manifests.length > 0) {
363
- console.log(chalk.white(' Recent proof bundles:'));
364
- for (const m of manifests) {
365
- try {
366
- const manifest = JSON.parse(fs.readFileSync(path.join(proofDir, m), 'utf-8'));
367
- const passed = manifest.previewGate?.passed ? chalk.green('passed') : chalk.red('failed');
368
- console.log(chalk.gray(` ${manifest.createdAt || m} `) + passed + chalk.gray(` ${manifest.entryPath || '-'}`));
369
- }
370
- catch {
371
- console.log(chalk.gray(` ${m}`));
372
- }
373
- }
374
- console.log();
375
- }
376
- }
377
- else {
378
- console.log(chalk.gray(' No git history or proof bundles found.'));
379
- console.log(chalk.gray(' Run an agent task first to generate changes.'));
380
- console.log();
381
- }
382
- }
383
- /**
384
- * Run Template Service preview gate and persist proof bundle
385
- */
386
- async runProofGate(projectPath, captureScreenshot) {
387
- const spinner = createSpinner('Running preview proof gate...').start();
388
- try {
389
- const result = await this.api.runTemplateServicePreviewGate('', {
390
- workspacePath: projectPath,
391
- projectPath: projectPath,
392
- targetPath: projectPath,
393
- });
394
- spinner.stop();
395
- console.log(chalk.bold.white(` ${CH.hLine.repeat(3)} Preview Proof Gate ${CH.hLine.repeat(39)}`));
396
- console.log();
397
- if (!result.required) {
398
- console.log(chalk.gray(' Preview gate: not required (no frontend artifacts detected)'));
399
- console.log();
400
- return;
401
- }
402
- const statusIcon = result.passed ? chalk.green(CH.success) : chalk.red(CH.error);
403
- console.log(` ${statusIcon} Preview gate: ${result.passed ? chalk.green('PASSED') : chalk.red('FAILED')}`);
404
- if (result.error) {
405
- console.log(chalk.yellow(` Error: ${result.error}`));
406
- }
407
- // Show modes
408
- if (result.modes) {
409
- const modes = result.modes;
410
- console.log();
411
- if (modes.design) {
412
- const designStatus = modes.design.ready ? chalk.green('ready') : chalk.gray('not ready');
413
- console.log(chalk.gray(` Design mode: `) + designStatus);
414
- if (modes.design.devices) {
415
- console.log(chalk.gray(` Devices: ${modes.design.devices.join(', ')}`));
416
- }
417
- }
418
- if (modes.live) {
419
- const liveStatus = modes.live.ready ? chalk.green('ready') : chalk.gray('not ready');
420
- console.log(chalk.gray(` Live mode: `) + liveStatus);
421
- if (modes.live.entryPoint) {
422
- console.log(chalk.gray(` Entry: ${modes.live.entryPoint}`));
423
- }
424
- }
425
- if (modes.production) {
426
- const prodStatus = modes.production.ready ? chalk.green('ready') : chalk.gray('not ready');
427
- console.log(chalk.gray(` Production mode: `) + prodStatus);
428
- }
429
- }
430
- // Show summary
431
- if (result.summary) {
432
- console.log();
433
- const summary = result.summary;
434
- if (summary.hasViewportMeta !== undefined) {
435
- console.log(chalk.gray(` Viewport meta: `) + (summary.hasViewportMeta ? chalk.green('yes') : chalk.yellow('missing')));
436
- }
437
- if (summary.hasResponsiveSignals !== undefined) {
438
- console.log(chalk.gray(` Responsive CSS: `) + (summary.hasResponsiveSignals ? chalk.green('yes') : chalk.gray('no')));
439
- }
440
- if (summary.hasInteractiveSignals !== undefined) {
441
- console.log(chalk.gray(` Interactive JS: `) + (summary.hasInteractiveSignals ? chalk.green('yes') : chalk.gray('no')));
442
- }
443
- if (typeof summary.sectionCount === 'number') {
444
- console.log(chalk.gray(` Section count: ${summary.sectionCount}`));
445
- }
446
- }
447
- // Show artifacts
448
- if (result.artifacts) {
449
- console.log();
450
- if (result.artifacts.manifestPath) {
451
- console.log(chalk.gray(` Manifest: ${result.artifacts.manifestPath}`));
452
- }
453
- if (result.artifacts.screenshotCaptured && result.artifacts.screenshotPath) {
454
- console.log(chalk.gray(` Screenshot: ${result.artifacts.screenshotPath}`));
455
- }
456
- if (result.artifacts.previewFileUrl) {
457
- console.log(chalk.gray(` File URL: `) + chalk.cyan.underline(result.artifacts.previewFileUrl));
458
- }
459
- }
460
- console.log();
461
- }
462
- catch (error) {
463
- spinner.stop();
464
- this.logger.error(`Preview proof gate failed: ${error?.message || String(error)}`);
465
- }
466
- }
467
- }
@@ -1,18 +0,0 @@
1
- import { Config } from '../utils/config.js';
2
- import { Logger } from '../utils/logger.js';
3
- interface ReplayOptions {
4
- speed?: number;
5
- json?: boolean;
6
- project?: string;
7
- }
8
- export declare class ReplayCommand {
9
- private config;
10
- private logger;
11
- constructor(config: Config, logger: Logger);
12
- private getHeaders;
13
- private getBaseUrl;
14
- private resolveWorkspaceRoot;
15
- private sleep;
16
- run(runId: string, options: ReplayOptions): Promise<void>;
17
- }
18
- export {};