@nolimitcli/cli 2.1.1 → 2.1.2
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/dist/index.js +106 -115
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3,9 +3,9 @@ import Conf from 'conf';
|
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import ora from 'ora';
|
|
5
5
|
import open from 'open';
|
|
6
|
-
import
|
|
6
|
+
import repl from 'repl';
|
|
7
7
|
const API_BASE = 'https://nolimit-production-2589.up.railway.app';
|
|
8
|
-
const VERSION = '2.1.
|
|
8
|
+
const VERSION = '2.1.2';
|
|
9
9
|
// Persistent config storage
|
|
10
10
|
const config = new Conf({
|
|
11
11
|
projectName: 'nolimit',
|
|
@@ -14,6 +14,9 @@ const config = new Conf({
|
|
|
14
14
|
apiKey: { type: 'string' },
|
|
15
15
|
},
|
|
16
16
|
});
|
|
17
|
+
// State
|
|
18
|
+
let apiKey;
|
|
19
|
+
let balance = 0;
|
|
17
20
|
// ============================================================================
|
|
18
21
|
// HELPERS
|
|
19
22
|
// ============================================================================
|
|
@@ -22,7 +25,9 @@ function formatTokens(tokens) {
|
|
|
22
25
|
return (tokens / 1000).toFixed(1).replace(/\.0$/, '') + 'K';
|
|
23
26
|
return tokens.toString();
|
|
24
27
|
}
|
|
25
|
-
async function getBalance(
|
|
28
|
+
async function getBalance() {
|
|
29
|
+
if (!apiKey)
|
|
30
|
+
return null;
|
|
26
31
|
try {
|
|
27
32
|
const response = await fetch(`${API_BASE}/api/credits/balance`, {
|
|
28
33
|
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
@@ -56,9 +61,11 @@ async function authenticate() {
|
|
|
56
61
|
return null;
|
|
57
62
|
}
|
|
58
63
|
}
|
|
59
|
-
async function watchAd(
|
|
64
|
+
async function watchAd() {
|
|
65
|
+
if (!apiKey)
|
|
66
|
+
return false;
|
|
60
67
|
try {
|
|
61
|
-
const startData = await getBalance(
|
|
68
|
+
const startData = await getBalance();
|
|
62
69
|
const startBalance = startData?.balance || 0;
|
|
63
70
|
const adResponse = await fetch(`${API_BASE}/api/ads/request`, {
|
|
64
71
|
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
@@ -76,9 +83,10 @@ async function watchAd(apiKey) {
|
|
|
76
83
|
attempts++;
|
|
77
84
|
const remaining = adData.duration - Math.min(attempts, adData.duration);
|
|
78
85
|
spinner.text = remaining > 0 ? `${remaining}s` : 'Verifying...';
|
|
79
|
-
const newData = await getBalance(
|
|
86
|
+
const newData = await getBalance();
|
|
80
87
|
if (newData && newData.balance > startBalance) {
|
|
81
88
|
spinner.succeed(chalk.green(`+${formatTokens(newData.balance - startBalance)} tokens`));
|
|
89
|
+
balance = newData.balance;
|
|
82
90
|
return true;
|
|
83
91
|
}
|
|
84
92
|
}
|
|
@@ -89,7 +97,9 @@ async function watchAd(apiKey) {
|
|
|
89
97
|
return false;
|
|
90
98
|
}
|
|
91
99
|
}
|
|
92
|
-
async function generate(
|
|
100
|
+
async function generate(userPrompt) {
|
|
101
|
+
if (!apiKey)
|
|
102
|
+
return null;
|
|
93
103
|
try {
|
|
94
104
|
const response = await fetch(`${API_BASE}/api/ai/generate`, {
|
|
95
105
|
method: 'POST',
|
|
@@ -116,9 +126,9 @@ async function generate(apiKey, userPrompt) {
|
|
|
116
126
|
}
|
|
117
127
|
}
|
|
118
128
|
// ============================================================================
|
|
119
|
-
// WELCOME
|
|
129
|
+
// WELCOME
|
|
120
130
|
// ============================================================================
|
|
121
|
-
function showWelcome(
|
|
131
|
+
function showWelcome() {
|
|
122
132
|
console.clear();
|
|
123
133
|
console.log();
|
|
124
134
|
console.log(chalk.bold.white(' ┌───────────────────────────────┐'));
|
|
@@ -137,7 +147,7 @@ function showWelcome(balance) {
|
|
|
137
147
|
// ============================================================================
|
|
138
148
|
async function main() {
|
|
139
149
|
// Get or create API key
|
|
140
|
-
|
|
150
|
+
apiKey = config.get('apiKey');
|
|
141
151
|
if (!apiKey) {
|
|
142
152
|
const spinner = ora('Initializing...').start();
|
|
143
153
|
const newKey = await authenticate();
|
|
@@ -149,130 +159,111 @@ async function main() {
|
|
|
149
159
|
spinner.succeed('Ready');
|
|
150
160
|
}
|
|
151
161
|
// Get balance
|
|
152
|
-
const balanceData = await getBalance(
|
|
153
|
-
|
|
162
|
+
const balanceData = await getBalance();
|
|
163
|
+
balance = balanceData?.balance || 0;
|
|
154
164
|
// Show welcome
|
|
155
|
-
showWelcome(
|
|
156
|
-
//
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
process.stdout.write(chalk.green('› '));
|
|
164
|
-
};
|
|
165
|
-
// Handle each line
|
|
166
|
-
rl.on('line', async (input) => {
|
|
167
|
-
const trimmed = input.trim();
|
|
168
|
-
if (!trimmed) {
|
|
169
|
-
showPrompt();
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
// Handle commands
|
|
173
|
-
if (trimmed.startsWith('/')) {
|
|
174
|
-
const cmd = trimmed.toLowerCase();
|
|
175
|
-
if (cmd === '/quit' || cmd === '/exit' || cmd === '/q') {
|
|
176
|
-
console.log(chalk.dim('\n Goodbye.\n'));
|
|
177
|
-
rl.close();
|
|
178
|
-
process.exit(0);
|
|
179
|
-
}
|
|
180
|
-
if (cmd === '/help' || cmd === '/h') {
|
|
181
|
-
console.log();
|
|
182
|
-
console.log(chalk.dim(' Commands:'));
|
|
183
|
-
console.log(chalk.cyan(' /earn') + chalk.dim(' Watch ad for 8K tokens'));
|
|
184
|
-
console.log(chalk.cyan(' /balance') + chalk.dim(' Check token balance'));
|
|
185
|
-
console.log(chalk.cyan(' /clear') + chalk.dim(' Clear screen'));
|
|
186
|
-
console.log(chalk.cyan(' /quit') + chalk.dim(' Exit'));
|
|
187
|
-
console.log();
|
|
188
|
-
showPrompt();
|
|
165
|
+
showWelcome();
|
|
166
|
+
// Start REPL
|
|
167
|
+
const r = repl.start({
|
|
168
|
+
prompt: chalk.green('› '),
|
|
169
|
+
eval: async (input, _context, _filename, callback) => {
|
|
170
|
+
const trimmed = input.trim();
|
|
171
|
+
if (!trimmed) {
|
|
172
|
+
callback(null, undefined);
|
|
189
173
|
return;
|
|
190
174
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
const
|
|
194
|
-
if (
|
|
195
|
-
|
|
196
|
-
|
|
175
|
+
// Handle commands
|
|
176
|
+
if (trimmed.startsWith('/')) {
|
|
177
|
+
const cmd = trimmed.toLowerCase();
|
|
178
|
+
if (cmd === '/quit' || cmd === '/exit' || cmd === '/q') {
|
|
179
|
+
console.log(chalk.dim('\n Goodbye.\n'));
|
|
180
|
+
process.exit(0);
|
|
197
181
|
}
|
|
198
|
-
|
|
199
|
-
showPrompt();
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
if (cmd === '/balance' || cmd === '/b') {
|
|
203
|
-
const data = await getBalance(apiKey);
|
|
204
|
-
if (data) {
|
|
205
|
-
balance = data.balance;
|
|
182
|
+
if (cmd === '/help' || cmd === '/h') {
|
|
206
183
|
console.log();
|
|
207
|
-
console.log(chalk.dim('
|
|
208
|
-
console.log(chalk.
|
|
209
|
-
console.log(chalk.
|
|
184
|
+
console.log(chalk.dim(' Commands:'));
|
|
185
|
+
console.log(chalk.cyan(' /earn') + chalk.dim(' Watch ad for 8K tokens'));
|
|
186
|
+
console.log(chalk.cyan(' /balance') + chalk.dim(' Check token balance'));
|
|
187
|
+
console.log(chalk.cyan(' /clear') + chalk.dim(' Clear screen'));
|
|
188
|
+
console.log(chalk.cyan(' /quit') + chalk.dim(' Exit'));
|
|
210
189
|
console.log();
|
|
190
|
+
callback(null, undefined);
|
|
191
|
+
return;
|
|
211
192
|
}
|
|
212
|
-
|
|
193
|
+
if (cmd === '/earn' || cmd === '/e') {
|
|
194
|
+
console.log();
|
|
195
|
+
await watchAd();
|
|
196
|
+
console.log();
|
|
197
|
+
callback(null, undefined);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
if (cmd === '/balance' || cmd === '/b') {
|
|
201
|
+
const data = await getBalance();
|
|
202
|
+
if (data) {
|
|
203
|
+
balance = data.balance;
|
|
204
|
+
console.log();
|
|
205
|
+
console.log(chalk.dim(' Balance: ') + chalk.bold.white(formatTokens(data.balance)));
|
|
206
|
+
console.log(chalk.dim(' Earned: ') + formatTokens(data.totalEarned));
|
|
207
|
+
console.log(chalk.dim(' Spent: ') + formatTokens(data.totalSpent));
|
|
208
|
+
console.log();
|
|
209
|
+
}
|
|
210
|
+
callback(null, undefined);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
if (cmd === '/clear' || cmd === '/c') {
|
|
214
|
+
showWelcome();
|
|
215
|
+
callback(null, undefined);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
console.log(chalk.dim(`\n Unknown: ${trimmed}\n`));
|
|
219
|
+
callback(null, undefined);
|
|
213
220
|
return;
|
|
214
221
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
222
|
+
// Check tokens
|
|
223
|
+
if (balance < 100) {
|
|
224
|
+
console.log();
|
|
225
|
+
console.log(chalk.yellow(' Low tokens. Run /earn'));
|
|
226
|
+
console.log();
|
|
227
|
+
callback(null, undefined);
|
|
218
228
|
return;
|
|
219
229
|
}
|
|
220
|
-
|
|
221
|
-
showPrompt();
|
|
222
|
-
return;
|
|
223
|
-
}
|
|
224
|
-
// Check if we have enough tokens
|
|
225
|
-
if (balance < 100) {
|
|
226
|
-
console.log();
|
|
227
|
-
console.log(chalk.yellow(' Low tokens. Run /earn to get more.'));
|
|
228
|
-
console.log();
|
|
229
|
-
showPrompt();
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
// Generate response
|
|
233
|
-
console.log();
|
|
234
|
-
const spinner = ora({ text: chalk.dim('Thinking...'), spinner: 'dots' }).start();
|
|
235
|
-
const result = await generate(apiKey, trimmed);
|
|
236
|
-
if (!result) {
|
|
237
|
-
spinner.fail(chalk.red('Failed'));
|
|
230
|
+
// Generate
|
|
238
231
|
console.log();
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
232
|
+
const spinner = ora({ text: chalk.dim('Thinking...'), spinner: 'dots' }).start();
|
|
233
|
+
const result = await generate(trimmed);
|
|
234
|
+
if (!result) {
|
|
235
|
+
spinner.fail(chalk.red('Failed'));
|
|
236
|
+
console.log();
|
|
237
|
+
callback(null, undefined);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
if (result.text === '__INSUFFICIENT_TOKENS__') {
|
|
241
|
+
spinner.stop();
|
|
242
|
+
console.log(chalk.yellow(' Insufficient tokens. Run /earn'));
|
|
243
|
+
console.log();
|
|
244
|
+
callback(null, undefined);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
243
247
|
spinner.stop();
|
|
244
|
-
|
|
248
|
+
// Show response
|
|
249
|
+
const lines = result.text.split('\n');
|
|
250
|
+
for (const line of lines) {
|
|
251
|
+
console.log(chalk.white(' ' + line));
|
|
252
|
+
}
|
|
245
253
|
console.log();
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
console.log(chalk.white(' ' + line));
|
|
254
|
-
}
|
|
255
|
-
console.log();
|
|
256
|
-
// Update and show balance
|
|
257
|
-
balance = Math.max(0, balance - result.tokensUsed);
|
|
258
|
-
console.log(chalk.dim(` ─ ${formatTokens(result.tokensUsed)} tokens · ${formatTokens(balance)} remaining`));
|
|
259
|
-
console.log();
|
|
260
|
-
showPrompt();
|
|
254
|
+
balance = Math.max(0, balance - result.tokensUsed);
|
|
255
|
+
console.log(chalk.dim(` ─ ${formatTokens(result.tokensUsed)} tokens · ${formatTokens(balance)} remaining`));
|
|
256
|
+
console.log();
|
|
257
|
+
callback(null, undefined);
|
|
258
|
+
},
|
|
259
|
+
writer: () => '', // Suppress default output
|
|
260
|
+
ignoreUndefined: true,
|
|
261
261
|
});
|
|
262
|
-
|
|
263
|
-
rl.on('close', () => {
|
|
262
|
+
r.on('exit', () => {
|
|
264
263
|
console.log(chalk.dim('\n Goodbye.\n'));
|
|
265
264
|
process.exit(0);
|
|
266
265
|
});
|
|
267
|
-
// Handle Ctrl+C
|
|
268
|
-
rl.on('SIGINT', () => {
|
|
269
|
-
console.log(chalk.dim('\n\n Goodbye.\n'));
|
|
270
|
-
process.exit(0);
|
|
271
|
-
});
|
|
272
|
-
// Start
|
|
273
|
-
showPrompt();
|
|
274
266
|
}
|
|
275
|
-
// Run
|
|
276
267
|
main().catch((error) => {
|
|
277
268
|
console.error(chalk.red('Error:'), error.message);
|
|
278
269
|
process.exit(1);
|