@vibecheckai/cli 3.0.9 → 3.0.10
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/bin/runners/lib/report-html.js +378 -1
- package/bin/runners/runBadge.js +823 -116
- package/bin/runners/runCtx.js +602 -119
- package/bin/runners/runDoctor.js +329 -42
- package/bin/runners/runFix.js +544 -85
- package/bin/runners/runGraph.js +231 -74
- package/bin/runners/runInit.js +647 -88
- package/bin/runners/runInstall.js +207 -46
- package/bin/runners/runPR.js +123 -32
- package/bin/runners/runProve.js +818 -97
- package/bin/runners/runReality.js +812 -92
- package/bin/runners/runReport.js +68 -2
- package/bin/runners/runShare.js +156 -38
- package/bin/runners/runShip.js +920 -889
- package/bin/runners/runWatch.js +175 -55
- package/mcp-server/package.json +1 -1
- package/package.json +1 -1
package/bin/runners/runWatch.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* vibecheck watch - Continuous Dev Mode
|
|
3
3
|
*
|
|
4
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
5
|
+
* ENTERPRISE EDITION - World-Class Terminal Experience
|
|
6
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
7
|
+
*
|
|
4
8
|
* Watches for file changes and re-runs ship automatically.
|
|
5
9
|
* Shows a persistent status line with current verdict.
|
|
6
10
|
* Perfect for development workflow.
|
|
@@ -12,16 +16,92 @@ const fs = require("fs");
|
|
|
12
16
|
const path = require("path");
|
|
13
17
|
const { shipCore } = require("./runShip");
|
|
14
18
|
|
|
19
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
20
|
+
// ADVANCED TERMINAL - ANSI CODES & UTILITIES
|
|
21
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
22
|
+
|
|
15
23
|
const c = {
|
|
16
|
-
reset:
|
|
17
|
-
bold:
|
|
18
|
-
dim:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
reset: '\x1b[0m',
|
|
25
|
+
bold: '\x1b[1m',
|
|
26
|
+
dim: '\x1b[2m',
|
|
27
|
+
italic: '\x1b[3m',
|
|
28
|
+
underline: '\x1b[4m',
|
|
29
|
+
red: '\x1b[31m',
|
|
30
|
+
green: '\x1b[32m',
|
|
31
|
+
yellow: '\x1b[33m',
|
|
32
|
+
blue: '\x1b[34m',
|
|
33
|
+
magenta: '\x1b[35m',
|
|
34
|
+
cyan: '\x1b[36m',
|
|
35
|
+
white: '\x1b[37m',
|
|
36
|
+
gray: '\x1b[90m',
|
|
37
|
+
clear: '\x1b[2J\x1b[H',
|
|
38
|
+
clearLine: '\x1b[2K',
|
|
39
|
+
hideCursor: '\x1b[?25l',
|
|
40
|
+
showCursor: '\x1b[?25h',
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const rgb = (r, g, b) => `\x1b[38;2;${r};${g};${b}m`;
|
|
44
|
+
const bgRgb = (r, g, b) => `\x1b[48;2;${r};${g};${b}m`;
|
|
45
|
+
|
|
46
|
+
const colors = {
|
|
47
|
+
gradient1: rgb(150, 100, 255),
|
|
48
|
+
gradient2: rgb(130, 80, 255),
|
|
49
|
+
gradient3: rgb(110, 60, 255),
|
|
50
|
+
shipGreen: rgb(0, 255, 150),
|
|
51
|
+
warnAmber: rgb(255, 200, 0),
|
|
52
|
+
blockRed: rgb(255, 80, 80),
|
|
53
|
+
accent: rgb(150, 100, 255),
|
|
54
|
+
muted: rgb(120, 120, 140),
|
|
55
|
+
watching: rgb(100, 200, 255),
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
59
|
+
// PREMIUM BANNER
|
|
60
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
61
|
+
|
|
62
|
+
const WATCH_BANNER = `
|
|
63
|
+
${rgb(150, 100, 255)} ██╗ ██╗ █████╗ ████████╗ ██████╗██╗ ██╗${c.reset}
|
|
64
|
+
${rgb(130, 80, 255)} ██║ ██║██╔══██╗╚══██╔══╝██╔════╝██║ ██║${c.reset}
|
|
65
|
+
${rgb(110, 60, 255)} ██║ █╗ ██║███████║ ██║ ██║ ███████║${c.reset}
|
|
66
|
+
${rgb(90, 40, 255)} ██║███╗██║██╔══██║ ██║ ██║ ██╔══██║${c.reset}
|
|
67
|
+
${rgb(70, 20, 255)} ╚███╔███╔╝██║ ██║ ██║ ╚██████╗██║ ██║${c.reset}
|
|
68
|
+
${rgb(50, 0, 255)} ╚══╝╚══╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝${c.reset}
|
|
69
|
+
`;
|
|
70
|
+
|
|
71
|
+
const BANNER_FULL = `
|
|
72
|
+
${rgb(150, 100, 255)} ██╗ ██╗██╗██████╗ ███████╗ ██████╗██╗ ██╗███████╗ ██████╗██╗ ██╗${c.reset}
|
|
73
|
+
${rgb(140, 90, 255)} ██║ ██║██║██╔══██╗██╔════╝██╔════╝██║ ██║██╔════╝██╔════╝██║ ██╔╝${c.reset}
|
|
74
|
+
${rgb(130, 80, 255)} ██║ ██║██║██████╔╝█████╗ ██║ ███████║█████╗ ██║ █████╔╝ ${c.reset}
|
|
75
|
+
${rgb(110, 60, 255)} ╚██╗ ██╔╝██║██╔══██╗██╔══╝ ██║ ██╔══██║██╔══╝ ██║ ██╔═██╗ ${c.reset}
|
|
76
|
+
${rgb(90, 40, 255)} ╚████╔╝ ██║██████╔╝███████╗╚██████╗██║ ██║███████╗╚██████╗██║ ██╗${c.reset}
|
|
77
|
+
${rgb(70, 20, 255)} ╚═══╝ ╚═╝╚═════╝ ╚══════╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═════╝╚═╝ ╚═╝${c.reset}
|
|
78
|
+
|
|
79
|
+
${c.dim} ┌─────────────────────────────────────────────────────────────────────┐${c.reset}
|
|
80
|
+
${c.dim} │${c.reset} ${rgb(150, 100, 255)}👁️${c.reset} ${c.bold}WATCH${c.reset} ${c.dim}•${c.reset} ${rgb(200, 200, 200)}Live Reload${c.reset} ${c.dim}•${c.reset} ${rgb(150, 150, 150)}Auto Analysis${c.reset} ${c.dim}•${c.reset} ${rgb(100, 100, 100)}Dev Mode${c.reset} ${c.dim}│${c.reset}
|
|
81
|
+
${c.dim} └─────────────────────────────────────────────────────────────────────┘${c.reset}
|
|
82
|
+
`;
|
|
83
|
+
|
|
84
|
+
const BOX = {
|
|
85
|
+
topLeft: '╭', topRight: '╮', bottomLeft: '╰', bottomRight: '╯',
|
|
86
|
+
horizontal: '─', vertical: '│',
|
|
87
|
+
dTopLeft: '╔', dTopRight: '╗', dBottomLeft: '╚', dBottomRight: '╝',
|
|
88
|
+
dHorizontal: '═', dVertical: '║',
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const ICONS = {
|
|
92
|
+
eye: '👁️',
|
|
93
|
+
check: '✓',
|
|
94
|
+
cross: '✗',
|
|
95
|
+
warning: '⚠',
|
|
96
|
+
arrow: '→',
|
|
97
|
+
bullet: '•',
|
|
98
|
+
ship: '🚀',
|
|
99
|
+
clock: '⏱',
|
|
100
|
+
file: '📄',
|
|
101
|
+
sparkle: '✨',
|
|
102
|
+
lightning: '⚡',
|
|
103
|
+
refresh: '🔄',
|
|
104
|
+
watching: '◉',
|
|
25
105
|
};
|
|
26
106
|
|
|
27
107
|
const IGNORE_PATTERNS = [
|
|
@@ -58,29 +138,63 @@ function formatDuration(ms) {
|
|
|
58
138
|
return `${(ms / 1000).toFixed(1)}s`;
|
|
59
139
|
}
|
|
60
140
|
|
|
141
|
+
function progressBar(percent, width = 20) {
|
|
142
|
+
const filled = Math.round((percent / 100) * width);
|
|
143
|
+
const empty = width - filled;
|
|
144
|
+
const color = percent >= 80 ? colors.shipGreen : percent >= 50 ? colors.warnAmber : colors.blockRed;
|
|
145
|
+
return `${color}${'█'.repeat(filled)}${c.dim}${'░'.repeat(empty)}${c.reset}`;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function printDivider(char = '─', width = 62) {
|
|
149
|
+
console.log(` ${c.dim}${char.repeat(width)}${c.reset}`);
|
|
150
|
+
}
|
|
151
|
+
|
|
61
152
|
function printStatus({ verdict, findings, duration, lastFile, runCount }) {
|
|
62
|
-
const verdictColor = verdict === "SHIP" ?
|
|
153
|
+
const verdictColor = verdict === "SHIP" ? colors.shipGreen : verdict === "WARN" ? colors.warnAmber : colors.blockRed;
|
|
63
154
|
const blocks = findings.filter(f => f.severity === "BLOCK").length;
|
|
64
155
|
const warns = findings.filter(f => f.severity === "WARN").length;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
${c.dim}
|
|
72
|
-
${c.dim}
|
|
73
|
-
${c.dim}Duration:${c.reset} ${formatDuration(duration)}
|
|
74
|
-
${c.dim}Changed:${c.reset} ${lastFile || "(initial)"}
|
|
75
|
-
|
|
76
|
-
${c.bold} VERDICT: ${verdictColor}${verdict}${c.reset}
|
|
156
|
+
const total = blocks + warns;
|
|
157
|
+
const health = total === 0 ? 100 : Math.max(0, 100 - (blocks * 20) - (warns * 5));
|
|
158
|
+
|
|
159
|
+
console.log();
|
|
160
|
+
console.log(` ${c.dim}${BOX.dTopLeft}${BOX.dHorizontal.repeat(62)}${BOX.dTopRight}${c.reset}`);
|
|
161
|
+
console.log(` ${c.dim}${BOX.dVertical}${c.reset} ${colors.watching}${ICONS.eye}${c.reset} ${c.bold}VIBECHECK WATCH${c.reset} ${c.dim}${BOX.dVertical}${c.reset}`);
|
|
162
|
+
console.log(` ${c.dim}${BOX.dVertical}${BOX.dHorizontal.repeat(62)}${BOX.dVertical}${c.reset}`);
|
|
163
|
+
console.log(` ${c.dim}${BOX.dVertical}${c.reset} ${c.dim}${BOX.dVertical}${c.reset}`);
|
|
77
164
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
`);
|
|
165
|
+
// Stats row
|
|
166
|
+
console.log(` ${c.dim}${BOX.dVertical}${c.reset} ${c.dim}${ICONS.clock} Time:${c.reset} ${formatTime()} ${c.dim}${ICONS.refresh} Runs:${c.reset} ${runCount} ${c.dim}${ICONS.lightning} Duration:${c.reset} ${formatDuration(duration)} ${c.dim}${BOX.dVertical}${c.reset}`);
|
|
167
|
+
|
|
168
|
+
// Changed file
|
|
169
|
+
const changedDisplay = lastFile ? lastFile.slice(0, 40) : '(initial scan)';
|
|
170
|
+
console.log(` ${c.dim}${BOX.dVertical}${c.reset} ${c.dim}${ICONS.file} Changed:${c.reset} ${colors.accent}${changedDisplay}${c.reset}${' '.repeat(Math.max(0, 45 - changedDisplay.length))}${c.dim}${BOX.dVertical}${c.reset}`);
|
|
171
|
+
|
|
172
|
+
console.log(` ${c.dim}${BOX.dVertical}${c.reset} ${c.dim}${BOX.dVertical}${c.reset}`);
|
|
173
|
+
console.log(` ${c.dim}${BOX.dVertical}${BOX.dHorizontal.repeat(62)}${BOX.dVertical}${c.reset}`);
|
|
174
|
+
|
|
175
|
+
// Verdict
|
|
176
|
+
const verdictIcon = verdict === "SHIP" ? ICONS.ship : verdict === "WARN" ? ICONS.warning : ICONS.cross;
|
|
177
|
+
console.log(` ${c.dim}${BOX.dVertical}${c.reset} ${c.dim}${BOX.dVertical}${c.reset}`);
|
|
178
|
+
console.log(` ${c.dim}${BOX.dVertical}${c.reset} ${c.bold}VERDICT:${c.reset} ${verdictColor}${c.bold}${verdictIcon} ${verdict}${c.reset} ${c.dim}${BOX.dVertical}${c.reset}`);
|
|
179
|
+
console.log(` ${c.dim}${BOX.dVertical}${c.reset} ${c.dim}${BOX.dVertical}${c.reset}`);
|
|
180
|
+
|
|
181
|
+
// Health bar
|
|
182
|
+
console.log(` ${c.dim}${BOX.dVertical}${c.reset} ${c.dim}Health:${c.reset} ${progressBar(health)} ${health}% ${c.dim}${BOX.dVertical}${c.reset}`);
|
|
183
|
+
console.log(` ${c.dim}${BOX.dVertical}${c.reset} ${c.dim}Findings:${c.reset} ${colors.blockRed}${blocks}${c.reset} ${c.dim}BLOCK${c.reset} ${colors.warnAmber}${warns}${c.reset} ${c.dim}WARN${c.reset} ${c.dim}${BOX.dVertical}${c.reset}`);
|
|
184
|
+
|
|
185
|
+
console.log(` ${c.dim}${BOX.dVertical}${c.reset} ${c.dim}${BOX.dVertical}${c.reset}`);
|
|
186
|
+
|
|
187
|
+
// Status message
|
|
188
|
+
const statusMsg = verdict === "SHIP"
|
|
189
|
+
? `${colors.shipGreen}${ICONS.check}${c.reset} Ready to ship`
|
|
190
|
+
: `${colors.warnAmber}${ICONS.arrow}${c.reset} Run ${colors.accent}vibecheck fix${c.reset} to resolve`;
|
|
191
|
+
console.log(` ${c.dim}${BOX.dVertical}${c.reset} ${statusMsg} ${c.dim}${BOX.dVertical}${c.reset}`);
|
|
192
|
+
|
|
193
|
+
console.log(` ${c.dim}${BOX.dVertical}${c.reset} ${c.dim}${BOX.dVertical}${c.reset}`);
|
|
194
|
+
console.log(` ${c.dim}${BOX.dBottomLeft}${BOX.dHorizontal.repeat(62)}${BOX.dBottomRight}${c.reset}`);
|
|
195
|
+
console.log();
|
|
196
|
+
console.log(` ${c.dim}${ICONS.watching} Watching for changes... (Ctrl+C to stop)${c.reset}`);
|
|
197
|
+
console.log();
|
|
84
198
|
}
|
|
85
199
|
|
|
86
200
|
function printTopFindings(findings, max = 5) {
|
|
@@ -90,12 +204,13 @@ function printTopFindings(findings, max = 5) {
|
|
|
90
204
|
|
|
91
205
|
if (!top.length) return;
|
|
92
206
|
|
|
93
|
-
console.log(
|
|
207
|
+
console.log(` ${c.bold}Top findings:${c.reset}`);
|
|
94
208
|
for (const f of top) {
|
|
95
|
-
const icon = f.severity === "BLOCK" ?
|
|
96
|
-
|
|
209
|
+
const icon = f.severity === "BLOCK" ? `${colors.blockRed}●` : `${colors.warnAmber}●`;
|
|
210
|
+
const title = f.title?.length > 50 ? f.title.slice(0, 47) + '...' : f.title;
|
|
211
|
+
console.log(` ${icon}${c.reset} ${title}`);
|
|
97
212
|
}
|
|
98
|
-
console.log(
|
|
213
|
+
console.log();
|
|
99
214
|
}
|
|
100
215
|
|
|
101
216
|
async function runShipQuiet(root, fastifyEntry) {
|
|
@@ -159,37 +274,42 @@ function watchDirectory(dir, callback) {
|
|
|
159
274
|
}
|
|
160
275
|
|
|
161
276
|
function printHelp() {
|
|
277
|
+
console.log(BANNER_FULL);
|
|
162
278
|
console.log(`
|
|
163
|
-
${c.
|
|
279
|
+
${c.bold}Usage:${c.reset} vibecheck watch [options]
|
|
280
|
+
|
|
281
|
+
${c.bold}Continuous Dev Mode${c.reset} — Live reload with automatic ship analysis.
|
|
282
|
+
|
|
283
|
+
${c.bold}Options:${c.reset}
|
|
284
|
+
${colors.accent}--fastify-entry <path>${c.reset} Fastify entry file for route extraction
|
|
285
|
+
${colors.accent}--debounce <ms>${c.reset} Debounce delay in ms ${c.dim}(default: 500)${c.reset}
|
|
286
|
+
${colors.accent}--no-clear${c.reset} Don't clear screen between runs
|
|
287
|
+
${colors.accent}--help, -h${c.reset} Show this help
|
|
164
288
|
|
|
165
|
-
${c.bold}
|
|
166
|
-
|
|
289
|
+
${c.bold}What It Does:${c.reset}
|
|
290
|
+
${colors.shipGreen}1.${c.reset} Runs initial ship analysis
|
|
291
|
+
${colors.shipGreen}2.${c.reset} Watches for file changes in your project
|
|
292
|
+
${colors.shipGreen}3.${c.reset} Re-runs analysis on each change
|
|
293
|
+
${colors.shipGreen}4.${c.reset} Shows live verdict dashboard
|
|
167
294
|
|
|
168
|
-
${c.bold}
|
|
169
|
-
|
|
170
|
-
--debounce <ms> Debounce delay in ms (default: 500)
|
|
171
|
-
--no-clear Don't clear screen between runs
|
|
172
|
-
--help, -h Show this help
|
|
295
|
+
${c.bold}Watched Files:${c.reset}
|
|
296
|
+
${colors.accent}.ts${c.reset} ${colors.accent}.tsx${c.reset} ${colors.accent}.js${c.reset} ${colors.accent}.jsx${c.reset} ${colors.accent}.json${c.reset} ${colors.accent}.env${c.reset} ${colors.accent}.md${c.reset} ${colors.accent}.yml${c.reset} ${colors.accent}.yaml${c.reset}
|
|
173
297
|
|
|
174
|
-
${c.bold}
|
|
175
|
-
|
|
176
|
-
2. Watches for file changes in your project
|
|
177
|
-
3. Re-runs analysis on each change
|
|
178
|
-
4. Shows live verdict dashboard
|
|
298
|
+
${c.bold}Ignored:${c.reset}
|
|
299
|
+
${c.dim}node_modules, .next, .vibecheck, dist, build, .git${c.reset}
|
|
179
300
|
|
|
180
|
-
${c.bold}
|
|
181
|
-
|
|
301
|
+
${c.bold}Examples:${c.reset}
|
|
302
|
+
${c.dim}# Start watching${c.reset}
|
|
303
|
+
vibecheck watch
|
|
182
304
|
|
|
183
|
-
${c.
|
|
184
|
-
|
|
305
|
+
${c.dim}# 1 second debounce${c.reset}
|
|
306
|
+
vibecheck watch --debounce 1000
|
|
185
307
|
|
|
186
|
-
${c.
|
|
187
|
-
|
|
188
|
-
vibecheck watch --debounce 1000 # 1s debounce
|
|
189
|
-
vibecheck watch --no-clear # Keep history
|
|
308
|
+
${c.dim}# Keep history (don't clear)${c.reset}
|
|
309
|
+
vibecheck watch --no-clear
|
|
190
310
|
|
|
191
|
-
${c.dim}Press Ctrl+C to stop watching${c.reset}
|
|
192
|
-
`);
|
|
311
|
+
${c.dim}Press Ctrl+C to stop watching${c.reset}
|
|
312
|
+
`);
|
|
193
313
|
}
|
|
194
314
|
|
|
195
315
|
async function runWatch(argsOrOpts = {}) {
|
package/mcp-server/package.json
CHANGED