@nolimitcli/cli 1.0.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/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # @nolimit/cli
2
+
3
+ No subscription. Just code.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npx @nolimit/cli
9
+ ```
10
+
11
+ ## Commands
12
+
13
+ ```bash
14
+ nolimit auth # Authenticate (get 2K welcome tokens)
15
+ nolimit earn # Watch ad to earn 8K tokens
16
+ nolimit balance # Check token balance
17
+ ```
18
+
19
+ ## How it works
20
+
21
+ 1. Watch a 30-second ad
22
+ 2. Earn 8,000 tokens
23
+ 3. Use tokens for AI prompts
24
+
25
+ No subscription. No credit card. Just code.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,173 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import Conf from 'conf';
4
+ import chalk from 'chalk';
5
+ import ora from 'ora';
6
+ import open from 'open';
7
+ const API_BASE = 'https://nolimit-production-2589.up.railway.app';
8
+ // Persistent config storage
9
+ const config = new Conf({
10
+ projectName: 'nolimit',
11
+ schema: {
12
+ sessionId: { type: 'string' },
13
+ apiKey: { type: 'string' },
14
+ },
15
+ });
16
+ const program = new Command();
17
+ program
18
+ .name('nolimit')
19
+ .description('No subscription. Just code.')
20
+ .version('1.0.0');
21
+ // Auth command - register and get API key
22
+ program
23
+ .command('auth')
24
+ .description('Authenticate with NoLimit')
25
+ .action(async () => {
26
+ const spinner = ora('Registering...').start();
27
+ try {
28
+ const response = await fetch(`${API_BASE}/api/auth/register`, {
29
+ method: 'POST',
30
+ headers: { 'Content-Type': 'application/json' },
31
+ body: JSON.stringify({
32
+ deviceId: `cli-${Date.now()}`,
33
+ userAgent: 'nolimit-cli/1.0.0',
34
+ consent: true,
35
+ }),
36
+ });
37
+ if (!response.ok) {
38
+ throw new Error(`Registration failed: ${response.status}`);
39
+ }
40
+ const data = await response.json();
41
+ config.set('sessionId', data.sessionId);
42
+ config.set('apiKey', data.apiKey);
43
+ spinner.succeed(chalk.green('Authenticated'));
44
+ console.log();
45
+ console.log(chalk.dim('Session:'), data.sessionId.slice(0, 8) + '...');
46
+ if (data.welcomeBonus > 0) {
47
+ console.log(chalk.green(`+${data.welcomeBonus.toLocaleString()}`), 'welcome tokens');
48
+ }
49
+ console.log();
50
+ console.log(chalk.dim('Run'), chalk.cyan('nolimit earn'), chalk.dim('to get more tokens'));
51
+ }
52
+ catch (error) {
53
+ spinner.fail(chalk.red('Authentication failed'));
54
+ console.error(error instanceof Error ? error.message : error);
55
+ process.exit(1);
56
+ }
57
+ });
58
+ // Earn command - watch ad to earn tokens
59
+ program
60
+ .command('earn')
61
+ .description('Watch an ad to earn tokens')
62
+ .action(async () => {
63
+ const apiKey = config.get('apiKey');
64
+ if (!apiKey) {
65
+ console.log(chalk.yellow('Not authenticated.'));
66
+ console.log(chalk.dim('Run'), chalk.cyan('nolimit auth'), chalk.dim('first'));
67
+ process.exit(1);
68
+ }
69
+ const spinner = ora('Requesting ad...').start();
70
+ try {
71
+ // Request ad
72
+ const adResponse = await fetch(`${API_BASE}/api/ads/request`, {
73
+ method: 'GET',
74
+ headers: {
75
+ 'Authorization': `Bearer ${apiKey}`,
76
+ },
77
+ });
78
+ if (!adResponse.ok) {
79
+ throw new Error(`Ad request failed: ${adResponse.status}`);
80
+ }
81
+ const adData = await adResponse.json();
82
+ spinner.succeed('Ad ready');
83
+ console.log();
84
+ console.log(chalk.dim('Reward:'), chalk.bold(adData.tokenReward.toLocaleString()), 'tokens');
85
+ console.log(chalk.dim('Duration:'), adData.duration, 'seconds');
86
+ console.log();
87
+ // Open ad viewer in browser
88
+ const adUrl = `${API_BASE}/ad-viewer.html?adId=${adData.adId}&apiKey=${apiKey}`;
89
+ console.log(chalk.dim('Opening ad in browser...'));
90
+ await open(adUrl);
91
+ // Wait for user to complete ad
92
+ console.log();
93
+ console.log(chalk.yellow('Complete the ad in your browser.'));
94
+ console.log(chalk.dim('Press Enter when done...'));
95
+ await new Promise((resolve) => {
96
+ process.stdin.once('data', () => resolve());
97
+ });
98
+ // Verify completion
99
+ const verifySpinner = ora('Verifying...').start();
100
+ const verifyResponse = await fetch(`${API_BASE}/api/ads/verify-completion`, {
101
+ method: 'POST',
102
+ headers: {
103
+ 'Content-Type': 'application/json',
104
+ 'Authorization': `Bearer ${apiKey}`,
105
+ },
106
+ body: JSON.stringify({
107
+ adId: adData.adId,
108
+ completedAt: Date.now(),
109
+ events: [
110
+ { event: 'play', time: 0 },
111
+ { event: 'midpoint', time: Math.floor(adData.duration / 2) },
112
+ { event: 'complete', time: adData.duration },
113
+ ],
114
+ }),
115
+ });
116
+ if (!verifyResponse.ok) {
117
+ const errorData = await verifyResponse.json().catch(() => ({}));
118
+ throw new Error(errorData.error || `Verification failed: ${verifyResponse.status}`);
119
+ }
120
+ const verifyData = await verifyResponse.json();
121
+ verifySpinner.succeed(chalk.green('Tokens earned'));
122
+ console.log();
123
+ console.log(chalk.bold.green(`+${verifyData.tokensGranted.toLocaleString()}`), 'tokens');
124
+ console.log(chalk.dim('New balance:'), chalk.bold(verifyData.newBalance.toLocaleString()));
125
+ }
126
+ catch (error) {
127
+ spinner.fail(chalk.red('Failed'));
128
+ console.error(error instanceof Error ? error.message : error);
129
+ process.exit(1);
130
+ }
131
+ });
132
+ // Balance command - check current balance
133
+ program
134
+ .command('balance')
135
+ .description('Check your token balance')
136
+ .action(async () => {
137
+ const apiKey = config.get('apiKey');
138
+ if (!apiKey) {
139
+ console.log(chalk.yellow('Not authenticated.'));
140
+ console.log(chalk.dim('Run'), chalk.cyan('nolimit auth'), chalk.dim('first'));
141
+ process.exit(1);
142
+ }
143
+ const spinner = ora('Fetching balance...').start();
144
+ try {
145
+ const response = await fetch(`${API_BASE}/api/credits/balance`, {
146
+ headers: { 'Authorization': `Bearer ${apiKey}` },
147
+ });
148
+ if (!response.ok) {
149
+ throw new Error(`Failed to fetch balance: ${response.status}`);
150
+ }
151
+ const data = await response.json();
152
+ spinner.succeed('Balance');
153
+ console.log();
154
+ console.log(chalk.bold.white(data.balance.toLocaleString()), 'tokens');
155
+ console.log();
156
+ console.log(chalk.dim('Total earned:'), data.totalEarned.toLocaleString());
157
+ console.log(chalk.dim('Total spent:'), data.totalSpent.toLocaleString());
158
+ }
159
+ catch (error) {
160
+ spinner.fail(chalk.red('Failed'));
161
+ console.error(error instanceof Error ? error.message : error);
162
+ process.exit(1);
163
+ }
164
+ });
165
+ // Default action - show help
166
+ program.action(() => {
167
+ console.log();
168
+ console.log(chalk.bold('NoLimit'));
169
+ console.log(chalk.dim('No subscription. Just code.'));
170
+ console.log();
171
+ program.outputHelp();
172
+ });
173
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@nolimitcli/cli",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "description": "No subscription. Just code. Watch an ad, build without limits.",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "nolimit": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsc -w",
13
+ "prepublishOnly": "npm run build"
14
+ },
15
+ "keywords": [
16
+ "ai",
17
+ "coding",
18
+ "free",
19
+ "tokens",
20
+ "cli",
21
+ "developer-tools"
22
+ ],
23
+ "author": "Buzzer Network",
24
+ "license": "MIT",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "https://github.com/anthropics/nolimit"
28
+ },
29
+ "engines": {
30
+ "node": ">=16"
31
+ },
32
+ "dependencies": {
33
+ "chalk": "^5.3.0",
34
+ "commander": "^12.0.0",
35
+ "conf": "^12.0.0",
36
+ "open": "^10.0.0",
37
+ "ora": "^8.0.0"
38
+ },
39
+ "devDependencies": {
40
+ "@types/node": "^20.0.0",
41
+ "typescript": "^5.0.0"
42
+ }
43
+ }