@nolimitcli/cli 2.0.0 → 2.0.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/README.md +51 -9
- package/dist/index.js +52 -58
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,25 +1,67 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @nolimitcli/cli
|
|
2
2
|
|
|
3
3
|
No subscription. Just code.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npx @
|
|
8
|
+
npx @nolimitcli/cli
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Or install globally:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
|
|
15
|
-
nolimit
|
|
16
|
-
|
|
14
|
+
npm install -g @nolimitcli/cli
|
|
15
|
+
nolimit
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
Just run the command and start chatting:
|
|
21
|
+
|
|
17
22
|
```
|
|
23
|
+
┌─────────────────────────────┐
|
|
24
|
+
│ NoLimit v2.0.0 │
|
|
25
|
+
│ No subscription. Just code. │
|
|
26
|
+
└─────────────────────────────┘
|
|
27
|
+
|
|
28
|
+
Balance: 2K tokens
|
|
29
|
+
|
|
30
|
+
Commands: /earn · /balance · /help · /quit
|
|
31
|
+
─────────────────────────────────
|
|
32
|
+
|
|
33
|
+
› Write a function to reverse a string
|
|
34
|
+
|
|
35
|
+
function reverse(str) {
|
|
36
|
+
return str.split('').reverse().join('');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
─ 89 tokens used
|
|
40
|
+
|
|
41
|
+
›
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Commands
|
|
45
|
+
|
|
46
|
+
| Command | Description |
|
|
47
|
+
|---------|-------------|
|
|
48
|
+
| `/earn` | Watch an ad to earn 8K tokens |
|
|
49
|
+
| `/balance` | Check your token balance |
|
|
50
|
+
| `/clear` | Clear the screen |
|
|
51
|
+
| `/help` | Show all commands |
|
|
52
|
+
| `/quit` | Exit |
|
|
18
53
|
|
|
19
54
|
## How it works
|
|
20
55
|
|
|
21
|
-
1.
|
|
22
|
-
2.
|
|
23
|
-
3.
|
|
56
|
+
1. First run auto-authenticates (2K welcome tokens)
|
|
57
|
+
2. Type anything to chat with AI
|
|
58
|
+
3. When tokens run low, type `/earn`
|
|
59
|
+
4. Watch a 30-second ad in your browser
|
|
60
|
+
5. Continue chatting
|
|
24
61
|
|
|
25
62
|
No subscription. No credit card. Just code.
|
|
63
|
+
|
|
64
|
+
## Links
|
|
65
|
+
|
|
66
|
+
- [nolimit.dev](https://nolimit.dev)
|
|
67
|
+
- [GitHub](https://github.com/buzzernetwork/nolimit)
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import ora from 'ora';
|
|
|
5
5
|
import open from 'open';
|
|
6
6
|
import * as readline from 'readline';
|
|
7
7
|
const API_BASE = 'https://nolimit-production-2589.up.railway.app';
|
|
8
|
-
const VERSION = '2.0.
|
|
8
|
+
const VERSION = '2.0.2';
|
|
9
9
|
// Persistent config storage
|
|
10
10
|
const config = new Conf({
|
|
11
11
|
projectName: 'nolimit',
|
|
@@ -58,20 +58,16 @@ async function authenticate() {
|
|
|
58
58
|
}
|
|
59
59
|
async function watchAd(apiKey) {
|
|
60
60
|
try {
|
|
61
|
-
// Get starting balance
|
|
62
61
|
const startData = await getBalance(apiKey);
|
|
63
62
|
const startBalance = startData?.balance || 0;
|
|
64
|
-
// Request ad
|
|
65
63
|
const adResponse = await fetch(`${API_BASE}/api/ads/request`, {
|
|
66
64
|
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
67
65
|
});
|
|
68
66
|
if (!adResponse.ok)
|
|
69
67
|
return false;
|
|
70
68
|
const adData = await adResponse.json();
|
|
71
|
-
// Open ad viewer
|
|
72
69
|
const adUrl = `${API_BASE}/ad-viewer.html?adId=${adData.adId}&apiKey=${apiKey}`;
|
|
73
70
|
await open(adUrl);
|
|
74
|
-
// Poll for completion
|
|
75
71
|
const spinner = ora('Watching...').start();
|
|
76
72
|
let attempts = 0;
|
|
77
73
|
const maxAttempts = 60;
|
|
@@ -93,7 +89,7 @@ async function watchAd(apiKey) {
|
|
|
93
89
|
return false;
|
|
94
90
|
}
|
|
95
91
|
}
|
|
96
|
-
async function generate(apiKey,
|
|
92
|
+
async function generate(apiKey, userPrompt) {
|
|
97
93
|
try {
|
|
98
94
|
const response = await fetch(`${API_BASE}/api/ai/generate`, {
|
|
99
95
|
method: 'POST',
|
|
@@ -101,7 +97,7 @@ async function generate(apiKey, prompt) {
|
|
|
101
97
|
'Authorization': `Bearer ${apiKey}`,
|
|
102
98
|
'Content-Type': 'application/json',
|
|
103
99
|
},
|
|
104
|
-
body: JSON.stringify({ prompt }),
|
|
100
|
+
body: JSON.stringify({ prompt: userPrompt }),
|
|
105
101
|
});
|
|
106
102
|
const data = await response.json();
|
|
107
103
|
if (!response.ok) {
|
|
@@ -115,11 +111,27 @@ async function generate(apiKey, prompt) {
|
|
|
115
111
|
tokensUsed: data.usage?.totalTokens || 0,
|
|
116
112
|
};
|
|
117
113
|
}
|
|
118
|
-
catch
|
|
114
|
+
catch {
|
|
119
115
|
return null;
|
|
120
116
|
}
|
|
121
117
|
}
|
|
122
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
|
+
// ============================================================================
|
|
123
135
|
// WELCOME SCREEN
|
|
124
136
|
// ============================================================================
|
|
125
137
|
function showWelcome(balance) {
|
|
@@ -158,24 +170,22 @@ async function main() {
|
|
|
158
170
|
// Show welcome
|
|
159
171
|
showWelcome(balance);
|
|
160
172
|
// Create readline interface
|
|
161
|
-
const rl =
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
173
|
+
const rl = createReadline();
|
|
174
|
+
// Main loop
|
|
175
|
+
let running = true;
|
|
176
|
+
while (running) {
|
|
177
|
+
try {
|
|
178
|
+
const input = await question(rl, chalk.green('› '));
|
|
167
179
|
const trimmed = input.trim();
|
|
168
|
-
if (!trimmed)
|
|
169
|
-
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
180
|
+
if (!trimmed)
|
|
181
|
+
continue;
|
|
172
182
|
// Handle commands
|
|
173
183
|
if (trimmed.startsWith('/')) {
|
|
174
184
|
const cmd = trimmed.toLowerCase();
|
|
175
185
|
if (cmd === '/quit' || cmd === '/exit' || cmd === '/q') {
|
|
176
186
|
console.log(chalk.dim('\n Goodbye.\n'));
|
|
177
|
-
|
|
178
|
-
|
|
187
|
+
running = false;
|
|
188
|
+
break;
|
|
179
189
|
}
|
|
180
190
|
if (cmd === '/help' || cmd === '/h') {
|
|
181
191
|
console.log();
|
|
@@ -185,8 +195,7 @@ async function main() {
|
|
|
185
195
|
console.log(chalk.cyan(' /clear') + chalk.dim(' Clear the screen'));
|
|
186
196
|
console.log(chalk.cyan(' /quit') + chalk.dim(' Exit NoLimit'));
|
|
187
197
|
console.log();
|
|
188
|
-
|
|
189
|
-
return;
|
|
198
|
+
continue;
|
|
190
199
|
}
|
|
191
200
|
if (cmd === '/earn' || cmd === '/e') {
|
|
192
201
|
console.log();
|
|
@@ -196,8 +205,7 @@ async function main() {
|
|
|
196
205
|
balance = newData?.balance || balance;
|
|
197
206
|
}
|
|
198
207
|
console.log();
|
|
199
|
-
|
|
200
|
-
return;
|
|
208
|
+
continue;
|
|
201
209
|
}
|
|
202
210
|
if (cmd === '/balance' || cmd === '/b') {
|
|
203
211
|
const data = await getBalance(apiKey);
|
|
@@ -209,29 +217,22 @@ async function main() {
|
|
|
209
217
|
console.log(chalk.dim(' Spent: ') + formatTokens(data.totalSpent));
|
|
210
218
|
console.log();
|
|
211
219
|
}
|
|
212
|
-
|
|
213
|
-
return;
|
|
220
|
+
continue;
|
|
214
221
|
}
|
|
215
222
|
if (cmd === '/clear' || cmd === '/c') {
|
|
216
223
|
showWelcome(balance);
|
|
217
|
-
|
|
218
|
-
return;
|
|
224
|
+
continue;
|
|
219
225
|
}
|
|
220
226
|
console.log(chalk.dim(`\n Unknown command: ${trimmed}\n`));
|
|
221
|
-
|
|
222
|
-
return;
|
|
227
|
+
continue;
|
|
223
228
|
}
|
|
224
229
|
// Check if we have enough tokens
|
|
225
230
|
if (balance < 100) {
|
|
226
231
|
console.log();
|
|
227
232
|
console.log(chalk.yellow(' Low tokens.') + chalk.dim(' Watch an ad to continue.'));
|
|
228
233
|
console.log();
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
resolve(answer.toLowerCase() !== 'n');
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
if (watch) {
|
|
234
|
+
const answer = await question(rl, chalk.dim(' Watch now? ') + chalk.cyan('[Y/n] '));
|
|
235
|
+
if (answer.toLowerCase() !== 'n') {
|
|
235
236
|
const success = await watchAd(apiKey);
|
|
236
237
|
if (success) {
|
|
237
238
|
const newData = await getBalance(apiKey);
|
|
@@ -239,8 +240,7 @@ async function main() {
|
|
|
239
240
|
}
|
|
240
241
|
}
|
|
241
242
|
console.log();
|
|
242
|
-
|
|
243
|
-
return;
|
|
243
|
+
continue;
|
|
244
244
|
}
|
|
245
245
|
// Generate response
|
|
246
246
|
console.log();
|
|
@@ -249,19 +249,14 @@ async function main() {
|
|
|
249
249
|
if (!result) {
|
|
250
250
|
spinner.fail(chalk.red('Failed to generate response'));
|
|
251
251
|
console.log();
|
|
252
|
-
|
|
253
|
-
return;
|
|
252
|
+
continue;
|
|
254
253
|
}
|
|
255
254
|
if (result.text === '__INSUFFICIENT_TOKENS__') {
|
|
256
255
|
spinner.stop();
|
|
257
256
|
console.log(chalk.yellow(' Insufficient tokens.') + chalk.dim(' Watch an ad to continue.'));
|
|
258
257
|
console.log();
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
resolve(answer.toLowerCase() !== 'n');
|
|
262
|
-
});
|
|
263
|
-
});
|
|
264
|
-
if (watch) {
|
|
258
|
+
const answer = await question(rl, chalk.dim(' Watch now? ') + chalk.cyan('[Y/n] '));
|
|
259
|
+
if (answer.toLowerCase() !== 'n') {
|
|
265
260
|
const success = await watchAd(apiKey);
|
|
266
261
|
if (success) {
|
|
267
262
|
const newData = await getBalance(apiKey);
|
|
@@ -269,8 +264,7 @@ async function main() {
|
|
|
269
264
|
}
|
|
270
265
|
}
|
|
271
266
|
console.log();
|
|
272
|
-
|
|
273
|
-
return;
|
|
267
|
+
continue;
|
|
274
268
|
}
|
|
275
269
|
spinner.stop();
|
|
276
270
|
// Show response
|
|
@@ -280,16 +274,16 @@ async function main() {
|
|
|
280
274
|
console.log();
|
|
281
275
|
// Update balance
|
|
282
276
|
balance = Math.max(0, balance - result.tokensUsed);
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
|
|
277
|
+
}
|
|
278
|
+
catch (error) {
|
|
279
|
+
// Handle Ctrl+C or EOF
|
|
280
|
+
console.log(chalk.dim('\n Goodbye.\n'));
|
|
281
|
+
running = false;
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
rl.close();
|
|
286
|
+
process.exit(0);
|
|
293
287
|
}
|
|
294
288
|
// Run
|
|
295
289
|
main().catch((error) => {
|