rampup 0.1.8 → 0.1.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/entitlements.js +3 -2
- package/index.js +101 -31
- package/package.json +1 -1
package/entitlements.js
CHANGED
|
@@ -8,12 +8,13 @@ import { getIdToken } from './auth.js';
|
|
|
8
8
|
const ENTITLEMENT_API_URL = process.env.ENTITLEMENT_API_URL ||
|
|
9
9
|
'https://entitlement-service.rian-19c.workers.dev';
|
|
10
10
|
|
|
11
|
-
// Action costs mapping
|
|
11
|
+
// Action costs mapping (must match token_costs in entitlement service)
|
|
12
12
|
const ACTION_COSTS = {
|
|
13
13
|
'learn': { action: 'chat', credits: 1 },
|
|
14
14
|
'ask': { action: 'chat', credits: 1 },
|
|
15
15
|
'guide': { action: 'generate', credits: 2 },
|
|
16
|
-
'voice': { action: '
|
|
16
|
+
'voice': { action: 'voice', credits: 2 }, // Per voice interaction
|
|
17
|
+
'voice_session': { action: 'voice', credits: 2 }, // Session start
|
|
17
18
|
'architect': { action: 'debug', credits: 3 },
|
|
18
19
|
};
|
|
19
20
|
|
package/index.js
CHANGED
|
@@ -739,6 +739,17 @@ program
|
|
|
739
739
|
// Get fresh token after potential login
|
|
740
740
|
const authToken = await getIdToken();
|
|
741
741
|
|
|
742
|
+
// Check entitlements before starting voice session
|
|
743
|
+
const idempotencyKey = `voice-${Date.now()}`;
|
|
744
|
+
const entitlementCheck = await checkAndBurnTokens('voice_session', idempotencyKey);
|
|
745
|
+
if (!entitlementCheck.allowed) {
|
|
746
|
+
console.log(chalk.red(`\n❌ ${entitlementCheck.reason}\n`));
|
|
747
|
+
process.exit(1);
|
|
748
|
+
}
|
|
749
|
+
if (entitlementCheck.balance !== undefined) {
|
|
750
|
+
console.log(chalk.dim(`Credits remaining: ${entitlementCheck.balance}\n`));
|
|
751
|
+
}
|
|
752
|
+
|
|
742
753
|
const RAMP_API_URL = process.env.RAMP_API_URL || 'https://ramp-api-946191982468.us-central1.run.app';
|
|
743
754
|
|
|
744
755
|
// Track usage
|
|
@@ -1375,47 +1386,106 @@ program
|
|
|
1375
1386
|
console.log(banner);
|
|
1376
1387
|
console.log(chalk.bold.blue('⚡ Upgrade Plan\n'));
|
|
1377
1388
|
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1389
|
+
const ENTITLEMENT_API_URL = process.env.ENTITLEMENT_API_URL ||
|
|
1390
|
+
'https://entitlement-service.rian-19c.workers.dev';
|
|
1391
|
+
|
|
1392
|
+
// Check if user is logged in
|
|
1393
|
+
const token = await getIdToken();
|
|
1394
|
+
if (!token) {
|
|
1395
|
+
console.log(chalk.yellow('Please log in first to upgrade your plan.\n'));
|
|
1396
|
+
console.log(chalk.dim('Run: ramp login\n'));
|
|
1397
|
+
return;
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
const spinner = ora('Loading plans...').start();
|
|
1401
|
+
|
|
1381
1402
|
try {
|
|
1382
|
-
|
|
1383
|
-
|
|
1403
|
+
// Get current balance
|
|
1404
|
+
const balance = await getTokenBalance();
|
|
1405
|
+
const currentCredits = balance?.balances?.[0]?.balance || 0;
|
|
1384
1406
|
|
|
1385
|
-
|
|
1386
|
-
|
|
1407
|
+
// Fetch plans from API
|
|
1408
|
+
const plansResponse = await fetch(`${ENTITLEMENT_API_URL}/billing/ramp/plans`);
|
|
1409
|
+
if (!plansResponse.ok) {
|
|
1410
|
+
throw new Error('Failed to fetch plans');
|
|
1411
|
+
}
|
|
1412
|
+
const { plans } = await plansResponse.json();
|
|
1387
1413
|
|
|
1388
|
-
|
|
1414
|
+
spinner.succeed('Plans loaded!\n');
|
|
1389
1415
|
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
console.log(chalk.dim(' • Unlimited text queries'));
|
|
1393
|
-
console.log(chalk.dim(' • 5 team members\n'));
|
|
1416
|
+
// Show current balance
|
|
1417
|
+
console.log(chalk.bold('Current Balance:'), chalk.cyan(`${currentCredits} credits\n`));
|
|
1394
1418
|
|
|
1395
|
-
|
|
1396
|
-
console.log(chalk.dim(' • 500 voice minutes'));
|
|
1397
|
-
console.log(chalk.dim(' • Unlimited everything'));
|
|
1398
|
-
console.log(chalk.dim(' • 25 team members'));
|
|
1399
|
-
console.log(chalk.dim(' • Priority support\n'));
|
|
1419
|
+
console.log(chalk.bold('Available Plans:\n'));
|
|
1400
1420
|
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1421
|
+
// Display plans
|
|
1422
|
+
for (const plan of plans) {
|
|
1423
|
+
const priceStr = plan.price === 0 ? 'Free' : `$${plan.price}/mo`;
|
|
1424
|
+
const label = plan.popular ? `${plan.name} ⭐` : plan.name;
|
|
1425
|
+
console.log(chalk.cyan(` ${label} - ${priceStr}`));
|
|
1426
|
+
for (const feature of plan.features) {
|
|
1427
|
+
console.log(chalk.dim(` • ${feature}`));
|
|
1428
|
+
}
|
|
1429
|
+
console.log();
|
|
1430
|
+
}
|
|
1406
1431
|
|
|
1407
|
-
|
|
1432
|
+
// Get paid plans for selection
|
|
1433
|
+
const paidPlans = plans.filter(p => p.price > 0);
|
|
1408
1434
|
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1435
|
+
const { selectedPlan } = await inquirer.prompt([{
|
|
1436
|
+
type: 'list',
|
|
1437
|
+
name: 'selectedPlan',
|
|
1438
|
+
message: 'Select a plan to upgrade:',
|
|
1439
|
+
choices: [
|
|
1440
|
+
...paidPlans.map(p => ({
|
|
1441
|
+
name: `${p.name} ($${p.price}/mo) - ${p.credits} credits`,
|
|
1442
|
+
value: p.id
|
|
1443
|
+
})),
|
|
1444
|
+
{ name: 'Cancel', value: null }
|
|
1445
|
+
]
|
|
1446
|
+
}]);
|
|
1415
1447
|
|
|
1416
|
-
|
|
1448
|
+
if (!selectedPlan) {
|
|
1449
|
+
console.log(chalk.dim('\nNo plan selected.\n'));
|
|
1450
|
+
return;
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
// Create checkout session
|
|
1454
|
+
const checkoutSpinner = ora('Creating checkout session...').start();
|
|
1455
|
+
|
|
1456
|
+
const checkoutResponse = await fetch(`${ENTITLEMENT_API_URL}/billing/ramp/checkout`, {
|
|
1457
|
+
method: 'POST',
|
|
1458
|
+
headers: {
|
|
1459
|
+
'Authorization': `Bearer ${token}`,
|
|
1460
|
+
'Content-Type': 'application/json'
|
|
1461
|
+
},
|
|
1462
|
+
body: JSON.stringify({
|
|
1463
|
+
plan: selectedPlan,
|
|
1464
|
+
successUrl: 'https://rampup.dev/billing?checkout=success',
|
|
1465
|
+
cancelUrl: 'https://rampup.dev/pricing?checkout=cancelled'
|
|
1466
|
+
})
|
|
1467
|
+
});
|
|
1468
|
+
|
|
1469
|
+
if (!checkoutResponse.ok) {
|
|
1470
|
+
const error = await checkoutResponse.json().catch(() => ({}));
|
|
1471
|
+
throw new Error(error.message || 'Failed to create checkout session');
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
const { url } = await checkoutResponse.json();
|
|
1475
|
+
checkoutSpinner.succeed('Checkout ready!\n');
|
|
1476
|
+
|
|
1477
|
+
console.log(chalk.green('Opening Stripe checkout in your browser...\n'));
|
|
1417
1478
|
const open = (await import('open')).default;
|
|
1418
|
-
await open(
|
|
1479
|
+
await open(url);
|
|
1480
|
+
|
|
1481
|
+
console.log(chalk.dim('If browser doesn\'t open, visit:'));
|
|
1482
|
+
console.log(chalk.cyan(url));
|
|
1483
|
+
console.log();
|
|
1484
|
+
|
|
1485
|
+
} catch (error) {
|
|
1486
|
+
spinner.fail('Failed to load upgrade options');
|
|
1487
|
+
console.error(chalk.red(error.message));
|
|
1488
|
+
console.log(chalk.dim('\nYou can also upgrade at: https://rampup.dev/pricing\n'));
|
|
1419
1489
|
}
|
|
1420
1490
|
});
|
|
1421
1491
|
|