@vibecheckai/cli 3.0.2 → 3.0.3
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/package.json +9 -1
- package/bin/cli-hygiene.js +0 -241
- package/bin/guardrail.js +0 -834
- package/bin/runners/cli-utils.js +0 -1070
- package/bin/runners/context/ai-task-decomposer.js +0 -337
- package/bin/runners/context/analyzer.js +0 -462
- package/bin/runners/context/api-contracts.js +0 -427
- package/bin/runners/context/context-diff.js +0 -342
- package/bin/runners/context/context-pruner.js +0 -291
- package/bin/runners/context/dependency-graph.js +0 -414
- package/bin/runners/context/generators/claude.js +0 -107
- package/bin/runners/context/generators/codex.js +0 -108
- package/bin/runners/context/generators/copilot.js +0 -119
- package/bin/runners/context/generators/cursor.js +0 -514
- package/bin/runners/context/generators/mcp.js +0 -151
- package/bin/runners/context/generators/windsurf.js +0 -180
- package/bin/runners/context/git-context.js +0 -302
- package/bin/runners/context/index.js +0 -1042
- package/bin/runners/context/insights.js +0 -173
- package/bin/runners/context/mcp-server/generate-rules.js +0 -337
- package/bin/runners/context/mcp-server/index.js +0 -1176
- package/bin/runners/context/mcp-server/package.json +0 -24
- package/bin/runners/context/memory.js +0 -200
- package/bin/runners/context/monorepo.js +0 -215
- package/bin/runners/context/multi-repo-federation.js +0 -404
- package/bin/runners/context/patterns.js +0 -253
- package/bin/runners/context/proof-context.js +0 -972
- package/bin/runners/context/security-scanner.js +0 -303
- package/bin/runners/context/semantic-search.js +0 -350
- package/bin/runners/context/shared.js +0 -264
- package/bin/runners/context/team-conventions.js +0 -310
- package/bin/runners/lib/ai-bridge.js +0 -416
- package/bin/runners/lib/analysis-core.js +0 -271
- package/bin/runners/lib/analyzers.js +0 -541
- package/bin/runners/lib/audit-bridge.js +0 -391
- package/bin/runners/lib/auth-truth.js +0 -193
- package/bin/runners/lib/auth.js +0 -215
- package/bin/runners/lib/backup.js +0 -62
- package/bin/runners/lib/billing.js +0 -107
- package/bin/runners/lib/claims.js +0 -118
- package/bin/runners/lib/cli-ui.js +0 -540
- package/bin/runners/lib/compliance-bridge-new.js +0 -0
- package/bin/runners/lib/compliance-bridge.js +0 -165
- package/bin/runners/lib/contracts/auth-contract.js +0 -194
- package/bin/runners/lib/contracts/env-contract.js +0 -178
- package/bin/runners/lib/contracts/external-contract.js +0 -198
- package/bin/runners/lib/contracts/guard.js +0 -168
- package/bin/runners/lib/contracts/index.js +0 -89
- package/bin/runners/lib/contracts/plan-validator.js +0 -311
- package/bin/runners/lib/contracts/route-contract.js +0 -192
- package/bin/runners/lib/detect.js +0 -89
- package/bin/runners/lib/doctor/autofix.js +0 -254
- package/bin/runners/lib/doctor/index.js +0 -37
- package/bin/runners/lib/doctor/modules/dependencies.js +0 -325
- package/bin/runners/lib/doctor/modules/index.js +0 -46
- package/bin/runners/lib/doctor/modules/network.js +0 -250
- package/bin/runners/lib/doctor/modules/project.js +0 -312
- package/bin/runners/lib/doctor/modules/runtime.js +0 -224
- package/bin/runners/lib/doctor/modules/security.js +0 -348
- package/bin/runners/lib/doctor/modules/system.js +0 -213
- package/bin/runners/lib/doctor/modules/vibecheck.js +0 -394
- package/bin/runners/lib/doctor/reporter.js +0 -262
- package/bin/runners/lib/doctor/service.js +0 -262
- package/bin/runners/lib/doctor/types.js +0 -113
- package/bin/runners/lib/doctor/ui.js +0 -263
- package/bin/runners/lib/doctor-enhanced.js +0 -233
- package/bin/runners/lib/doctor-v2.js +0 -608
- package/bin/runners/lib/enforcement.js +0 -72
package/bin/guardrail.js
DELETED
|
@@ -1,834 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// bin/vibecheck.js
|
|
3
|
-
const readline = require("readline");
|
|
4
|
-
const path = require("path");
|
|
5
|
-
const fs = require("fs");
|
|
6
|
-
const { routeArgv } = require("./_router");
|
|
7
|
-
const { warnDeprecationOnce } = require("./_deprecations");
|
|
8
|
-
const {
|
|
9
|
-
getApiKey,
|
|
10
|
-
checkEntitlement,
|
|
11
|
-
getEntitlements,
|
|
12
|
-
} = require("./runners/lib/auth");
|
|
13
|
-
|
|
14
|
-
// Read version from package.json
|
|
15
|
-
function getVersion() {
|
|
16
|
-
try {
|
|
17
|
-
const pkgPath = path.join(__dirname, "..", "package.json");
|
|
18
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
19
|
-
return pkg.version || "0.0.0";
|
|
20
|
-
} catch {
|
|
21
|
-
return "0.0.0";
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Runners
|
|
26
|
-
const { runScan } = require("./runners/runScan");
|
|
27
|
-
const { runGate } = require("./runners/runGate");
|
|
28
|
-
const { runContext } = require("./runners/runContext");
|
|
29
|
-
const { runDashboard, runDemo } = require("./runners/runDashboard");
|
|
30
|
-
const { runFix } = require("./runners/runFix");
|
|
31
|
-
const { runShip } = require("./runners/runShip");
|
|
32
|
-
const { runLaunch } = require("./runners/runLaunch");
|
|
33
|
-
const { runAutopilot } = require("./runners/runAutopilot");
|
|
34
|
-
const { runProof } = require("./runners/runProof");
|
|
35
|
-
|
|
36
|
-
// Graceful loading for modules that may have syntax issues
|
|
37
|
-
let runReality, runRealitySniff;
|
|
38
|
-
try {
|
|
39
|
-
runReality = require("./runners/runReality").runReality;
|
|
40
|
-
} catch (e) {
|
|
41
|
-
runReality = async () => { console.error("Reality runner unavailable:", e.message); return 1; };
|
|
42
|
-
}
|
|
43
|
-
try {
|
|
44
|
-
runRealitySniff = require("./runners/runRealitySniff").runRealitySniff;
|
|
45
|
-
} catch (e) {
|
|
46
|
-
runRealitySniff = async () => { console.error("RealitySniff runner unavailable:", e.message); return 1; };
|
|
47
|
-
}
|
|
48
|
-
const { runValidate } = require("./runners/runValidate");
|
|
49
|
-
const { runDoctor } = require("./runners/runDoctor");
|
|
50
|
-
const { runInit } = require("./runners/runInit");
|
|
51
|
-
const { runMcp } = require("./runners/runMcp");
|
|
52
|
-
const { runLogin, runLogout, runWhoami } = require("./runners/runAuth");
|
|
53
|
-
const {
|
|
54
|
-
runNaturalLanguage,
|
|
55
|
-
isNaturalLanguageCommand,
|
|
56
|
-
} = require("./runners/runNaturalLanguage");
|
|
57
|
-
const { runAIAgent } = require("./runners/runAIAgent");
|
|
58
|
-
const { runBadge } = require("./runners/runBadge");
|
|
59
|
-
const { runUpgrade } = require("./runners/runUpgrade");
|
|
60
|
-
const { runCertify } = require("./runners/runCertify");
|
|
61
|
-
const { runVerifyAgentOutput } = require("./runners/runVerifyAgentOutput");
|
|
62
|
-
const { runFixPacks } = require("./runners/runFixPacks");
|
|
63
|
-
const { runAudit } = require("./runners/runAudit");
|
|
64
|
-
const { runMdc } = require("./runners/runMdc");
|
|
65
|
-
const { runEnhancedShip } = require("./runners/runEnhancedShip");
|
|
66
|
-
const { runPromptFirewall } = require("./runners/runPromptFirewall");
|
|
67
|
-
|
|
68
|
-
// Route Truth v1 - ctx command
|
|
69
|
-
const { runCtx } = require("./runners/runCtx");
|
|
70
|
-
// Share command
|
|
71
|
-
const { runShare } = require("./runners/runShare");
|
|
72
|
-
// PR command
|
|
73
|
-
const { runPR } = require("./runners/runPR");
|
|
74
|
-
// Init GHA command
|
|
75
|
-
const { runInitGha } = require("./runners/runInitGha");
|
|
76
|
-
// Install command
|
|
77
|
-
const { runInstall } = require("./runners/runInstall");
|
|
78
|
-
// Prove command
|
|
79
|
-
const { runProve } = require("./runners/runProve");
|
|
80
|
-
// Watch command
|
|
81
|
-
const { runWatch } = require("./runners/runWatch");
|
|
82
|
-
// Status command
|
|
83
|
-
const { runStatus } = require("./runners/runStatus");
|
|
84
|
-
// Graph command - Reality Proof Graph
|
|
85
|
-
const { runGraph } = require("./runners/runGraph");
|
|
86
|
-
// Permissions command - AuthZ Matrix & IDOR
|
|
87
|
-
const { runPermissions } = require("./runners/runPermissions");
|
|
88
|
-
// Replay command - Record and replay user sessions
|
|
89
|
-
const { runReplay } = require("./runners/runReplay");
|
|
90
|
-
// Context Contracts commands
|
|
91
|
-
const { runCtxSync } = require("./runners/runCtxSync");
|
|
92
|
-
const { runCtxGuard } = require("./runners/runCtxGuard");
|
|
93
|
-
|
|
94
|
-
// Truth Pack v1 - Core truth system
|
|
95
|
-
let runTruthpack;
|
|
96
|
-
try {
|
|
97
|
-
runTruthpack = require("./runners/runTruthpack").runTruthpack;
|
|
98
|
-
} catch (e) {
|
|
99
|
-
runTruthpack = async () => { console.error("Truthpack runner unavailable:", e.message); return 1; };
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const VERSION = getVersion();
|
|
103
|
-
|
|
104
|
-
// ANSI colors
|
|
105
|
-
const c = {
|
|
106
|
-
reset: "\x1b[0m",
|
|
107
|
-
dim: "\x1b[2m",
|
|
108
|
-
cyan: "\x1b[36m",
|
|
109
|
-
green: "\x1b[32m",
|
|
110
|
-
yellow: "\x1b[33m",
|
|
111
|
-
red: "\x1b[31m",
|
|
112
|
-
blue: "\x1b[34m",
|
|
113
|
-
magenta: "\x1b[35m",
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
// Detect CI/CD environment (non-interactive)
|
|
117
|
-
function isCI() {
|
|
118
|
-
return !!(
|
|
119
|
-
process.env.CI ||
|
|
120
|
-
process.env.CONTINUOUS_INTEGRATION ||
|
|
121
|
-
process.env.RAILWAY_ENVIRONMENT ||
|
|
122
|
-
process.env.VERCEL ||
|
|
123
|
-
process.env.NETLIFY ||
|
|
124
|
-
process.env.GITHUB_ACTIONS ||
|
|
125
|
-
process.env.GITLAB_CI ||
|
|
126
|
-
process.env.CIRCLECI ||
|
|
127
|
-
process.env.TRAVIS ||
|
|
128
|
-
process.env.BUILDKITE ||
|
|
129
|
-
process.env.RENDER ||
|
|
130
|
-
process.env.HEROKU ||
|
|
131
|
-
!process.stdin.isTTY
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// ============================================================================
|
|
136
|
-
// TIER-BASED COMMAND ACCESS
|
|
137
|
-
// ============================================================================
|
|
138
|
-
// FREE ($0) - No API key needed
|
|
139
|
-
const FREE_COMMANDS = [
|
|
140
|
-
"help",
|
|
141
|
-
"version",
|
|
142
|
-
"doctor",
|
|
143
|
-
"init",
|
|
144
|
-
"login",
|
|
145
|
-
"logout",
|
|
146
|
-
"whoami",
|
|
147
|
-
"scan", // Route integrity + security analysis
|
|
148
|
-
"validate", // AI code validation
|
|
149
|
-
"badge", // Generate badges
|
|
150
|
-
"certify", // Certification badges (SEO fuel)
|
|
151
|
-
"context", // AI rules generator
|
|
152
|
-
"dashboard", // Real-time monitoring
|
|
153
|
-
"demo", // Interactive demo
|
|
154
|
-
"upgrade", // Subscription management
|
|
155
|
-
"verify-agent-output", // Verify AI agent output
|
|
156
|
-
"mdc", // MDC documentation generator
|
|
157
|
-
"prompt-firewall", // Prompt firewall (free tier with limited features)
|
|
158
|
-
"firewall", // Alias for prompt-firewall
|
|
159
|
-
"ctx", // Truth Pack generator
|
|
160
|
-
"truthpack", // Alias for ctx
|
|
161
|
-
"replay", // Record and replay user sessions
|
|
162
|
-
"graph", // Reality Proof Graph
|
|
163
|
-
"status", // Quick project status
|
|
164
|
-
"watch", // Continuous dev mode
|
|
165
|
-
"prove", // One command reality proof
|
|
166
|
-
"install", // Zero-friction onboarding
|
|
167
|
-
"pr", // PR comment generator
|
|
168
|
-
"share", // Share bundle generator
|
|
169
|
-
"reality", // Runtime UI verification
|
|
170
|
-
];
|
|
171
|
-
|
|
172
|
-
// STARTER ($19/mo) - Requires API key with starter+ plan
|
|
173
|
-
const STARTER_COMMANDS = {
|
|
174
|
-
ship: "ship:audit", // Plain English audit
|
|
175
|
-
"enhanced-ship": "enhanced-ship:full", // Enhanced ship decision with all features
|
|
176
|
-
gate: "gate:ci", // CI/CD gate
|
|
177
|
-
reality: "reality:basic", // Browser testing
|
|
178
|
-
launch: "launch:checklist", // Pre-launch wizard
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
// PRO ($49/mo) - Requires API key with pro+ plan
|
|
182
|
-
const PRO_COMMANDS = {
|
|
183
|
-
"ai-test": "ai:agent", // AI Agent testing
|
|
184
|
-
ai: "ai:agent",
|
|
185
|
-
agent: "ai:agent",
|
|
186
|
-
// fix: removed - handled specially to allow --plan-only on FREE tier
|
|
187
|
-
autopilot: "autopilot:enable", // Continuous protection
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
// Commands with FREE tier read-only modes
|
|
191
|
-
const TIERED_COMMANDS = {
|
|
192
|
-
fix: {
|
|
193
|
-
freeArgs: ["--plan-only", "--help", "-h"], // Allow these args on FREE
|
|
194
|
-
requiredScope: "fix:apply",
|
|
195
|
-
tier: "pro",
|
|
196
|
-
},
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
// Special: proof command has sub-modes with different tiers
|
|
200
|
-
const PROOF_COMMANDS = {
|
|
201
|
-
mocks: "proof:mocks", // Starter+
|
|
202
|
-
reality: "proof:reality", // Pro+
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
// Commands that always work (utilities)
|
|
206
|
-
const UTILITY_COMMANDS = ["mcp", "rules", "api", "deps", "sbom", "fixpacks"];
|
|
207
|
-
|
|
208
|
-
// Compliance tier commands
|
|
209
|
-
const COMPLIANCE_COMMANDS = {
|
|
210
|
-
audit: "audit:full", // Full audit trail
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
async function prompt(question) {
|
|
214
|
-
const rl = readline.createInterface({
|
|
215
|
-
input: process.stdin,
|
|
216
|
-
output: process.stdout,
|
|
217
|
-
});
|
|
218
|
-
return new Promise((resolve) => {
|
|
219
|
-
rl.question(question, (answer) => {
|
|
220
|
-
rl.close();
|
|
221
|
-
resolve(answer.trim());
|
|
222
|
-
});
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
async function showWelcomeAndPromptLogin() {
|
|
227
|
-
console.log(`
|
|
228
|
-
${c.cyan}╔════════════════════════════════════════════════════════════╗
|
|
229
|
-
║ ${c.reset}🛡️ VIBECHECK${c.cyan} ║
|
|
230
|
-
╚════════════════════════════════════════════════════════════╝${c.reset}
|
|
231
|
-
|
|
232
|
-
${c.dim}Ship with confidence. Catch fake features before your users do.${c.reset}
|
|
233
|
-
|
|
234
|
-
`);
|
|
235
|
-
|
|
236
|
-
const { key, source } = getApiKey();
|
|
237
|
-
|
|
238
|
-
if (!key) {
|
|
239
|
-
// In CI/CD environments, skip interactive prompts
|
|
240
|
-
if (isCI()) {
|
|
241
|
-
console.log(`${c.yellow}⚠ No API key found${c.reset}`);
|
|
242
|
-
console.log(
|
|
243
|
-
`${c.dim}Running in CI mode with FREE tier features.${c.reset}`,
|
|
244
|
-
);
|
|
245
|
-
console.log(
|
|
246
|
-
`${c.dim}Set VIBECHECK_API_KEY env var to unlock more features.${c.reset}\n`,
|
|
247
|
-
);
|
|
248
|
-
return { key: null, entitlements: null };
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
console.log(`${c.yellow}⚠ No API key found${c.reset}`);
|
|
252
|
-
console.log(`
|
|
253
|
-
${c.dim}To unlock all features, you need a vibecheck API key.${c.reset}
|
|
254
|
-
|
|
255
|
-
${c.green}FREE${c.reset} scan, validate, badge, doctor, init
|
|
256
|
-
${c.cyan}STARTER${c.reset} ship, gate, reality, launch, proof mocks ${c.dim}($29/mo)${c.reset}
|
|
257
|
-
${c.magenta}PRO${c.reset} ai-test, fix, autopilot, proof reality ${c.dim}($99/mo)${c.reset}
|
|
258
|
-
|
|
259
|
-
${c.dim}Get your API key at: ${c.cyan}https://vibecheckai.dev/settings/keys${c.reset}
|
|
260
|
-
`);
|
|
261
|
-
|
|
262
|
-
const answer = await prompt(
|
|
263
|
-
`${c.cyan}?${c.reset} Do you have an API key? (y/N) `,
|
|
264
|
-
);
|
|
265
|
-
|
|
266
|
-
if (answer.toLowerCase() === "y") {
|
|
267
|
-
const apiKey = await prompt(`${c.cyan}?${c.reset} Paste your API key: `);
|
|
268
|
-
if (apiKey) {
|
|
269
|
-
const { saveApiKey } = require("./runners/lib/auth");
|
|
270
|
-
console.log(`\n${c.dim}Verifying...${c.reset}`);
|
|
271
|
-
|
|
272
|
-
const entitlements = await getEntitlements(apiKey);
|
|
273
|
-
if (entitlements) {
|
|
274
|
-
saveApiKey(apiKey);
|
|
275
|
-
console.log(
|
|
276
|
-
`\n${c.green}✓${c.reset} Logged in as ${entitlements.user?.name || "User"}`,
|
|
277
|
-
);
|
|
278
|
-
console.log(
|
|
279
|
-
`${c.dim}Plan: ${entitlements.plan?.toUpperCase() || "FREE"}${c.reset}\n`,
|
|
280
|
-
);
|
|
281
|
-
return { key: apiKey, entitlements };
|
|
282
|
-
} else {
|
|
283
|
-
console.log(`\n${c.red}✗${c.reset} Invalid API key\n`);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
console.log(`
|
|
289
|
-
${c.dim}Continuing in FREE mode. Some features will be limited.${c.reset}
|
|
290
|
-
${c.dim}Run ${c.cyan}vibecheck login${c.dim} anytime to upgrade.${c.reset}
|
|
291
|
-
`);
|
|
292
|
-
return { key: null, entitlements: null };
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
// User has API key, get entitlements
|
|
296
|
-
const entitlements = await getEntitlements(key);
|
|
297
|
-
return { key, entitlements };
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
async function checkCommandAccess(cmd, entitlements, args = []) {
|
|
301
|
-
// Free commands always work (no API key needed)
|
|
302
|
-
if (FREE_COMMANDS.includes(cmd)) {
|
|
303
|
-
return { allowed: true, tier: "free" };
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
// Utility commands always work
|
|
307
|
-
if (UTILITY_COMMANDS.includes(cmd)) {
|
|
308
|
-
return { allowed: true, tier: "utility" };
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
// Tiered commands with FREE read-only modes
|
|
312
|
-
if (TIERED_COMMANDS[cmd]) {
|
|
313
|
-
const config = TIERED_COMMANDS[cmd];
|
|
314
|
-
// Check if using a FREE tier argument
|
|
315
|
-
const hasFreeArg = args.some(arg => config.freeArgs.includes(arg));
|
|
316
|
-
// Also allow if no fix pack specified (shows help)
|
|
317
|
-
const hasNoFixPack = cmd === "fix" && !args.some(arg => !arg.startsWith("-"));
|
|
318
|
-
|
|
319
|
-
if (hasFreeArg || hasNoFixPack) {
|
|
320
|
-
return { allowed: true, tier: "free" };
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
// Requires paid tier
|
|
324
|
-
if (!entitlements) {
|
|
325
|
-
return {
|
|
326
|
-
allowed: false,
|
|
327
|
-
reason: `${c.yellow}${cmd}${c.reset} requires a ${c.magenta}PRO${c.reset} plan.\n\n Run ${c.cyan}vibecheck login${c.reset} to authenticate.\n Get your API key at: ${c.cyan}https://vibecheckai.dev/settings/keys${c.reset}`,
|
|
328
|
-
};
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
if (
|
|
332
|
-
entitlements.scopes?.includes(config.requiredScope) ||
|
|
333
|
-
entitlements.scopes?.includes("*")
|
|
334
|
-
) {
|
|
335
|
-
return { allowed: true, tier: config.tier };
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
return {
|
|
339
|
-
allowed: false,
|
|
340
|
-
reason: `Your ${c.yellow}${entitlements.plan?.toUpperCase()}${c.reset} plan doesn't include this feature.\n\n Required: ${config.requiredScope}\n Upgrade to ${c.magenta}PRO${c.reset} at: ${c.cyan}https://vibecheckai.dev/pricing${c.reset}`,
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
// Special handling for proof command (has sub-modes with different tiers)
|
|
345
|
-
if (cmd === "proof") {
|
|
346
|
-
const subMode = args[0]; // mocks or reality
|
|
347
|
-
if (subMode === "mocks") {
|
|
348
|
-
// Starter+ required
|
|
349
|
-
if (!entitlements) {
|
|
350
|
-
return {
|
|
351
|
-
allowed: false,
|
|
352
|
-
reason: `${c.yellow}proof mocks${c.reset} requires a ${c.cyan}STARTER${c.reset} plan or higher.\n\n Run ${c.cyan}vibecheck login${c.reset} to authenticate.\n Get your API key at: ${c.cyan}https://vibecheckai.dev/settings/keys${c.reset}`,
|
|
353
|
-
};
|
|
354
|
-
}
|
|
355
|
-
if (
|
|
356
|
-
entitlements.scopes?.includes("proof:mocks") ||
|
|
357
|
-
entitlements.scopes?.includes("*")
|
|
358
|
-
) {
|
|
359
|
-
return { allowed: true, tier: "starter" };
|
|
360
|
-
}
|
|
361
|
-
return {
|
|
362
|
-
allowed: false,
|
|
363
|
-
reason: `Your ${c.yellow}${entitlements.plan?.toUpperCase()}${c.reset} plan doesn't include mock detection.\n\n Upgrade to ${c.cyan}STARTER${c.reset} at: ${c.cyan}https://vibecheckai.dev/pricing${c.reset}`,
|
|
364
|
-
};
|
|
365
|
-
} else if (subMode === "reality") {
|
|
366
|
-
// Pro+ required
|
|
367
|
-
if (!entitlements) {
|
|
368
|
-
return {
|
|
369
|
-
allowed: false,
|
|
370
|
-
reason: `${c.yellow}proof reality${c.reset} requires a ${c.magenta}PRO${c.reset} plan.\n\n Run ${c.cyan}vibecheck login${c.reset} to authenticate.\n Get your API key at: ${c.cyan}https://vibecheckai.dev/settings/keys${c.reset}`,
|
|
371
|
-
};
|
|
372
|
-
}
|
|
373
|
-
if (
|
|
374
|
-
entitlements.scopes?.includes("proof:reality") ||
|
|
375
|
-
entitlements.scopes?.includes("*")
|
|
376
|
-
) {
|
|
377
|
-
return { allowed: true, tier: "pro" };
|
|
378
|
-
}
|
|
379
|
-
return {
|
|
380
|
-
allowed: false,
|
|
381
|
-
reason: `Your ${c.yellow}${entitlements.plan?.toUpperCase()}${c.reset} plan doesn't include runtime verification.\n\n Upgrade to ${c.magenta}PRO${c.reset} at: ${c.cyan}https://vibecheckai.dev/pricing${c.reset}`,
|
|
382
|
-
};
|
|
383
|
-
}
|
|
384
|
-
// No submode - show help
|
|
385
|
-
return { allowed: true };
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
// STARTER tier commands
|
|
389
|
-
if (STARTER_COMMANDS[cmd]) {
|
|
390
|
-
const requiredScope = STARTER_COMMANDS[cmd];
|
|
391
|
-
|
|
392
|
-
if (!entitlements) {
|
|
393
|
-
return {
|
|
394
|
-
allowed: false,
|
|
395
|
-
reason: `${c.yellow}${cmd}${c.reset} requires a ${c.cyan}STARTER${c.reset} plan or higher.\n\n Run ${c.cyan}vibecheck login${c.reset} to authenticate.\n Get your API key at: ${c.cyan}https://vibecheckai.dev/settings/keys${c.reset}`,
|
|
396
|
-
};
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
if (
|
|
400
|
-
entitlements.scopes?.includes(requiredScope) ||
|
|
401
|
-
entitlements.scopes?.includes("*")
|
|
402
|
-
) {
|
|
403
|
-
return { allowed: true, tier: "starter" };
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
return {
|
|
407
|
-
allowed: false,
|
|
408
|
-
reason: `Your ${c.yellow}${entitlements.plan?.toUpperCase()}${c.reset} plan doesn't include this feature.\n\n Required: ${requiredScope}\n Upgrade to ${c.cyan}STARTER${c.reset} at: ${c.cyan}https://vibecheckai.dev/pricing${c.reset}`,
|
|
409
|
-
};
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
// PRO tier commands
|
|
413
|
-
if (PRO_COMMANDS[cmd]) {
|
|
414
|
-
const requiredScope = PRO_COMMANDS[cmd];
|
|
415
|
-
|
|
416
|
-
if (!entitlements) {
|
|
417
|
-
return {
|
|
418
|
-
allowed: false,
|
|
419
|
-
reason: `${c.yellow}${cmd}${c.reset} requires a ${c.magenta}PRO${c.reset} plan.\n\n Run ${c.cyan}vibecheck login${c.reset} to authenticate.\n Get your API key at: ${c.cyan}https://vibecheckai.dev/settings/keys${c.reset}`,
|
|
420
|
-
};
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
if (
|
|
424
|
-
entitlements.scopes?.includes(requiredScope) ||
|
|
425
|
-
entitlements.scopes?.includes("*")
|
|
426
|
-
) {
|
|
427
|
-
return { allowed: true, tier: "pro" };
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
return {
|
|
431
|
-
allowed: false,
|
|
432
|
-
reason: `Your ${c.yellow}${entitlements.plan?.toUpperCase()}${c.reset} plan doesn't include this feature.\n\n Required: ${requiredScope}\n Upgrade to ${c.magenta}PRO${c.reset} at: ${c.cyan}https://vibecheckai.dev/pricing${c.reset}`,
|
|
433
|
-
};
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
return { allowed: true };
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
function printHelp() {
|
|
440
|
-
console.log(
|
|
441
|
-
`
|
|
442
|
-
${c.cyan}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${c.reset}
|
|
443
|
-
${c.cyan} VIBECHECK${c.reset} - Ship with confidence
|
|
444
|
-
${c.cyan}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${c.reset}
|
|
445
|
-
|
|
446
|
-
${c.green}🚀 QUICK START${c.reset}
|
|
447
|
-
|
|
448
|
-
${c.cyan}ship${c.reset} "Is my app ready?" - Plain English, traffic light score
|
|
449
|
-
${c.cyan}ship --fix${c.reset} Same + auto-fix problems
|
|
450
|
-
|
|
451
|
-
${c.yellow}🧪 TESTING${c.reset} (each does something different!)
|
|
452
|
-
|
|
453
|
-
${c.cyan}scan${c.reset} ${c.dim}Route Integrity${c.reset} - dead links, orphans, coverage, security 🗺️
|
|
454
|
-
${c.cyan}scan --truth${c.reset} ${c.dim}+ Build manifest${c.reset} verification (CI/ship ready)
|
|
455
|
-
${c.cyan}scan --reality${c.reset} ${c.dim}+ Playwright${c.reset} runtime proof (best-in-class)
|
|
456
|
-
${c.cyan}reality${c.reset} ${c.dim}Browser testing${c.reset} - clicks buttons, fills forms, finds broken UI
|
|
457
|
-
${c.cyan}ai-test${c.reset} ${c.dim}AI Agent${c.reset} - autonomous testing + generates fix prompts 🤖
|
|
458
|
-
|
|
459
|
-
${c.magenta}🚦 CI/CD & GATES${c.reset}
|
|
460
|
-
|
|
461
|
-
${c.cyan}gate${c.reset} Block bad deploys - pass/fail for CI pipelines
|
|
462
|
-
${c.cyan}proof mocks${c.reset} Block mock/demo code from reaching production
|
|
463
|
-
${c.cyan}proof reality${c.reset} Runtime GO/NO-GO verification with Playwright
|
|
464
|
-
|
|
465
|
-
${c.blue}🔧 FIX & AUTOMATE${c.reset}
|
|
466
|
-
|
|
467
|
-
${c.cyan}fix${c.reset} Auto-fix detected issues (--plan first, then --apply)
|
|
468
|
-
${c.cyan}autopilot${c.reset} Continuous protection - weekly reports, auto-PRs
|
|
469
|
-
${c.cyan}badge${c.reset} Generate Ship Badge for your README/PR
|
|
470
|
-
${c.cyan}certify${c.reset} Generate vibecheck Certified badge with verification link
|
|
471
|
-
|
|
472
|
-
${c.dim}📦 TRUTH SYSTEM${c.reset}
|
|
473
|
-
|
|
474
|
-
${c.cyan}ctx${c.reset} Generate Truth Pack - ground truth for AI agents
|
|
475
|
-
${c.cyan}ctx --snapshot${c.reset} Save snapshot to .vibecheck/truth/snapshots/
|
|
476
|
-
${c.cyan}graph${c.reset} Build Reality Proof Graph - end-to-end causal chains
|
|
477
|
-
|
|
478
|
-
${c.dim}📦 EXTRAS${c.reset}
|
|
479
|
-
|
|
480
|
-
${c.cyan}audit${c.reset} View/export audit trail (Compliance+ tier)
|
|
481
|
-
${c.cyan}context${c.reset} Generate AI rules files (.cursorrules, .windsurf/rules, etc.)
|
|
482
|
-
${c.cyan}dashboard${c.reset} Real-time monitoring dashboard with live metrics
|
|
483
|
-
${c.cyan}demo${c.reset} Interactive terminal features showcase
|
|
484
|
-
${c.cyan}launch${c.reset} Pre-launch checklist wizard
|
|
485
|
-
${c.cyan}validate${c.reset} Check AI-generated code for hallucinations
|
|
486
|
-
${c.cyan}init${c.reset} Set up vibecheck in your project
|
|
487
|
-
${c.cyan}doctor${c.reset} Debug environment issues
|
|
488
|
-
${c.cyan}mcp${c.reset} Start MCP server for AI editors
|
|
489
|
-
|
|
490
|
-
${c.dim}🔑 ACCOUNT${c.reset}
|
|
491
|
-
|
|
492
|
-
${c.cyan}login${c.reset} Sign in with API key
|
|
493
|
-
${c.cyan}logout${c.reset} Sign out
|
|
494
|
-
${c.cyan}whoami${c.reset} Show current user & plan
|
|
495
|
-
${c.cyan}upgrade${c.reset} Manage subscription & view usage
|
|
496
|
-
|
|
497
|
-
${c.cyan}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${c.reset}
|
|
498
|
-
|
|
499
|
-
${c.green}Examples:${c.reset}
|
|
500
|
-
|
|
501
|
-
vibecheck ship ${c.dim}# Quick health check${c.reset}
|
|
502
|
-
vibecheck scan ${c.dim}# Route integrity + security analysis${c.reset}
|
|
503
|
-
vibecheck scan --truth ${c.dim}# + Build manifest verification${c.reset}
|
|
504
|
-
vibecheck scan --reality --url http://localhost:3000 ${c.dim}# Full proof${c.reset}
|
|
505
|
-
vibecheck reality --url https://... ${c.dim}# Test live app${c.reset}
|
|
506
|
-
vibecheck ai-test --url https://... ${c.dim}# AI explores your app${c.reset}
|
|
507
|
-
vibecheck gate ${c.dim}# Block bad deploy in CI${c.reset}
|
|
508
|
-
vibecheck badge ${c.dim}# Generate ship badge${c.reset}
|
|
509
|
-
|
|
510
|
-
${c.dim}Run 'vibecheck <command> --help' for details.${c.reset}
|
|
511
|
-
`.trim(),
|
|
512
|
-
);
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
(async function main() {
|
|
516
|
-
const rawArgs = process.argv.slice(2);
|
|
517
|
-
|
|
518
|
-
// Check if the first argument looks like a natural language command
|
|
519
|
-
// Natural language commands are typically quoted strings or multi-word phrases
|
|
520
|
-
const firstArg = rawArgs[0];
|
|
521
|
-
if (firstArg && isNaturalLanguageCommand(firstArg)) {
|
|
522
|
-
// Join all args as the natural language input
|
|
523
|
-
const nlInput = rawArgs.join(" ");
|
|
524
|
-
const exitCode = await runNaturalLanguage(nlInput);
|
|
525
|
-
process.exit(exitCode);
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
const { legacyFrom, routed } = routeArgv(process.argv);
|
|
529
|
-
|
|
530
|
-
const cmd = routed[0];
|
|
531
|
-
const args = routed.slice(1);
|
|
532
|
-
|
|
533
|
-
// Commands that skip auth check entirely
|
|
534
|
-
const skipAuthCommands = [
|
|
535
|
-
"help",
|
|
536
|
-
"-h",
|
|
537
|
-
"--help",
|
|
538
|
-
"version",
|
|
539
|
-
"login",
|
|
540
|
-
"logout",
|
|
541
|
-
"whoami",
|
|
542
|
-
"doctor",
|
|
543
|
-
];
|
|
544
|
-
|
|
545
|
-
if (!cmd || cmd === "-h" || cmd === "--help" || cmd === "help") {
|
|
546
|
-
printHelp();
|
|
547
|
-
process.exit(0);
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
// Check for first run (no API key) - only for non-skip commands
|
|
551
|
-
let authInfo = { key: null, entitlements: null };
|
|
552
|
-
|
|
553
|
-
if (!skipAuthCommands.includes(cmd)) {
|
|
554
|
-
// Check if this is a free command or utility - if so, skip entitlement checks
|
|
555
|
-
const isFreeCommand = FREE_COMMANDS.includes(cmd) || UTILITY_COMMANDS.includes(cmd);
|
|
556
|
-
const isKnownCommand = isFreeCommand ||
|
|
557
|
-
STARTER_COMMANDS[cmd] ||
|
|
558
|
-
PRO_COMMANDS[cmd] ||
|
|
559
|
-
TIERED_COMMANDS[cmd] ||
|
|
560
|
-
PROOF_COMMANDS[cmd] ||
|
|
561
|
-
COMPLIANCE_COMMANDS[cmd];
|
|
562
|
-
|
|
563
|
-
// For unknown commands, skip auth and let them fail with "Unknown command" message
|
|
564
|
-
if (!isKnownCommand) {
|
|
565
|
-
// Skip authentication for unknown commands - they'll show help/error message
|
|
566
|
-
authInfo = { key: null, entitlements: null };
|
|
567
|
-
} else {
|
|
568
|
-
const { key } = getApiKey();
|
|
569
|
-
|
|
570
|
-
// First run without API key - show welcome and prompt
|
|
571
|
-
if (!key && !process.env.VIBECHECK_SKIP_AUTH) {
|
|
572
|
-
authInfo = await showWelcomeAndPromptLogin();
|
|
573
|
-
} else if (key && !isFreeCommand) {
|
|
574
|
-
// Has API key and command requires auth - get entitlements silently
|
|
575
|
-
// For free commands, we don't need to check entitlements
|
|
576
|
-
try {
|
|
577
|
-
const entitlements = await getEntitlements(key);
|
|
578
|
-
authInfo = { key, entitlements };
|
|
579
|
-
} catch (error) {
|
|
580
|
-
// If API is unavailable, allow free commands to proceed
|
|
581
|
-
// Paid commands will be blocked in checkCommandAccess
|
|
582
|
-
if (isFreeCommand) {
|
|
583
|
-
authInfo = { key, entitlements: null };
|
|
584
|
-
} else {
|
|
585
|
-
throw error;
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
} else if (key && isFreeCommand) {
|
|
589
|
-
// Free command with key - no need to fetch entitlements
|
|
590
|
-
authInfo = { key, entitlements: null };
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
// Check if user has access to this command (only for known commands)
|
|
595
|
-
if (isKnownCommand) {
|
|
596
|
-
const access = await checkCommandAccess(cmd, authInfo.entitlements, args);
|
|
597
|
-
|
|
598
|
-
if (!access.allowed) {
|
|
599
|
-
console.log(`\n${c.red}✗ Access Denied${c.reset}\n`);
|
|
600
|
-
console.log(access.reason);
|
|
601
|
-
console.log("");
|
|
602
|
-
process.exit(1);
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
// Show tier info for paid features
|
|
606
|
-
if (access.tier === "starter") {
|
|
607
|
-
console.log(`${c.cyan}▸ STARTER${c.reset} ${c.dim}feature${c.reset}\n`);
|
|
608
|
-
} else if (access.tier === "pro") {
|
|
609
|
-
console.log(`${c.magenta}▸ PRO${c.reset} ${c.dim}feature${c.reset}\n`);
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
// Deprecation suggestions
|
|
615
|
-
if (legacyFrom) {
|
|
616
|
-
const suggestion = routed.slice(0, 2).join(" ");
|
|
617
|
-
warnDeprecationOnce(legacyFrom, suggestion, VERSION);
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
try {
|
|
621
|
-
let exitCode = 0;
|
|
622
|
-
switch (cmd) {
|
|
623
|
-
case "scan":
|
|
624
|
-
exitCode = await runScan(args);
|
|
625
|
-
break;
|
|
626
|
-
case "gate":
|
|
627
|
-
exitCode = await runGate(args);
|
|
628
|
-
break;
|
|
629
|
-
case "ship":
|
|
630
|
-
exitCode = await runShip(args);
|
|
631
|
-
break;
|
|
632
|
-
case "enhanced-ship":
|
|
633
|
-
exitCode = await runEnhancedShip(args);
|
|
634
|
-
break;
|
|
635
|
-
case "prompt-firewall":
|
|
636
|
-
case "firewall":
|
|
637
|
-
exitCode = await runPromptFirewall(args);
|
|
638
|
-
break;
|
|
639
|
-
case "launch":
|
|
640
|
-
exitCode = await runLaunch(args);
|
|
641
|
-
break;
|
|
642
|
-
case "autopilot":
|
|
643
|
-
exitCode = await runAutopilot(args);
|
|
644
|
-
break;
|
|
645
|
-
case "fix":
|
|
646
|
-
exitCode = await runFix(args);
|
|
647
|
-
break;
|
|
648
|
-
case "share":
|
|
649
|
-
exitCode = await runShare({
|
|
650
|
-
repoRoot: process.cwd(),
|
|
651
|
-
missionDir: args.find((a, i) => args[i-1] === '--mission-dir'),
|
|
652
|
-
outputDir: args.find((a, i) => args[i-1] === '--output-dir'),
|
|
653
|
-
prComment: args.includes('--pr-comment')
|
|
654
|
-
});
|
|
655
|
-
break;
|
|
656
|
-
case "pr":
|
|
657
|
-
exitCode = await runPR({
|
|
658
|
-
repoRoot: process.cwd(),
|
|
659
|
-
fastifyEntry: args.find((a, i) => args[i-1] === '--fastify-entry'),
|
|
660
|
-
out: args.find((a, i) => args[i-1] === '--out'),
|
|
661
|
-
failOnWarn: args.includes('--fail-on-warn'),
|
|
662
|
-
maxFindings: Number(args.find((a, i) => args[i-1] === '--max-findings')) || 12
|
|
663
|
-
});
|
|
664
|
-
break;
|
|
665
|
-
case "install":
|
|
666
|
-
exitCode = await runInstall({ repoRoot: process.cwd() });
|
|
667
|
-
break;
|
|
668
|
-
case "prove":
|
|
669
|
-
exitCode = await runProve({
|
|
670
|
-
repoRoot: process.cwd(),
|
|
671
|
-
url: args.find((a, i) => args[i-1] === '--url' || args[i-1] === '-u'),
|
|
672
|
-
auth: args.find((a, i) => args[i-1] === '--auth'),
|
|
673
|
-
storageState: args.find((a, i) => args[i-1] === '--storage-state'),
|
|
674
|
-
fastifyEntry: args.find((a, i) => args[i-1] === '--fastify-entry'),
|
|
675
|
-
maxFixRounds: Number(args.find((a, i) => args[i-1] === '--max-fix-rounds')) || 3,
|
|
676
|
-
maxMissions: Number(args.find((a, i) => args[i-1] === '--max-missions')) || 8,
|
|
677
|
-
maxSteps: Number(args.find((a, i) => args[i-1] === '--max-steps')) || 10,
|
|
678
|
-
skipReality: args.includes('--skip-reality'),
|
|
679
|
-
skipFix: args.includes('--skip-fix'),
|
|
680
|
-
headed: args.includes('--headed'),
|
|
681
|
-
danger: args.includes('--danger'),
|
|
682
|
-
maxPages: Number(args.find((a, i) => args[i-1] === '--max-pages')) || 18,
|
|
683
|
-
maxDepth: Number(args.find((a, i) => args[i-1] === '--max-depth')) || 2,
|
|
684
|
-
timeoutMs: Number(args.find((a, i) => args[i-1] === '--timeout-ms')) || 15000
|
|
685
|
-
});
|
|
686
|
-
break;
|
|
687
|
-
case "watch":
|
|
688
|
-
exitCode = await runWatch({
|
|
689
|
-
repoRoot: process.cwd(),
|
|
690
|
-
fastifyEntry: args.find((a, i) => args[i-1] === '--fastify-entry'),
|
|
691
|
-
debounceMs: Number(args.find((a, i) => args[i-1] === '--debounce')) || 500,
|
|
692
|
-
clearScreen: !args.includes('--no-clear')
|
|
693
|
-
});
|
|
694
|
-
break;
|
|
695
|
-
case "status":
|
|
696
|
-
exitCode = await runStatus({
|
|
697
|
-
repoRoot: process.cwd(),
|
|
698
|
-
json: args.includes('--json')
|
|
699
|
-
});
|
|
700
|
-
break;
|
|
701
|
-
case "proof":
|
|
702
|
-
exitCode = await runProof(args);
|
|
703
|
-
break;
|
|
704
|
-
case "reality":
|
|
705
|
-
exitCode = await runReality({
|
|
706
|
-
repoRoot: process.cwd(),
|
|
707
|
-
url: args.find((a, i) => args[i-1] === '--url' || args[i-1] === '-u'),
|
|
708
|
-
auth: args.find((a, i) => args[i-1] === '--auth'),
|
|
709
|
-
storageState: args.find((a, i) => args[i-1] === '--storage-state'),
|
|
710
|
-
saveStorageState: args.find((a, i) => args[i-1] === '--save-storage-state'),
|
|
711
|
-
truthpack: args.find((a, i) => args[i-1] === '--truthpack'),
|
|
712
|
-
verifyAuth: args.includes('--verify-auth'),
|
|
713
|
-
headed: args.includes('--headed'),
|
|
714
|
-
maxPages: Number(args.find((a, i) => args[i-1] === '--max-pages')) || 18,
|
|
715
|
-
maxDepth: Number(args.find((a, i) => args[i-1] === '--max-depth')) || 2,
|
|
716
|
-
danger: args.includes('--danger'),
|
|
717
|
-
timeoutMs: Number(args.find((a, i) => args[i-1] === '--timeout-ms')) || 15000
|
|
718
|
-
});
|
|
719
|
-
break;
|
|
720
|
-
case "reality-sniff":
|
|
721
|
-
case "sniff":
|
|
722
|
-
exitCode = await runRealitySniff(args);
|
|
723
|
-
break;
|
|
724
|
-
case "ai-test":
|
|
725
|
-
case "ai":
|
|
726
|
-
case "agent":
|
|
727
|
-
exitCode = await runAIAgent(args);
|
|
728
|
-
break;
|
|
729
|
-
case "validate":
|
|
730
|
-
exitCode = await runValidate(args);
|
|
731
|
-
break;
|
|
732
|
-
case "doctor":
|
|
733
|
-
exitCode = runDoctor(args);
|
|
734
|
-
break;
|
|
735
|
-
case "init":
|
|
736
|
-
// Enterprise init handles all flags including --gha, --gitlab, --compliance, etc.
|
|
737
|
-
exitCode = await runInit(args);
|
|
738
|
-
break;
|
|
739
|
-
case "mcp":
|
|
740
|
-
exitCode = runMcp(args);
|
|
741
|
-
break;
|
|
742
|
-
case "login":
|
|
743
|
-
exitCode = await runLogin(args);
|
|
744
|
-
break;
|
|
745
|
-
case "logout":
|
|
746
|
-
exitCode = await runLogout(args);
|
|
747
|
-
break;
|
|
748
|
-
case "whoami":
|
|
749
|
-
exitCode = await runWhoami(args);
|
|
750
|
-
break;
|
|
751
|
-
case "badge":
|
|
752
|
-
exitCode = await runBadge(args);
|
|
753
|
-
break;
|
|
754
|
-
case "context":
|
|
755
|
-
case "rules":
|
|
756
|
-
exitCode = await runContext(args);
|
|
757
|
-
break;
|
|
758
|
-
case "dashboard":
|
|
759
|
-
exitCode = await runDashboard(args);
|
|
760
|
-
break;
|
|
761
|
-
case "demo":
|
|
762
|
-
exitCode = await runDemo(args);
|
|
763
|
-
break;
|
|
764
|
-
case "upgrade":
|
|
765
|
-
exitCode = await runUpgrade(args);
|
|
766
|
-
break;
|
|
767
|
-
case "certify":
|
|
768
|
-
exitCode = await runCertify(args, process.cwd());
|
|
769
|
-
break;
|
|
770
|
-
case "verify-agent-output":
|
|
771
|
-
exitCode = await runVerifyAgentOutput(args);
|
|
772
|
-
break;
|
|
773
|
-
case "fixpacks":
|
|
774
|
-
exitCode = await runFixPacks(args);
|
|
775
|
-
break;
|
|
776
|
-
case "audit":
|
|
777
|
-
exitCode = await runAudit(args);
|
|
778
|
-
break;
|
|
779
|
-
case "mdc":
|
|
780
|
-
exitCode = await runMdc(args);
|
|
781
|
-
break;
|
|
782
|
-
case "graph":
|
|
783
|
-
exitCode = await runGraph(args);
|
|
784
|
-
break;
|
|
785
|
-
case "permissions":
|
|
786
|
-
case "authz":
|
|
787
|
-
exitCode = await runPermissions(args);
|
|
788
|
-
break;
|
|
789
|
-
case "ctx":
|
|
790
|
-
case "truthpack":
|
|
791
|
-
// Check for subcommands
|
|
792
|
-
if (args[0] === "sync") {
|
|
793
|
-
exitCode = await runCtxSync({
|
|
794
|
-
repoRoot: process.cwd(),
|
|
795
|
-
fastifyEntry: args.find((a, i) => args[i-1] === '--fastify-entry')
|
|
796
|
-
});
|
|
797
|
-
break;
|
|
798
|
-
}
|
|
799
|
-
if (args[0] === "guard") {
|
|
800
|
-
exitCode = await runCtxGuard.main(args.slice(1));
|
|
801
|
-
break;
|
|
802
|
-
}
|
|
803
|
-
// Parse args for ctx command - use Route Truth v1
|
|
804
|
-
const fastifyEntryIdx = args.indexOf('--fastify-entry');
|
|
805
|
-
const fastifyEntry = fastifyEntryIdx !== -1 ? args[fastifyEntryIdx + 1] : undefined;
|
|
806
|
-
await runCtx({
|
|
807
|
-
repoRoot: process.cwd(),
|
|
808
|
-
fastifyEntry,
|
|
809
|
-
print: args.includes('--print'),
|
|
810
|
-
});
|
|
811
|
-
exitCode = 0;
|
|
812
|
-
break;
|
|
813
|
-
case "version":
|
|
814
|
-
console.log(`vibecheck v${VERSION}`);
|
|
815
|
-
break;
|
|
816
|
-
default:
|
|
817
|
-
// Try natural language parsing as fallback for unknown commands
|
|
818
|
-
const nlInput = [cmd, ...args].join(" ");
|
|
819
|
-
if (isNaturalLanguageCommand(nlInput)) {
|
|
820
|
-
exitCode = await runNaturalLanguage(nlInput);
|
|
821
|
-
} else {
|
|
822
|
-
process.stderr.write(`Unknown command: ${cmd}\n\n`);
|
|
823
|
-
printHelp();
|
|
824
|
-
exitCode = 1;
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
process.exit(exitCode);
|
|
828
|
-
} catch (err) {
|
|
829
|
-
process.stderr.write(
|
|
830
|
-
err && err.stack ? err.stack + "\n" : String(err) + "\n",
|
|
831
|
-
);
|
|
832
|
-
process.exit(1);
|
|
833
|
-
}
|
|
834
|
-
})();
|