@vibecheckai/cli 3.2.4 → 3.2.5

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/vibecheck.js CHANGED
@@ -1123,35 +1123,60 @@ async function main() {
1123
1123
  process.env.VIBECHECK_LOCAL === '1';
1124
1124
 
1125
1125
  // Auth check (unless skipAuth or offline mode)
1126
- if (!cmdDef.skipAuth && !isOffline) {
1126
+ // Only allow login, logout, whoami, and help without auth
1127
+ const authExemptCommands = ['login', 'logout', 'whoami', 'help', '--help', '-h', 'version', '--version'];
1128
+ const needsAuth = !authExemptCommands.includes(cmd) && !cmdDef.skipAuth && !isOffline;
1129
+
1130
+ if (needsAuth) {
1127
1131
  const auth = getAuthModule();
1128
1132
  const { key } = auth.getApiKey();
1129
1133
  authInfo.key = key;
1130
1134
 
1135
+ // If no API key, prompt for login
1136
+ if (!key) {
1137
+ console.log(`\n ${c.red}❌ Authentication Required${c.reset}`);
1138
+ console.log(` Please log in to use vibecheck.\n`);
1139
+ console.log(` ${c.cyan}Options:${c.reset}`);
1140
+ console.log(` 1. Press ${c.yellow}Enter${c.reset} to open browser and sign up`);
1141
+ console.log(` 2. Visit ${c.underline}https://vibecheckai.dev${c.reset} directly`);
1142
+ console.log(` 3. Run ${c.cyan}vibecheck login${c.reset} after getting your API key\n`);
1143
+
1144
+ // Wait for Enter key
1145
+ const readline = getReadline();
1146
+ readline.createInterface({
1147
+ input: process.stdin,
1148
+ output: process.stdout
1149
+ }).question('', async () => {
1150
+ try {
1151
+ const https = getHttps();
1152
+ const url = 'https://vibecheckai.dev';
1153
+ console.log(`\n Opening ${c.underline}${url}${c.reset} in your browser...\n`);
1154
+
1155
+ // Try to open browser
1156
+ const start = process.platform === 'darwin' ? 'open' :
1157
+ process.platform === 'win32' ? 'start' : 'xdg-open';
1158
+ require('child_process').exec(`${start} ${url}`);
1159
+ } catch (e) {
1160
+ console.log(` Could not open browser. Please visit: ${c.underline}https://vibecheckai.dev${c.reset}`);
1161
+ }
1162
+ process.exit(0);
1163
+ });
1164
+
1165
+ // Keep process alive
1166
+ return new Promise(() => {});
1167
+ }
1168
+
1131
1169
  const access = await checkCommandAccess(cmd, cmdArgs, authInfo);
1132
1170
 
1133
1171
  if (!access.allowed) {
1134
1172
  console.log(access.reason);
1135
- process.exit(access.exitCode || 3);
1136
- }
1137
-
1138
- // Downgrade notice
1139
- if (access.downgrade && !config.quiet) {
1140
- const upsell = getUpsell();
1141
- console.log(upsell.formatDowngrade(cmd, {
1142
- currentTier: access.tier,
1143
- effectiveMode: access.downgrade,
1144
- caps: access.caps,
1145
- }));
1146
- }
1147
-
1148
- // Tier badge
1149
- if (!config.quiet && !config.noBanner) {
1150
- if (access.tier === "pro") {
1151
- console.log(`${c.magenta}${sym.arrowRight} PRO${c.reset} ${c.dim}feature${c.reset}`);
1152
- } else if (access.tier === "complete") {
1153
- console.log(`${c.yellow}${sym.arrowRight} COMPLETE${c.reset} ${c.dim}feature${c.reset}`);
1173
+
1174
+ // Show upgrade prompt if tier insufficient
1175
+ if (access.upgradeUrl) {
1176
+ console.log(`\n ${c.cyan}Upgrade:${c.reset} ${access.upgradeUrl}`);
1154
1177
  }
1178
+
1179
+ return 1;
1155
1180
  }
1156
1181
 
1157
1182
  authInfo.access = access;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibecheck-mcp-server",
3
- "version": "3.1.8",
3
+ "version": "3.2.0",
4
4
  "description": "Professional MCP server for vibecheck - Intelligent development environment vibechecks",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -169,8 +169,8 @@ async function loadUserConfig() {
169
169
  * Determine tier from API key
170
170
  * Matches CLI entitlements-v2.js logic
171
171
  */
172
- function getTierFromApiKey(apiKey) {
173
- if (!apiKey) return 'free';
172
+ async function getTierFromApiKey(apiKey) {
173
+ if (!apiKey) return null; // No API key = no access
174
174
 
175
175
  // Check API key prefix patterns (matches CLI)
176
176
  if (apiKey.startsWith('gr_starter_')) return 'starter';
@@ -178,16 +178,43 @@ function getTierFromApiKey(apiKey) {
178
178
  if (apiKey.startsWith('gr_compliance_') || apiKey.startsWith('gr_ent_')) return 'compliance';
179
179
  if (apiKey.startsWith('gr_free_')) return 'free';
180
180
 
181
- // Try to fetch from API (same as CLI)
182
- // For now, default to free - API lookup would happen in production
183
- return 'free'; // default for unknown keys
184
- }
181
+ // Try to validate with API
182
+ try {
183
+ const response = await fetch('https://api.vibecheckai.dev/whoami', {
184
+ headers: {
185
+ 'Authorization': `Bearer ${apiKey}`,
186
+ 'Content-Type': 'application/json',
187
+ },
188
+ });
189
+
190
+ if (!response.ok) {
191
+ return null; // Invalid API key
192
+ }
193
+
194
+ const data = await response.json();
195
+
196
+ // Map API response to tier
197
+ switch (data.plan?.toLowerCase()) {
198
+ case 'starter':
199
+ return 'starter';
200
+ case 'pro':
201
+ return 'pro';
202
+ case 'compliance':
203
+ return 'compliance';
204
+ default:
205
+ return 'free';
206
+ }
207
+ } catch (error) {
208
+ console.error('API validation failed:', error);
209
+ return null; // On error, deny access
210
+ }
211
+ } // default for unknown keys
185
212
 
186
213
  /**
187
214
  * Check if user has access to a specific feature
188
215
  * Matches CLI entitlements-v2.js logic
189
216
  */
190
- export async function checkFeatureAccess(featureName, providedApiKey = null) {
217
+ export async function getFeatureAccessStatus(featureName, providedApiKey = null) {
191
218
  // Try to load user config
192
219
  const userConfig = await loadUserConfig();
193
220
  const apiKey = providedApiKey || userConfig?.apiKey;
@@ -195,13 +222,22 @@ export async function checkFeatureAccess(featureName, providedApiKey = null) {
195
222
  if (!apiKey) {
196
223
  return {
197
224
  hasAccess: false,
198
- tier: 'free',
199
- reason: 'No API key provided. Run: vibecheck auth --key YOUR_API_KEY',
225
+ tier: null,
226
+ reason: 'No API key provided. Please set your API key with `vibecheck login`.',
200
227
  upgradeUrl: 'https://vibecheckai.dev'
201
228
  };
202
229
  }
203
230
 
204
- const currentTier = getTierFromApiKey(apiKey);
231
+ const currentTier = await getTierFromApiKey(apiKey);
232
+
233
+ if (!currentTier) {
234
+ return {
235
+ hasAccess: false,
236
+ tier: null,
237
+ reason: 'Invalid API key. Please check your API key or get a new one at https://vibecheckai.dev',
238
+ upgradeUrl: 'https://vibecheckai.dev'
239
+ };
240
+ }
205
241
  const currentTierConfig = TIERS[currentTier];
206
242
 
207
243
  // Find which tier has this feature
@@ -273,11 +309,30 @@ export function withTierCheck(featureName, handler) {
273
309
  * Check if user has access to a specific MCP tool
274
310
  * MCP tools have specific tier requirements separate from CLI features
275
311
  */
276
- export async function checkMcpToolAccess(toolName, providedApiKey = null) {
312
+ export async function getMcpToolAccess(toolName, providedApiKey = null) {
277
313
  const userConfig = await loadUserConfig();
278
314
  const apiKey = providedApiKey || userConfig?.apiKey;
279
315
 
280
- const currentTier = getTierFromApiKey(apiKey);
316
+ if (!apiKey) {
317
+ return {
318
+ hasAccess: false,
319
+ tier: null,
320
+ reason: 'No API key provided. Please set your API key with `vibecheck login`.',
321
+ upgradeUrl: 'https://vibecheckai.dev'
322
+ };
323
+ }
324
+
325
+ const currentTier = await getTierFromApiKey(apiKey);
326
+
327
+ if (!currentTier) {
328
+ return {
329
+ hasAccess: false,
330
+ tier: null,
331
+ reason: 'Invalid API key. Please check your API key or get a new one at https://vibecheckai.dev',
332
+ upgradeUrl: 'https://vibecheckai.dev'
333
+ };
334
+ }
335
+
281
336
  const currentTierConfig = TIERS[currentTier];
282
337
 
283
338
  // Check if tool is allowed for current tier
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibecheckai/cli",
3
- "version": "3.2.4",
3
+ "version": "3.2.5",
4
4
  "description": "Vibecheck CLI - Ship with confidence. One verdict: SHIP | WARN | BLOCK.",
5
5
  "main": "bin/vibecheck.js",
6
6
  "bin": {