@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
|
-
|
|
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
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
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;
|
package/mcp-server/package.json
CHANGED
package/mcp-server/tier-auth.js
CHANGED
|
@@ -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
|
|
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
|
|
182
|
-
|
|
183
|
-
|
|
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
|
|
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:
|
|
199
|
-
reason: 'No API key provided.
|
|
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
|
|
312
|
+
export async function getMcpToolAccess(toolName, providedApiKey = null) {
|
|
277
313
|
const userConfig = await loadUserConfig();
|
|
278
314
|
const apiKey = providedApiKey || userConfig?.apiKey;
|
|
279
315
|
|
|
280
|
-
|
|
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
|
|
Binary file
|