@nolimitcli/cli 2.0.2 → 2.1.1

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 +115 -128
  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 { createInterface } from 'readline';
7
7
  const API_BASE = 'https://nolimit-production-2589.up.railway.app';
8
- const VERSION = '2.0.2';
8
+ const VERSION = '2.1.1';
9
9
  // Persistent config storage
10
10
  const config = new Conf({
11
11
  projectName: 'nolimit',
@@ -116,40 +116,24 @@ 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
  // ============================================================================
152
- // MAIN LOOP
136
+ // MAIN
153
137
  // ============================================================================
154
138
  async function main() {
155
139
  // Get or create API key
@@ -170,120 +154,123 @@ async function main() {
170
154
  // Show welcome
171
155
  showWelcome(balance);
172
156
  // Create readline interface
173
- const rl = createReadline();
174
- // Main loop
175
- let running = true;
176
- while (running) {
177
- try {
178
- const input = await question(rl, chalk.green('› '));
179
- const trimmed = input.trim();
180
- if (!trimmed)
181
- 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;
199
- }
200
- if (cmd === '/earn' || cmd === '/e') {
201
- console.log();
202
- const success = await watchAd(apiKey);
203
- if (success) {
204
- const newData = await getBalance(apiKey);
205
- balance = newData?.balance || balance;
206
- }
207
- 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
- }
226
- console.log(chalk.dim(`\n Unknown command: ${trimmed}\n`));
227
- continue;
157
+ const rl = createInterface({
158
+ input: process.stdin,
159
+ output: process.stdout,
160
+ });
161
+ // Show prompt
162
+ const showPrompt = () => {
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);
228
179
  }
229
- // Check if we have enough tokens
230
- if (balance < 100) {
180
+ if (cmd === '/help' || cmd === '/h') {
231
181
  console.log();
232
- console.log(chalk.yellow(' Low tokens.') + chalk.dim(' Watch an ad to continue.'));
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'));
233
187
  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();
243
- continue;
244
- }
245
- // Generate response
246
- 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;
188
+ showPrompt();
189
+ return;
253
190
  }
254
- if (result.text === '__INSUFFICIENT_TOKENS__') {
255
- spinner.stop();
256
- console.log(chalk.yellow(' Insufficient tokens.') + chalk.dim(' Watch an ad to continue.'));
191
+ if (cmd === '/earn' || cmd === '/e') {
257
192
  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
- }
193
+ const success = await watchAd(apiKey);
194
+ if (success) {
195
+ const newData = await getBalance(apiKey);
196
+ balance = newData?.balance || balance;
265
197
  }
266
198
  console.log();
267
- continue;
199
+ showPrompt();
200
+ return;
268
201
  }
269
- spinner.stop();
270
- // Show response
271
- console.log(chalk.white(result.text));
202
+ if (cmd === '/balance' || cmd === '/b') {
203
+ const data = await getBalance(apiKey);
204
+ if (data) {
205
+ balance = data.balance;
206
+ console.log();
207
+ console.log(chalk.dim(' Balance: ') + chalk.bold.white(formatTokens(data.balance)));
208
+ console.log(chalk.dim(' Earned: ') + formatTokens(data.totalEarned));
209
+ console.log(chalk.dim(' Spent: ') + formatTokens(data.totalSpent));
210
+ console.log();
211
+ }
212
+ showPrompt();
213
+ return;
214
+ }
215
+ if (cmd === '/clear' || cmd === '/c') {
216
+ showWelcome(balance);
217
+ showPrompt();
218
+ return;
219
+ }
220
+ console.log(chalk.dim(`\n Unknown: ${trimmed}\n`));
221
+ showPrompt();
222
+ return;
223
+ }
224
+ // Check if we have enough tokens
225
+ if (balance < 100) {
272
226
  console.log();
273
- console.log(chalk.dim(` ${formatTokens(result.tokensUsed)} tokens used`));
227
+ console.log(chalk.yellow(' Low tokens. Run /earn to get more.'));
274
228
  console.log();
275
- // Update balance
276
- balance = Math.max(0, balance - result.tokensUsed);
229
+ showPrompt();
230
+ return;
277
231
  }
278
- catch (error) {
279
- // Handle Ctrl+C or EOF
280
- console.log(chalk.dim('\n Goodbye.\n'));
281
- running = false;
282
- break;
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'));
238
+ console.log();
239
+ showPrompt();
240
+ return;
283
241
  }
284
- }
285
- rl.close();
286
- process.exit(0);
242
+ if (result.text === '__INSUFFICIENT_TOKENS__') {
243
+ spinner.stop();
244
+ console.log(chalk.yellow(' Insufficient tokens. Run /earn to get more.'));
245
+ console.log();
246
+ showPrompt();
247
+ return;
248
+ }
249
+ spinner.stop();
250
+ // Show response (indented for visual hierarchy)
251
+ const lines = result.text.split('\n');
252
+ for (const line of lines) {
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();
261
+ });
262
+ // Handle close
263
+ rl.on('close', () => {
264
+ console.log(chalk.dim('\n Goodbye.\n'));
265
+ process.exit(0);
266
+ });
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();
287
274
  }
288
275
  // Run
289
276
  main().catch((error) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nolimitcli/cli",
3
- "version": "2.0.2",
3
+ "version": "2.1.1",
4
4
  "type": "module",
5
5
  "description": "No subscription. Just code. AI chat powered by watching ads.",
6
6
  "main": "dist/index.js",