@vibecheckai/cli 3.1.6 → 3.2.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.
Files changed (56) hide show
  1. package/README.md +27 -32
  2. package/bin/registry.js +208 -343
  3. package/bin/runners/context/generators/mcp.js +18 -0
  4. package/bin/runners/context/index.js +72 -4
  5. package/bin/runners/context/proof-context.js +293 -1
  6. package/bin/runners/context/security-scanner.js +311 -73
  7. package/bin/runners/lib/analyzers.js +607 -20
  8. package/bin/runners/lib/detectors-v2.js +172 -15
  9. package/bin/runners/lib/entitlements-v2.js +48 -1
  10. package/bin/runners/lib/evidence-pack.js +678 -0
  11. package/bin/runners/lib/html-proof-report.js +913 -0
  12. package/bin/runners/lib/missions/plan.js +231 -41
  13. package/bin/runners/lib/missions/templates.js +125 -0
  14. package/bin/runners/lib/scan-output.js +492 -253
  15. package/bin/runners/lib/ship-output.js +901 -641
  16. package/bin/runners/runCheckpoint.js +44 -3
  17. package/bin/runners/runContext.d.ts +4 -0
  18. package/bin/runners/runContext.js +2 -3
  19. package/bin/runners/runDoctor.js +11 -4
  20. package/bin/runners/runFix.js +51 -341
  21. package/bin/runners/runInit.js +37 -20
  22. package/bin/runners/runPolish.d.ts +4 -0
  23. package/bin/runners/runPolish.js +608 -29
  24. package/bin/runners/runProve.js +210 -25
  25. package/bin/runners/runReality.js +861 -107
  26. package/bin/runners/runScan.js +238 -4
  27. package/bin/runners/runShip.js +19 -3
  28. package/bin/runners/runWatch.js +25 -5
  29. package/bin/vibecheck.js +35 -47
  30. package/mcp-server/consolidated-tools.js +408 -42
  31. package/mcp-server/index.js +152 -15
  32. package/mcp-server/package.json +1 -1
  33. package/mcp-server/proof-tools.js +571 -0
  34. package/mcp-server/tier-auth.js +22 -19
  35. package/mcp-server/tools-v3.js +744 -0
  36. package/mcp-server/truth-firewall-tools.js +190 -4
  37. package/package.json +3 -1
  38. package/bin/runners/runBadge.js +0 -916
  39. package/bin/runners/runContracts.js +0 -105
  40. package/bin/runners/runCtx.js +0 -680
  41. package/bin/runners/runCtxDiff.js +0 -301
  42. package/bin/runners/runCtxGuard.js +0 -176
  43. package/bin/runners/runCtxSync.js +0 -116
  44. package/bin/runners/runExport.js +0 -93
  45. package/bin/runners/runGraph.js +0 -454
  46. package/bin/runners/runInstall.js +0 -273
  47. package/bin/runners/runLabs.js +0 -341
  48. package/bin/runners/runLaunch.js +0 -181
  49. package/bin/runners/runPR.js +0 -255
  50. package/bin/runners/runPermissions.js +0 -310
  51. package/bin/runners/runPreflight.js +0 -580
  52. package/bin/runners/runReplay.js +0 -499
  53. package/bin/runners/runSecurity.js +0 -92
  54. package/bin/runners/runShare.js +0 -212
  55. package/bin/runners/runStatus.js +0 -102
  56. package/bin/runners/runVerify.js +0 -272
@@ -1,181 +0,0 @@
1
- /**
2
- * vibecheck launch - Pre-launch checklist wizard
3
- */
4
-
5
- const fs = require("fs");
6
- const path = require("path");
7
- const readline = require("readline");
8
-
9
- const c = {
10
- reset: "\x1b[0m",
11
- bold: "\x1b[1m",
12
- dim: "\x1b[2m",
13
- green: "\x1b[32m",
14
- yellow: "\x1b[33m",
15
- red: "\x1b[31m",
16
- cyan: "\x1b[36m",
17
- bgGreen: "\x1b[42m",
18
- bgYellow: "\x1b[43m",
19
- bgRed: "\x1b[41m",
20
- white: "\x1b[37m",
21
- };
22
-
23
- const CHECKLIST = [
24
- { id: "env", name: "Environment variables documented", category: "Config" },
25
- { id: "secrets", name: "No hardcoded secrets", category: "Security" },
26
- { id: "auth", name: "Authentication configured", category: "Security" },
27
- { id: "https", name: "HTTPS/TLS enabled", category: "Security" },
28
- { id: "cors", name: "CORS configured properly", category: "Security" },
29
- { id: "rate-limit", name: "Rate limiting enabled", category: "Security" },
30
- { id: "errors", name: "Error handling in place", category: "Reliability" },
31
- { id: "logging", name: "Logging configured", category: "Observability" },
32
- { id: "monitoring", name: "Monitoring/alerting set up", category: "Observability" },
33
- { id: "backup", name: "Database backup configured", category: "Data" },
34
- { id: "tests", name: "Tests passing", category: "Quality" },
35
- { id: "docs", name: "README updated", category: "Documentation" },
36
- { id: "changelog", name: "CHANGELOG updated", category: "Documentation" },
37
- { id: "version", name: "Version bumped", category: "Release" },
38
- ];
39
-
40
- function parseArgs(args) {
41
- const opts = {
42
- help: false,
43
- interactive: true,
44
- json: false,
45
- check: null,
46
- };
47
-
48
- for (let i = 0; i < args.length; i++) {
49
- const arg = args[i];
50
- switch (arg) {
51
- case "--help":
52
- case "-h":
53
- opts.help = true;
54
- break;
55
- case "--json":
56
- opts.json = true;
57
- opts.interactive = false;
58
- break;
59
- case "--check":
60
- opts.check = args[++i];
61
- opts.interactive = false;
62
- break;
63
- case "--no-interactive":
64
- opts.interactive = false;
65
- break;
66
- }
67
- }
68
-
69
- return opts;
70
- }
71
-
72
- function printHelp() {
73
- console.log(`
74
- ${c.bold}vibecheck launch${c.reset} - Pre-launch checklist wizard
75
-
76
- ${c.bold}USAGE${c.reset}
77
- vibecheck launch [options]
78
-
79
- ${c.bold}OPTIONS${c.reset}
80
- --help, -h Show this help
81
- --json Output checklist as JSON
82
- --check <id> Auto-check specific item
83
- --no-interactive Non-interactive mode
84
-
85
- ${c.bold}CHECKLIST ITEMS${c.reset}
86
- ${CHECKLIST.map(item => ` ${item.id.padEnd(12)} ${item.name}`).join("\n")}
87
-
88
- ${c.bold}EXAMPLES${c.reset}
89
- vibecheck launch # Interactive wizard
90
- vibecheck launch --json # Get checklist as JSON
91
- vibecheck launch --check env # Mark env as done
92
- `);
93
- }
94
-
95
- async function runInteractiveChecklist() {
96
- const rl = readline.createInterface({
97
- input: process.stdin,
98
- output: process.stdout,
99
- });
100
-
101
- const ask = (q) => new Promise((resolve) => rl.question(q, resolve));
102
-
103
- console.log(`
104
- ${c.bold}🚀 PRE-LAUNCH CHECKLIST${c.reset}
105
- ${c.dim}─────────────────────────────────────────${c.reset}
106
- `);
107
-
108
- const results = [];
109
- let currentCategory = "";
110
-
111
- for (const item of CHECKLIST) {
112
- if (item.category !== currentCategory) {
113
- currentCategory = item.category;
114
- console.log(`\n${c.cyan}${c.bold}${currentCategory}${c.reset}`);
115
- }
116
-
117
- const answer = await ask(` ${item.name}? [y/n/s] `);
118
- const status = answer.toLowerCase() === "y" ? "done" :
119
- answer.toLowerCase() === "s" ? "skip" : "pending";
120
-
121
- results.push({ ...item, status });
122
-
123
- if (status === "done") {
124
- process.stdout.write(`\x1b[1A\x1b[2K ${c.green}✓${c.reset} ${item.name}\n`);
125
- } else if (status === "skip") {
126
- process.stdout.write(`\x1b[1A\x1b[2K ${c.yellow}↷${c.reset} ${item.name} ${c.dim}(skipped)${c.reset}\n`);
127
- } else {
128
- process.stdout.write(`\x1b[1A\x1b[2K ${c.red}✗${c.reset} ${item.name}\n`);
129
- }
130
- }
131
-
132
- rl.close();
133
-
134
- // Summary
135
- const done = results.filter(r => r.status === "done").length;
136
- const pending = results.filter(r => r.status === "pending").length;
137
- const skipped = results.filter(r => r.status === "skip").length;
138
-
139
- console.log(`
140
- ${c.bold}─────────────────────────────────────────${c.reset}
141
- ${c.bold}SUMMARY${c.reset}
142
- ${c.green}✓ Done:${c.reset} ${done}
143
- ${c.red}✗ Pending:${c.reset} ${pending}
144
- ${c.yellow}↷ Skipped:${c.reset} ${skipped}
145
- `);
146
-
147
- if (pending === 0) {
148
- console.log(`${c.bgGreen}${c.white}${c.bold} 🚀 READY TO LAUNCH! ${c.reset}\n`);
149
- return 0;
150
- } else {
151
- console.log(`${c.bgYellow}${c.white}${c.bold} ⚠ ${pending} items remaining ${c.reset}\n`);
152
- return 1;
153
- }
154
- }
155
-
156
- async function runLaunch(args) {
157
- const opts = parseArgs(args);
158
-
159
- if (opts.help) {
160
- printHelp();
161
- return 0;
162
- }
163
-
164
- if (opts.json) {
165
- console.log(JSON.stringify({ checklist: CHECKLIST }, null, 2));
166
- return 0;
167
- }
168
-
169
- if (!opts.interactive) {
170
- console.log(`\n${c.bold}Pre-Launch Checklist${c.reset}\n`);
171
- for (const item of CHECKLIST) {
172
- console.log(` [ ] ${item.name}`);
173
- }
174
- console.log(`\n${c.dim}Run 'vibecheck launch' for interactive mode${c.reset}\n`);
175
- return 0;
176
- }
177
-
178
- return runInteractiveChecklist();
179
- }
180
-
181
- module.exports = { runLaunch };
@@ -1,255 +0,0 @@
1
- /**
2
- * vibecheck pr - Generate PR Comment from Ship Report
3
- *
4
- * ═══════════════════════════════════════════════════════════════════════════════
5
- * ENTERPRISE EDITION - World-Class Terminal Experience
6
- * ═══════════════════════════════════════════════════════════════════════════════
7
- */
8
-
9
- const fs = require("fs");
10
- const path = require("path");
11
- const { shipCore } = require("./runShip");
12
-
13
- // ═══════════════════════════════════════════════════════════════════════════════
14
- // ADVANCED TERMINAL - ANSI CODES & UTILITIES
15
- // ═══════════════════════════════════════════════════════════════════════════════
16
-
17
- const c = {
18
- reset: '\x1b[0m',
19
- bold: '\x1b[1m',
20
- dim: '\x1b[2m',
21
- italic: '\x1b[3m',
22
- underline: '\x1b[4m',
23
- red: '\x1b[31m',
24
- green: '\x1b[32m',
25
- yellow: '\x1b[33m',
26
- blue: '\x1b[34m',
27
- magenta: '\x1b[35m',
28
- cyan: '\x1b[36m',
29
- white: '\x1b[37m',
30
- gray: '\x1b[90m',
31
- clearLine: '\x1b[2K',
32
- hideCursor: '\x1b[?25l',
33
- showCursor: '\x1b[?25h',
34
- };
35
-
36
- const rgb = (r, g, b) => `\x1b[38;2;${r};${g};${b}m`;
37
- const bgRgb = (r, g, b) => `\x1b[48;2;${r};${g};${b}m`;
38
-
39
- const colors = {
40
- gradient1: rgb(100, 150, 255),
41
- gradient2: rgb(80, 130, 255),
42
- gradient3: rgb(60, 110, 255),
43
- shipGreen: rgb(0, 255, 150),
44
- warnAmber: rgb(255, 200, 0),
45
- blockRed: rgb(255, 80, 80),
46
- accent: rgb(100, 150, 255),
47
- muted: rgb(120, 120, 140),
48
- };
49
-
50
- // ═══════════════════════════════════════════════════════════════════════════════
51
- // PREMIUM BANNER
52
- // ═══════════════════════════════════════════════════════════════════════════════
53
-
54
- const PR_BANNER = `
55
- ${rgb(100, 150, 255)} ██████╗ ██████╗ ${c.reset}
56
- ${rgb(80, 130, 255)} ██╔══██╗██╔══██╗${c.reset}
57
- ${rgb(60, 110, 255)} ██████╔╝██████╔╝${c.reset}
58
- ${rgb(40, 90, 255)} ██╔═══╝ ██╔══██╗${c.reset}
59
- ${rgb(20, 70, 255)} ██║ ██║ ██║${c.reset}
60
- ${rgb(0, 50, 255)} ╚═╝ ╚═╝ ╚═╝${c.reset}
61
- `;
62
-
63
- const BANNER_FULL = `
64
- ${rgb(100, 150, 255)} ██╗ ██╗██╗██████╗ ███████╗ ██████╗██╗ ██╗███████╗ ██████╗██╗ ██╗${c.reset}
65
- ${rgb(90, 140, 255)} ██║ ██║██║██╔══██╗██╔════╝██╔════╝██║ ██║██╔════╝██╔════╝██║ ██╔╝${c.reset}
66
- ${rgb(80, 130, 255)} ██║ ██║██║██████╔╝█████╗ ██║ ███████║█████╗ ██║ █████╔╝ ${c.reset}
67
- ${rgb(60, 110, 255)} ╚██╗ ██╔╝██║██╔══██╗██╔══╝ ██║ ██╔══██║██╔══╝ ██║ ██╔═██╗ ${c.reset}
68
- ${rgb(40, 90, 255)} ╚████╔╝ ██║██████╔╝███████╗╚██████╗██║ ██║███████╗╚██████╗██║ ██╗${c.reset}
69
- ${rgb(20, 70, 255)} ╚═══╝ ╚═╝╚═════╝ ╚══════╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═════╝╚═╝ ╚═╝${c.reset}
70
-
71
- ${c.dim} ┌─────────────────────────────────────────────────────────────────────┐${c.reset}
72
- ${c.dim} │${c.reset} ${rgb(100, 150, 255)}📋${c.reset} ${c.bold}PR${c.reset} ${c.dim}•${c.reset} ${rgb(200, 200, 200)}GitHub Comments${c.reset} ${c.dim}•${c.reset} ${rgb(150, 150, 150)}CI Integration${c.reset} ${c.dim}•${c.reset} ${rgb(100, 100, 100)}Ship Verdict${c.reset} ${c.dim}│${c.reset}
73
- ${c.dim} └─────────────────────────────────────────────────────────────────────┘${c.reset}
74
- `;
75
-
76
- const ICONS = {
77
- pr: '📋',
78
- check: '✓',
79
- cross: '✗',
80
- warning: '⚠',
81
- arrow: '→',
82
- bullet: '•',
83
- ship: '🚀',
84
- github: '🐙',
85
- file: '📄',
86
- sparkle: '✨',
87
- };
88
-
89
- function printDivider(char = '─', width = 69, color = c.dim) {
90
- console.log(`${color} ${char.repeat(width)}${c.reset}`);
91
- }
92
-
93
- function printSection(title, icon = '◆') {
94
- console.log();
95
- console.log(` ${colors.accent}${icon}${c.reset} ${c.bold}${title}${c.reset}`);
96
- printDivider();
97
- }
98
-
99
- function printHelp() {
100
- console.log(BANNER_FULL);
101
- console.log(`
102
- ${c.bold}Usage:${c.reset} vibecheck pr [options]
103
-
104
- ${c.bold}PR Comment Generator${c.reset} — Generate GitHub-ready markdown from ship analysis.
105
-
106
- ${c.bold}Options:${c.reset}
107
- ${colors.accent}--fastify-entry <path>${c.reset} Fastify entry file for route extraction
108
- ${colors.accent}--out <file>${c.reset} Write markdown to file
109
- ${colors.accent}--fail-on-warn${c.reset} Exit 1 on WARN verdict
110
- ${colors.accent}--max-findings <n>${c.reset} Max findings to show ${c.dim}(default: 12)${c.reset}
111
- ${colors.accent}--help, -h${c.reset} Show this help
112
-
113
- ${c.bold}What It Does:${c.reset}
114
- ${colors.shipGreen}1.${c.reset} Runs ship analysis (static + runtime)
115
- ${colors.shipGreen}2.${c.reset} Generates GitHub-ready markdown summary
116
- ${colors.shipGreen}3.${c.reset} Outputs PR comment body to stdout
117
-
118
- ${c.bold}Exit Codes:${c.reset}
119
- ${colors.shipGreen}0${c.reset} SHIP or WARN ${c.dim}(without --fail-on-warn)${c.reset}
120
- ${colors.warnAmber}1${c.reset} WARN ${c.dim}(with --fail-on-warn)${c.reset}
121
- ${colors.blockRed}2${c.reset} BLOCK
122
-
123
- ${c.bold}Examples:${c.reset}
124
- ${c.dim}# Print PR comment to stdout${c.reset}
125
- vibecheck pr
126
-
127
- ${c.dim}# Save to file for GitHub Actions${c.reset}
128
- vibecheck pr --out pr-comment.md
129
-
130
- ${c.dim}# Strict CI mode (fail on warnings)${c.reset}
131
- vibecheck pr --fail-on-warn
132
- `);
133
- }
134
-
135
- function ensureDir(p) {
136
- fs.mkdirSync(p, { recursive: true });
137
- }
138
-
139
- function severityCounts(findings) {
140
- const counts = { BLOCK: 0, WARN: 0, INFO: 0 };
141
- for (const f of findings || []) {
142
- if (f.severity === "BLOCK") counts.BLOCK++;
143
- else if (f.severity === "WARN") counts.WARN++;
144
- else counts.INFO++;
145
- }
146
- return counts;
147
- }
148
-
149
- function toEmojiVerdict(v) {
150
- if (v === "SHIP") return "✅ SHIP";
151
- if (v === "WARN") return "⚠️ WARN";
152
- return "🛑 BLOCK";
153
- }
154
-
155
- function buildPrMarkdown({ report, maxFindings = 12 } = {}) {
156
- const verdict = report?.meta?.verdict || "unknown";
157
- const findings = report?.findings || [];
158
- const counts = severityCounts(findings);
159
-
160
- const top = findings
161
- .filter(f => f.severity === "BLOCK" || f.severity === "WARN")
162
- .slice(0, maxFindings);
163
-
164
- const lines = [];
165
- lines.push(`## vibecheck — ${toEmojiVerdict(verdict)}`);
166
- lines.push(``);
167
- lines.push(`**Reality summary:** BLOCK=${counts.BLOCK} • WARN=${counts.WARN}`);
168
- lines.push(``);
169
-
170
- if (!top.length) {
171
- lines.push(`✅ No blockers. Ship it.`);
172
- return lines.join("\n");
173
- }
174
-
175
- lines.push(`### Top findings`);
176
- for (const f of top) {
177
- lines.push(`- **${f.severity}** \`${f.id}\` — ${f.title}`);
178
- const ev = (f.evidence || [])[0];
179
- if (ev?.file) {
180
- lines.push(` - Evidence: \`${ev.file}:${ev.lines}\` (${ev.reason})`);
181
- if (ev.snippetHash) lines.push(` - SnipHash: \`${ev.snippetHash}\``);
182
- }
183
- const hint = (f.fixHints || [])[0];
184
- if (hint) lines.push(` - Fix: ${hint}`);
185
- }
186
-
187
- if (findings.length > top.length) {
188
- lines.push(``);
189
- lines.push(`_…and ${findings.length - top.length} more finding(s). See \`.vibecheck/last_ship.json\` for full details._`);
190
- }
191
-
192
- return lines.join("\n");
193
- }
194
-
195
- function exitCodeForVerdict(verdict, { failOnWarn = false } = {}) {
196
- if (verdict === "SHIP") return 0;
197
- if (verdict === "WARN") return failOnWarn ? 1 : 0;
198
- return 2; // BLOCK
199
- }
200
-
201
- async function runPR(argsOrOpts = {}) {
202
- // Handle array args from CLI
203
- if (Array.isArray(argsOrOpts)) {
204
- if (argsOrOpts.includes("--help") || argsOrOpts.includes("-h")) {
205
- printHelp();
206
- return 0;
207
- }
208
- const getArg = (flags) => {
209
- for (const f of flags) {
210
- const idx = argsOrOpts.indexOf(f);
211
- if (idx !== -1 && idx < argsOrOpts.length - 1) return argsOrOpts[idx + 1];
212
- }
213
- return undefined;
214
- };
215
- argsOrOpts = {
216
- repoRoot: process.cwd(),
217
- fastifyEntry: getArg(["--fastify-entry"]),
218
- out: getArg(["--out", "-o"]),
219
- failOnWarn: argsOrOpts.includes("--fail-on-warn"),
220
- maxFindings: parseInt(getArg(["--max-findings"]) || "12", 10),
221
- };
222
- }
223
-
224
- // Check for help in object form (from main CLI)
225
- if (argsOrOpts.help) {
226
- printHelp();
227
- return 0;
228
- }
229
-
230
- const {
231
- repoRoot,
232
- fastifyEntry,
233
- out,
234
- failOnWarn = false,
235
- maxFindings = 12
236
- } = argsOrOpts;
237
-
238
- const root = repoRoot || process.cwd();
239
-
240
- const { report, verdict } = await shipCore({ repoRoot: root, fastifyEntry, noWrite: false });
241
-
242
- const md = buildPrMarkdown({ report, maxFindings });
243
-
244
- if (out) {
245
- const outAbs = path.isAbsolute(out) ? out : path.join(root, out);
246
- ensureDir(path.dirname(outAbs));
247
- fs.writeFileSync(outAbs, md, "utf8");
248
- }
249
-
250
- console.log(md);
251
-
252
- process.exitCode = exitCodeForVerdict(verdict, { failOnWarn });
253
- }
254
-
255
- module.exports = { runPR };