@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.
Files changed (2) hide show
  1. package/dist/index.js +121 -118
  2. 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.2';
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(' NoLimit ') + chalk.dim(`v${VERSION}`) + chalk.bold.white(' │'));
142
- console.log(chalk.bold.white(' │') + chalk.gray(' No subscription. Just code.') + chalk.bold.white(' │'));
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(' Balance: ') + chalk.bold.white(formatTokens(balance)) + chalk.dim(' tokens'));
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(' Commands: ') + chalk.cyan('/earn') + chalk.dim(' · ') + chalk.cyan('/balance') + chalk.dim(' · ') + chalk.cyan('/help') + chalk.dim(' · ') + chalk.cyan('/quit'));
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 = createReadline();
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
- let running = true;
176
- while (running) {
168
+ while (true) {
169
+ let input;
177
170
  try {
178
- const input = await question(rl, chalk.green('› '));
179
- const trimmed = input.trim();
180
- if (!trimmed)
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
- // Handle commands
183
- if (trimmed.startsWith('/')) {
184
- const cmd = trimmed.toLowerCase();
185
- if (cmd === '/quit' || cmd === '/exit' || cmd === '/q') {
186
- console.log(chalk.dim('\n Goodbye.\n'));
187
- running = false;
188
- break;
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
- if (cmd === '/earn' || cmd === '/e') {
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
- const success = await watchAd(apiKey);
203
- if (success) {
204
- const newData = await getBalance(apiKey);
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
- // Check if we have enough tokens
230
- if (balance < 100) {
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
- // Generate response
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
- const spinner = ora({ text: chalk.dim('Thinking...'), spinner: 'dots' }).start();
248
- const result = await generate(apiKey, trimmed);
249
- if (!result) {
250
- spinner.fail(chalk.red('Failed to generate response'));
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
- if (result.text === '__INSUFFICIENT_TOKENS__') {
255
- spinner.stop();
256
- console.log(chalk.yellow(' Insufficient tokens.') + chalk.dim(' Watch an ad to continue.'));
257
- console.log();
258
- const answer = await question(rl, chalk.dim(' Watch now? ') + chalk.cyan('[Y/n] '));
259
- if (answer.toLowerCase() !== 'n') {
260
- const success = await watchAd(apiKey);
261
- if (success) {
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
- console.log(chalk.dim(` ─ ${formatTokens(result.tokensUsed)} tokens used`));
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
- // Update balance
276
- balance = Math.max(0, balance - result.tokensUsed);
254
+ continue;
277
255
  }
278
- catch (error) {
279
- // Handle Ctrl+C or EOF
280
- console.log(chalk.dim('\n Goodbye.\n'));
281
- running = false;
282
- break;
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nolimitcli/cli",
3
- "version": "2.0.2",
3
+ "version": "2.1.0",
4
4
  "type": "module",
5
5
  "description": "No subscription. Just code. AI chat powered by watching ads.",
6
6
  "main": "dist/index.js",