@nolimitcli/cli 2.0.2 → 2.1.0
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 +121 -118
- 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 * as readline from 'readline';
|
|
6
|
+
import * as readline from 'readline/promises';
|
|
7
7
|
const API_BASE = 'https://nolimit-production-2589.up.railway.app';
|
|
8
|
-
const VERSION = '2.0
|
|
8
|
+
const VERSION = '2.1.0';
|
|
9
9
|
// Persistent config storage
|
|
10
10
|
const config = new Conf({
|
|
11
11
|
projectName: 'nolimit',
|
|
@@ -116,36 +116,20 @@ async function generate(apiKey, userPrompt) {
|
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
// ============================================================================
|
|
119
|
-
// READLINE HELPERS
|
|
120
|
-
// ============================================================================
|
|
121
|
-
function createReadline() {
|
|
122
|
-
return readline.createInterface({
|
|
123
|
-
input: process.stdin,
|
|
124
|
-
output: process.stdout,
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
function question(rl, query) {
|
|
128
|
-
return new Promise((resolve) => {
|
|
129
|
-
rl.question(query, (answer) => {
|
|
130
|
-
resolve(answer);
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
// ============================================================================
|
|
135
119
|
// WELCOME SCREEN
|
|
136
120
|
// ============================================================================
|
|
137
121
|
function showWelcome(balance) {
|
|
138
122
|
console.clear();
|
|
139
123
|
console.log();
|
|
140
|
-
console.log(chalk.bold.white('
|
|
141
|
-
console.log(chalk.bold.white(' │') + chalk.bold('
|
|
142
|
-
console.log(chalk.bold.white(' │') + chalk.
|
|
143
|
-
console.log(chalk.bold.white('
|
|
124
|
+
console.log(chalk.bold.white(' ┌───────────────────────────────┐'));
|
|
125
|
+
console.log(chalk.bold.white(' │') + chalk.bold(' NoLimit ') + chalk.dim(`v${VERSION}`) + chalk.bold.white(' │'));
|
|
126
|
+
console.log(chalk.bold.white(' │') + chalk.dim(' No subscription. Just code.') + chalk.bold.white(' │'));
|
|
127
|
+
console.log(chalk.bold.white(' └───────────────────────────────┘'));
|
|
144
128
|
console.log();
|
|
145
|
-
console.log(chalk.dim('
|
|
129
|
+
console.log(chalk.dim(' Gemini 2.0 Flash') + chalk.dim(' · ') + chalk.bold.white(formatTokens(balance)) + chalk.dim(' tokens'));
|
|
146
130
|
console.log();
|
|
147
|
-
console.log(chalk.dim('
|
|
148
|
-
console.log(chalk.dim('
|
|
131
|
+
console.log(chalk.dim(' /earn · /balance · /help · /quit'));
|
|
132
|
+
console.log(chalk.dim(' ───────────────────────────────────'));
|
|
149
133
|
console.log();
|
|
150
134
|
}
|
|
151
135
|
// ============================================================================
|
|
@@ -169,118 +153,137 @@ async function main() {
|
|
|
169
153
|
let balance = balanceData?.balance || 0;
|
|
170
154
|
// Show welcome
|
|
171
155
|
showWelcome(balance);
|
|
172
|
-
// Create readline interface
|
|
173
|
-
const rl =
|
|
156
|
+
// Create readline interface using promises API
|
|
157
|
+
const rl = readline.createInterface({
|
|
158
|
+
input: process.stdin,
|
|
159
|
+
output: process.stdout,
|
|
160
|
+
});
|
|
161
|
+
// Handle Ctrl+C
|
|
162
|
+
process.on('SIGINT', () => {
|
|
163
|
+
console.log(chalk.dim('\n\n Goodbye.\n'));
|
|
164
|
+
rl.close();
|
|
165
|
+
process.exit(0);
|
|
166
|
+
});
|
|
174
167
|
// Main loop
|
|
175
|
-
|
|
176
|
-
|
|
168
|
+
while (true) {
|
|
169
|
+
let input;
|
|
177
170
|
try {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
171
|
+
input = await rl.question(chalk.green('› '));
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
// EOF or stream closed
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
const trimmed = input.trim();
|
|
178
|
+
if (!trimmed)
|
|
179
|
+
continue;
|
|
180
|
+
// Handle commands
|
|
181
|
+
if (trimmed.startsWith('/')) {
|
|
182
|
+
const cmd = trimmed.toLowerCase();
|
|
183
|
+
if (cmd === '/quit' || cmd === '/exit' || cmd === '/q') {
|
|
184
|
+
console.log(chalk.dim('\n Goodbye.\n'));
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
if (cmd === '/help' || cmd === '/h') {
|
|
188
|
+
console.log();
|
|
189
|
+
console.log(chalk.dim(' Commands:'));
|
|
190
|
+
console.log(chalk.cyan(' /earn') + chalk.dim(' Watch ad for 8K tokens'));
|
|
191
|
+
console.log(chalk.cyan(' /balance') + chalk.dim(' Check token balance'));
|
|
192
|
+
console.log(chalk.cyan(' /clear') + chalk.dim(' Clear screen'));
|
|
193
|
+
console.log(chalk.cyan(' /quit') + chalk.dim(' Exit'));
|
|
194
|
+
console.log();
|
|
181
195
|
continue;
|
|
182
|
-
|
|
183
|
-
if (
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
if (cmd === '/help' || cmd === '/h') {
|
|
191
|
-
console.log();
|
|
192
|
-
console.log(chalk.dim(' Commands:'));
|
|
193
|
-
console.log(chalk.cyan(' /earn') + chalk.dim(' Watch an ad to earn tokens'));
|
|
194
|
-
console.log(chalk.cyan(' /balance') + chalk.dim(' Check your token balance'));
|
|
195
|
-
console.log(chalk.cyan(' /clear') + chalk.dim(' Clear the screen'));
|
|
196
|
-
console.log(chalk.cyan(' /quit') + chalk.dim(' Exit NoLimit'));
|
|
197
|
-
console.log();
|
|
198
|
-
continue;
|
|
196
|
+
}
|
|
197
|
+
if (cmd === '/earn' || cmd === '/e') {
|
|
198
|
+
console.log();
|
|
199
|
+
const success = await watchAd(apiKey);
|
|
200
|
+
if (success) {
|
|
201
|
+
const newData = await getBalance(apiKey);
|
|
202
|
+
balance = newData?.balance || balance;
|
|
199
203
|
}
|
|
200
|
-
|
|
204
|
+
console.log();
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (cmd === '/balance' || cmd === '/b') {
|
|
208
|
+
const data = await getBalance(apiKey);
|
|
209
|
+
if (data) {
|
|
210
|
+
balance = data.balance;
|
|
201
211
|
console.log();
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
balance = newData?.balance || balance;
|
|
206
|
-
}
|
|
212
|
+
console.log(chalk.dim(' Balance: ') + chalk.bold.white(formatTokens(data.balance)));
|
|
213
|
+
console.log(chalk.dim(' Earned: ') + formatTokens(data.totalEarned));
|
|
214
|
+
console.log(chalk.dim(' Spent: ') + formatTokens(data.totalSpent));
|
|
207
215
|
console.log();
|
|
208
|
-
continue;
|
|
209
|
-
}
|
|
210
|
-
if (cmd === '/balance' || cmd === '/b') {
|
|
211
|
-
const data = await getBalance(apiKey);
|
|
212
|
-
if (data) {
|
|
213
|
-
balance = data.balance;
|
|
214
|
-
console.log();
|
|
215
|
-
console.log(chalk.dim(' Balance: ') + chalk.bold.white(formatTokens(data.balance)) + chalk.dim(' tokens'));
|
|
216
|
-
console.log(chalk.dim(' Earned: ') + formatTokens(data.totalEarned));
|
|
217
|
-
console.log(chalk.dim(' Spent: ') + formatTokens(data.totalSpent));
|
|
218
|
-
console.log();
|
|
219
|
-
}
|
|
220
|
-
continue;
|
|
221
|
-
}
|
|
222
|
-
if (cmd === '/clear' || cmd === '/c') {
|
|
223
|
-
showWelcome(balance);
|
|
224
|
-
continue;
|
|
225
216
|
}
|
|
226
|
-
console.log(chalk.dim(`\n Unknown command: ${trimmed}\n`));
|
|
227
217
|
continue;
|
|
228
218
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
console.log();
|
|
232
|
-
console.log(chalk.yellow(' Low tokens.') + chalk.dim(' Watch an ad to continue.'));
|
|
233
|
-
console.log();
|
|
234
|
-
const answer = await question(rl, chalk.dim(' Watch now? ') + chalk.cyan('[Y/n] '));
|
|
235
|
-
if (answer.toLowerCase() !== 'n') {
|
|
236
|
-
const success = await watchAd(apiKey);
|
|
237
|
-
if (success) {
|
|
238
|
-
const newData = await getBalance(apiKey);
|
|
239
|
-
balance = newData?.balance || balance;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
console.log();
|
|
219
|
+
if (cmd === '/clear' || cmd === '/c') {
|
|
220
|
+
showWelcome(balance);
|
|
243
221
|
continue;
|
|
244
222
|
}
|
|
245
|
-
|
|
223
|
+
console.log(chalk.dim(`\n Unknown: ${trimmed}\n`));
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
// Check if we have enough tokens
|
|
227
|
+
if (balance < 100) {
|
|
246
228
|
console.log();
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
console.log();
|
|
252
|
-
continue;
|
|
229
|
+
console.log(chalk.yellow(' Low tokens.'));
|
|
230
|
+
let answer;
|
|
231
|
+
try {
|
|
232
|
+
answer = await rl.question(chalk.dim(' Watch ad? ') + chalk.cyan('[Y/n] '));
|
|
253
233
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
const
|
|
259
|
-
if (
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
const newData = await getBalance(apiKey);
|
|
263
|
-
balance = newData?.balance || balance;
|
|
264
|
-
}
|
|
234
|
+
catch {
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
if (answer.toLowerCase() !== 'n') {
|
|
238
|
+
const success = await watchAd(apiKey);
|
|
239
|
+
if (success) {
|
|
240
|
+
const newData = await getBalance(apiKey);
|
|
241
|
+
balance = newData?.balance || balance;
|
|
265
242
|
}
|
|
266
|
-
console.log();
|
|
267
|
-
continue;
|
|
268
243
|
}
|
|
269
|
-
spinner.stop();
|
|
270
|
-
// Show response
|
|
271
|
-
console.log(chalk.white(result.text));
|
|
272
244
|
console.log();
|
|
273
|
-
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
// Generate response
|
|
248
|
+
console.log();
|
|
249
|
+
const spinner = ora({ text: chalk.dim('Thinking...'), spinner: 'dots' }).start();
|
|
250
|
+
const result = await generate(apiKey, trimmed);
|
|
251
|
+
if (!result) {
|
|
252
|
+
spinner.fail(chalk.red('Failed'));
|
|
274
253
|
console.log();
|
|
275
|
-
|
|
276
|
-
balance = Math.max(0, balance - result.tokensUsed);
|
|
254
|
+
continue;
|
|
277
255
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
console.log(chalk.
|
|
281
|
-
|
|
282
|
-
|
|
256
|
+
if (result.text === '__INSUFFICIENT_TOKENS__') {
|
|
257
|
+
spinner.stop();
|
|
258
|
+
console.log(chalk.yellow(' Insufficient tokens.'));
|
|
259
|
+
let answer;
|
|
260
|
+
try {
|
|
261
|
+
answer = await rl.question(chalk.dim(' Watch ad? ') + chalk.cyan('[Y/n] '));
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
break;
|
|
265
|
+
}
|
|
266
|
+
if (answer.toLowerCase() !== 'n') {
|
|
267
|
+
const success = await watchAd(apiKey);
|
|
268
|
+
if (success) {
|
|
269
|
+
const newData = await getBalance(apiKey);
|
|
270
|
+
balance = newData?.balance || balance;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
console.log();
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
spinner.stop();
|
|
277
|
+
// Show response (indented for visual hierarchy)
|
|
278
|
+
const lines = result.text.split('\n');
|
|
279
|
+
for (const line of lines) {
|
|
280
|
+
console.log(chalk.white(' ' + line));
|
|
283
281
|
}
|
|
282
|
+
console.log();
|
|
283
|
+
// Update and show balance
|
|
284
|
+
balance = Math.max(0, balance - result.tokensUsed);
|
|
285
|
+
console.log(chalk.dim(` ─ ${formatTokens(result.tokensUsed)} tokens · ${formatTokens(balance)} remaining`));
|
|
286
|
+
console.log();
|
|
284
287
|
}
|
|
285
288
|
rl.close();
|
|
286
289
|
process.exit(0);
|