clawcloud 1.0.0 → 1.0.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.
package/index.js ADDED
@@ -0,0 +1,559 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * ClawCloud CLI - Decentralized Cloud Infrastructure for AI Agents
5
+ * Purchase and manage VMs with crypto on Base blockchain
6
+ *
7
+ * Usage: npx clawcloud [command] [options]
8
+ */
9
+
10
+ const { ethers } = require('ethers');
11
+ const readline = require('readline');
12
+ const fs = require('fs');
13
+ const os = require('os');
14
+ const path = require('path');
15
+
16
+ // ============================================================================
17
+ // PRODUCTION CONFIGURATION
18
+ // ============================================================================
19
+
20
+ const CONFIG = {
21
+ // Network
22
+ NETWORK: 'base',
23
+ RPC_URL: 'https://mainnet.base.org',
24
+ CHAIN_ID: 8453,
25
+
26
+ // Contracts
27
+ CONTRACT_ADDRESS: '0xF708741D37C420518852c6A15aB658066951c852',
28
+ USDC_ADDRESS: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
29
+
30
+ // API
31
+ API_URL: 'https://api.clawcloud.co',
32
+
33
+ // Explorer
34
+ EXPLORER_URL: 'https://basescan.org',
35
+
36
+ // Config file
37
+ CONFIG_FILE: path.join(os.homedir(), '.clawcloud', 'config.json')
38
+ };
39
+
40
+ // ============================================================================
41
+ // CONTRACT ABIs
42
+ // ============================================================================
43
+
44
+ const CONTRACT_ABI = [
45
+ "function purchaseVM(uint8 tier, uint16 durationDays) returns (uint256)",
46
+ "function getTierConfig(uint8 tier) view returns (uint256, bool, string)",
47
+ "function isTokenValid(uint256 tokenId) view returns (bool)",
48
+ "function ownerOf(uint256 tokenId) view returns (address)",
49
+ "function balanceOf(address owner) view returns (uint256)",
50
+ "function tokenOfOwnerByIndex(address owner, uint256 index) view returns (uint256)"
51
+ ];
52
+
53
+ const USDC_ABI = [
54
+ "function approve(address spender, uint256 amount) returns (bool)",
55
+ "function allowance(address owner, address spender) view returns (uint256)",
56
+ "function balanceOf(address account) view returns (uint256)"
57
+ ];
58
+
59
+ // ============================================================================
60
+ // UTILITIES
61
+ // ============================================================================
62
+
63
+ const rl = readline.createInterface({
64
+ input: process.stdin,
65
+ output: process.stdout
66
+ });
67
+
68
+ function question(query) {
69
+ return new Promise(resolve => rl.question(query, resolve));
70
+ }
71
+
72
+ function log(message, type = 'info') {
73
+ const symbols = {
74
+ info: 'šŸ¦ž',
75
+ success: 'āœ…',
76
+ error: 'āŒ',
77
+ warning: 'āš ļø',
78
+ loading: 'ā³'
79
+ };
80
+ console.log(`${symbols[type]} ${message}`);
81
+ }
82
+
83
+ function formatUSDC(amount) {
84
+ return ethers.formatUnits(amount, 6);
85
+ }
86
+
87
+ function parseUSDC(amount) {
88
+ return ethers.parseUnits(amount.toString(), 6);
89
+ }
90
+
91
+ // ============================================================================
92
+ // CONFIGURATION MANAGEMENT
93
+ // ============================================================================
94
+
95
+ function loadConfig() {
96
+ try {
97
+ if (fs.existsSync(CONFIG.CONFIG_FILE)) {
98
+ return JSON.parse(fs.readFileSync(CONFIG.CONFIG_FILE, 'utf8'));
99
+ }
100
+ } catch (error) {
101
+ // Config doesn't exist or is invalid
102
+ }
103
+ return {};
104
+ }
105
+
106
+ function saveConfig(config) {
107
+ const dir = path.dirname(CONFIG.CONFIG_FILE);
108
+ if (!fs.existsSync(dir)) {
109
+ fs.mkdirSync(dir, { recursive: true });
110
+ }
111
+ fs.writeFileSync(CONFIG.CONFIG_FILE, JSON.stringify(config, null, 2));
112
+ }
113
+
114
+ // ============================================================================
115
+ // WALLET SETUP
116
+ // ============================================================================
117
+
118
+ async function setupWallet() {
119
+ const config = loadConfig();
120
+
121
+ if (config.privateKey) {
122
+ const provider = new ethers.JsonRpcProvider(CONFIG.RPC_URL);
123
+ return new ethers.Wallet(config.privateKey, provider);
124
+ }
125
+
126
+ log('No wallet found. Let\'s set one up!', 'info');
127
+ console.log('\nOptions:');
128
+ console.log('1. Import existing private key');
129
+ console.log('2. Generate new wallet');
130
+
131
+ const choice = await question('\nChoose (1 or 2): ');
132
+
133
+ let wallet;
134
+ if (choice === '1') {
135
+ const privateKey = await question('Enter your private key: ');
136
+ const provider = new ethers.JsonRpcProvider(CONFIG.RPC_URL);
137
+ wallet = new ethers.Wallet(privateKey.trim(), provider);
138
+ } else {
139
+ const provider = new ethers.JsonRpcProvider(CONFIG.RPC_URL);
140
+ wallet = ethers.Wallet.createRandom(provider);
141
+ log(`New wallet created!`, 'success');
142
+ console.log(`Address: ${wallet.address}`);
143
+ console.log(`\nāš ļø SAVE THIS PRIVATE KEY SECURELY:`);
144
+ console.log(`${wallet.privateKey}\n`);
145
+ await question('Press Enter after saving your private key...');
146
+ }
147
+
148
+ const save = await question('Save wallet to config? (y/n): ');
149
+ if (save.toLowerCase() === 'y') {
150
+ saveConfig({ privateKey: wallet.privateKey });
151
+ log('Wallet saved!', 'success');
152
+ }
153
+
154
+ return wallet;
155
+ }
156
+
157
+ // ============================================================================
158
+ // COMMANDS
159
+ // ============================================================================
160
+
161
+ async function cmdTiers() {
162
+ try {
163
+ log('Fetching available VM tiers...', 'loading');
164
+
165
+ const response = await fetch(`${CONFIG.API_URL}/tiers`);
166
+ const data = await response.json();
167
+
168
+ console.log('\nšŸ“Š Available VM Tiers:\n');
169
+ console.log('ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”');
170
+ console.log('│ Tier │ Name │ Per Day │ Per Month │ Status │');
171
+ console.log('ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤');
172
+
173
+ for (const tier of data.tiers) {
174
+ const status = tier.active ? 'āœ…' : 'āŒ';
175
+ console.log(
176
+ `│ ${String(tier.tier).padEnd(4)} │ ${tier.name.padEnd(27)} │ $${tier.pricePerDay.padEnd(11)} │ $${tier.pricePerMonth.padEnd(12)} │ ${status} │`
177
+ );
178
+ }
179
+
180
+ console.log('ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜\n');
181
+
182
+ } catch (error) {
183
+ log(`Failed to fetch tiers: ${error.message}`, 'error');
184
+ }
185
+ }
186
+
187
+ async function cmdPurchase() {
188
+ try {
189
+ const wallet = await setupWallet();
190
+
191
+ log(`Wallet: ${wallet.address}`, 'info');
192
+
193
+ // Get tiers first
194
+ const response = await fetch(`${CONFIG.API_URL}/tiers`);
195
+ const { tiers } = await response.json();
196
+
197
+ // Show tiers
198
+ console.log('\nšŸ“Š Available Tiers:\n');
199
+ tiers.forEach(tier => {
200
+ if (tier.active) {
201
+ console.log(`${tier.tier}. ${tier.name} - $${tier.pricePerDay}/day ($${tier.pricePerMonth}/month)`);
202
+ }
203
+ });
204
+
205
+ // Get user input
206
+ const tierInput = await question('\nChoose tier (0-7): ');
207
+ const tier = parseInt(tierInput);
208
+
209
+ if (tier < 0 || tier > 7 || !tiers[tier].active) {
210
+ log('Invalid tier!', 'error');
211
+ return;
212
+ }
213
+
214
+ const daysInput = await question('Duration in days (3+ recommended): ');
215
+ const days = parseInt(daysInput);
216
+
217
+ if (days < 3) {
218
+ log('Minimum duration is 3 days!', 'error');
219
+ return;
220
+ }
221
+
222
+ // Calculate cost
223
+ const pricePerDay = parseUSDC(tiers[tier].pricePerDay);
224
+ const totalCost = pricePerDay * BigInt(days);
225
+
226
+ console.log(`\nšŸ’° Total cost: $${formatUSDC(totalCost)} USDC`);
227
+
228
+ const confirm = await question('Proceed with purchase? (y/n): ');
229
+ if (confirm.toLowerCase() !== 'y') {
230
+ log('Purchase cancelled', 'info');
231
+ return;
232
+ }
233
+
234
+ // Check USDC balance
235
+ log('Checking USDC balance...', 'loading');
236
+ const usdc = new ethers.Contract(CONFIG.USDC_ADDRESS, USDC_ABI, wallet);
237
+ const balance = await usdc.balanceOf(wallet.address);
238
+
239
+ if (balance < totalCost) {
240
+ log(`Insufficient USDC! You have $${formatUSDC(balance)}, need $${formatUSDC(totalCost)}`, 'error');
241
+ console.log(`\nBuy USDC on Base: https://app.uniswap.org/swap?chain=base`);
242
+ return;
243
+ }
244
+
245
+ log(`USDC balance: $${formatUSDC(balance)} āœ…`, 'success');
246
+
247
+ // Check approval
248
+ log('Checking USDC approval...', 'loading');
249
+ const contract = new ethers.Contract(CONFIG.CONTRACT_ADDRESS, CONTRACT_ABI, wallet);
250
+ const allowance = await usdc.allowance(wallet.address, CONFIG.CONTRACT_ADDRESS);
251
+
252
+ if (allowance < totalCost) {
253
+ log('Approving USDC...', 'loading');
254
+ const approveTx = await usdc.approve(CONFIG.CONTRACT_ADDRESS, totalCost);
255
+ log(`Approval tx: ${CONFIG.EXPLORER_URL}/tx/${approveTx.hash}`, 'info');
256
+ await approveTx.wait();
257
+ log('USDC approved!', 'success');
258
+ }
259
+
260
+ // Purchase VM
261
+ log('Purchasing VM...', 'loading');
262
+ const purchaseTx = await contract.purchaseVM(tier, days);
263
+ log(`Purchase tx: ${CONFIG.EXPLORER_URL}/tx/${purchaseTx.hash}`, 'info');
264
+
265
+ const receipt = await purchaseTx.wait();
266
+
267
+ // Get token ID from event
268
+ const iface = new ethers.Interface(CONTRACT_ABI);
269
+ const event = receipt.logs
270
+ .map(log => {
271
+ try {
272
+ return iface.parseLog(log);
273
+ } catch {
274
+ return null;
275
+ }
276
+ })
277
+ .find(e => e && e.name === 'VMPurchased');
278
+
279
+ const tokenId = event.args.tokenId;
280
+
281
+ log(`VM purchased successfully! šŸŽ‰`, 'success');
282
+ console.log(`\nToken ID: ${tokenId}`);
283
+ console.log(`Tier: ${tier}`);
284
+ console.log(`Duration: ${days} days`);
285
+ console.log(`\nā³ VM is provisioning... This takes 2-3 minutes.`);
286
+ console.log(`\nGet credentials: npx clawcloud get ${tokenId}`);
287
+
288
+ } catch (error) {
289
+ log(`Purchase failed: ${error.message}`, 'error');
290
+ if (error.message.includes('insufficient funds')) {
291
+ log('You need ETH on Base for gas fees!', 'warning');
292
+ console.log(`Bridge ETH: https://bridge.base.org`);
293
+ }
294
+ }
295
+ }
296
+
297
+ async function cmdGet(tokenId) {
298
+ try {
299
+ if (!tokenId) {
300
+ log('Usage: npx clawcloud get <tokenId>', 'error');
301
+ return;
302
+ }
303
+
304
+ const wallet = await setupWallet();
305
+
306
+ log(`Fetching credentials for VM #${tokenId}...`, 'loading');
307
+
308
+ // Sign authentication message
309
+ const message = `ClawCloud Access Request: ${tokenId}`;
310
+ const signature = await wallet.signMessage(message);
311
+
312
+ // Call API
313
+ const response = await fetch(
314
+ `${CONFIG.API_URL}/credentials/${tokenId}`,
315
+ {
316
+ headers: {
317
+ 'Authorization': `Bearer ${signature}`
318
+ }
319
+ }
320
+ );
321
+
322
+ const data = await response.json();
323
+
324
+ if (response.status === 202) {
325
+ log('VM is still provisioning...', 'warning');
326
+ console.log(`Status: ${data.status}`);
327
+ console.log(`Message: ${data.message}`);
328
+ console.log(`\nTry again in 2-3 minutes: npx clawcloud get ${tokenId}`);
329
+ return;
330
+ }
331
+
332
+ if (!response.ok) {
333
+ log(`Error: ${data.error || 'Failed to get credentials'}`, 'error');
334
+ return;
335
+ }
336
+
337
+ log('VM credentials retrieved!', 'success');
338
+ console.log('\n' + '='.repeat(70));
339
+ console.log(`šŸ–„ļø VM #${data.tokenId} - ${data.type.toUpperCase()}`);
340
+ console.log('='.repeat(70));
341
+ console.log(`Tier: ${data.tier}`);
342
+ console.log(`Host: ${data.host}`);
343
+ console.log(`Username: ${data.username}`);
344
+ console.log(`Expires: ${new Date(data.expiresAt).toLocaleString()}`);
345
+ console.log('\nšŸ“ SSH Command:');
346
+ console.log(` ${data.instructions}`);
347
+
348
+ if (data.privateKey) {
349
+ console.log('\nšŸ”‘ Private Key:');
350
+ console.log(` Save to file: echo "${data.privateKey}" > vm_${tokenId}.pem`);
351
+ console.log(` Then: chmod 600 vm_${tokenId}.pem`);
352
+ console.log(` Connect: ssh -i vm_${tokenId}.pem ${data.username}@${data.host}`);
353
+ }
354
+
355
+ console.log('='.repeat(70) + '\n');
356
+
357
+ } catch (error) {
358
+ log(`Failed to get credentials: ${error.message}`, 'error');
359
+ }
360
+ }
361
+
362
+ async function cmdList() {
363
+ try {
364
+ const wallet = await setupWallet();
365
+
366
+ log(`Fetching VMs for ${wallet.address}...`, 'loading');
367
+
368
+ const response = await fetch(`${CONFIG.API_URL}/vms/${wallet.address}`);
369
+ const data = await response.json();
370
+
371
+ if (data.count === 0) {
372
+ log('No VMs found!', 'info');
373
+ console.log('\nPurchase a VM: npx clawcloud purchase');
374
+ return;
375
+ }
376
+
377
+ log(`Found ${data.count} VM(s)`, 'success');
378
+ console.log('\n' + '='.repeat(90));
379
+ console.log('Your VMs:');
380
+ console.log('='.repeat(90));
381
+
382
+ for (const vm of data.vms) {
383
+ const status = vm.status === 'running' ? 'āœ…' :
384
+ vm.status === 'provisioning' ? 'ā³' :
385
+ vm.status === 'expired' ? 'ā°' : 'āŒ';
386
+
387
+ console.log(`\n${status} VM #${vm.token_id}`);
388
+ console.log(` Tier: ${vm.tier}`);
389
+ console.log(` Type: ${vm.vm_type}`);
390
+ console.log(` Host: ${vm.ssh_host}`);
391
+ console.log(` Status: ${vm.status}`);
392
+ console.log(` Created: ${new Date(vm.created_at).toLocaleString()}`);
393
+ console.log(` Expires: ${new Date(vm.expires_at).toLocaleString()}`);
394
+ console.log(` Access: npx clawcloud get ${vm.token_id}`);
395
+ }
396
+
397
+ console.log('\n' + '='.repeat(90) + '\n');
398
+
399
+ } catch (error) {
400
+ log(`Failed to list VMs: ${error.message}`, 'error');
401
+ }
402
+ }
403
+
404
+ async function cmdBalance() {
405
+ try {
406
+ const wallet = await setupWallet();
407
+
408
+ log('Checking balances...', 'loading');
409
+
410
+ const provider = wallet.provider;
411
+ const usdc = new ethers.Contract(CONFIG.USDC_ADDRESS, USDC_ABI, provider);
412
+
413
+ const ethBalance = await provider.getBalance(wallet.address);
414
+ const usdcBalance = await usdc.balanceOf(wallet.address);
415
+
416
+ console.log('\nšŸ’° Wallet Balances:');
417
+ console.log(` Address: ${wallet.address}`);
418
+ console.log(` ETH: ${ethers.formatEther(ethBalance)} ETH (for gas)`);
419
+ console.log(` USDC: $${formatUSDC(usdcBalance)} USDC`);
420
+
421
+ if (ethBalance === 0n) {
422
+ log('You need ETH for gas fees!', 'warning');
423
+ console.log(` Bridge ETH: https://bridge.base.org`);
424
+ }
425
+
426
+ if (usdcBalance === 0n) {
427
+ log('You need USDC to purchase VMs!', 'warning');
428
+ console.log(` Buy USDC: https://app.uniswap.org/swap?chain=base`);
429
+ }
430
+
431
+ console.log('');
432
+
433
+ } catch (error) {
434
+ log(`Failed to check balance: ${error.message}`, 'error');
435
+ }
436
+ }
437
+
438
+ async function cmdInfo() {
439
+ console.log('\nšŸ¦ž ClawCloud CLI\n');
440
+ console.log('Decentralized Cloud Infrastructure for AI Agents\n');
441
+ console.log('Network: Base Mainnet');
442
+ console.log(`Contract: ${CONFIG.CONTRACT_ADDRESS}`);
443
+ console.log(`USDC: ${CONFIG.USDC_ADDRESS}`);
444
+ console.log(`API: ${CONFIG.API_URL}`);
445
+ console.log(`Explorer: ${CONFIG.EXPLORER_URL}`);
446
+ console.log(`\nDocumentation: https://docs.clawcloud.co`);
447
+ console.log(`Chart: https://dexscreener.com/base/0xe8850bBc9c289c34e7C92C9572BE38f77D61cB07`);
448
+ console.log(`X: x.com/clawcloudx`);
449
+ console.log('');
450
+ }
451
+
452
+ async function cmdHelp() {
453
+ console.log('\nšŸ¦ž ClawCloud CLI - Commands\n');
454
+ console.log('PURCHASE & MANAGE:');
455
+ console.log(' npx clawcloud purchase Purchase a new VM');
456
+ console.log(' npx clawcloud get <tokenId> Get VM credentials');
457
+ console.log(' npx clawcloud list List your VMs');
458
+ console.log('');
459
+ console.log('INFORMATION:');
460
+ console.log(' npx clawcloud tiers Show available VM tiers');
461
+ console.log(' npx clawcloud balance Check wallet balance');
462
+ console.log(' npx clawcloud info Show contract/API info');
463
+ console.log('');
464
+ console.log('WALLET:');
465
+ console.log(' npx clawcloud wallet View/setup wallet');
466
+ console.log('');
467
+ console.log('HELP:');
468
+ console.log(' npx clawcloud help Show this help');
469
+ console.log('');
470
+ console.log('Examples:');
471
+ console.log(' npx clawcloud tiers');
472
+ console.log(' npx clawcloud purchase');
473
+ console.log(' npx clawcloud get 42');
474
+ console.log(' npx clawcloud list');
475
+ console.log('');
476
+ }
477
+
478
+ async function cmdWallet() {
479
+ const config = loadConfig();
480
+
481
+ if (config.privateKey) {
482
+ const provider = new ethers.JsonRpcProvider(CONFIG.RPC_URL);
483
+ const wallet = new ethers.Wallet(config.privateKey, provider);
484
+
485
+ console.log('\nšŸ’¼ Current Wallet:');
486
+ console.log(` Address: ${wallet.address}`);
487
+ console.log(` Network: Base Mainnet`);
488
+ console.log('');
489
+
490
+ const action = await question('Options: (b)alance, (c)hange wallet, (r)emove wallet, or Enter to exit: ');
491
+
492
+ if (action === 'b') {
493
+ await cmdBalance();
494
+ } else if (action === 'c') {
495
+ saveConfig({});
496
+ log('Wallet removed. Run any command to set up a new one.', 'success');
497
+ } else if (action === 'r') {
498
+ saveConfig({});
499
+ log('Wallet removed from config.', 'success');
500
+ }
501
+ } else {
502
+ await setupWallet();
503
+ }
504
+ }
505
+
506
+ // ============================================================================
507
+ // MAIN
508
+ // ============================================================================
509
+
510
+ async function main() {
511
+ const args = process.argv.slice(2);
512
+ const command = args[0] || 'help';
513
+
514
+ try {
515
+ switch (command) {
516
+ case 'tiers':
517
+ await cmdTiers();
518
+ break;
519
+ case 'purchase':
520
+ case 'buy':
521
+ await cmdPurchase();
522
+ break;
523
+ case 'get':
524
+ case 'credentials':
525
+ await cmdGet(args[1]);
526
+ break;
527
+ case 'list':
528
+ case 'ls':
529
+ await cmdList();
530
+ break;
531
+ case 'balance':
532
+ case 'bal':
533
+ await cmdBalance();
534
+ break;
535
+ case 'wallet':
536
+ await cmdWallet();
537
+ break;
538
+ case 'info':
539
+ await cmdInfo();
540
+ break;
541
+ case 'help':
542
+ case '--help':
543
+ case '-h':
544
+ await cmdHelp();
545
+ break;
546
+ default:
547
+ log(`Unknown command: ${command}`, 'error');
548
+ await cmdHelp();
549
+ }
550
+ } catch (error) {
551
+ log(`Error: ${error.message}`, 'error');
552
+ console.error(error);
553
+ } finally {
554
+ rl.close();
555
+ process.exit(0);
556
+ }
557
+ }
558
+
559
+ main();
package/package.json CHANGED
@@ -1,57 +1,40 @@
1
1
  {
2
2
  "name": "clawcloud",
3
- "version": "1.0.0",
4
- "description": "ā˜ļø Cloud infrastructure AI agents can own - CLI tool",
5
- "main": "bin/clawcloud.js",
6
- "type": "module",
3
+ "version": "1.0.1",
4
+ "description": "ClawCloud CLI - Decentralized cloud infrastructure for AI agents on Base",
5
+ "main": "index.js",
7
6
  "bin": {
8
- "clawcloud": "./bin/clawcloud.js"
7
+ "clawcloud": "./index.js"
9
8
  },
10
9
  "scripts": {
11
- "test": "echo \"Tests coming soon\"",
12
- "prepublishOnly": "chmod +x bin/clawcloud.js"
10
+ "test": "echo \"Error: no test specified\" && exit 1"
13
11
  },
14
12
  "keywords": [
15
- "ai",
16
- "agents",
17
- "cloud",
18
- "vm",
19
- "infrastructure",
20
- "autonomous",
21
13
  "blockchain",
22
14
  "base",
15
+ "cloud",
16
+ "vm",
17
+ "ai",
18
+ "agents",
19
+ "cryptocurrency",
23
20
  "nft",
24
- "openclaw",
25
- "depin"
21
+ "web3",
22
+ "cli"
26
23
  ],
27
24
  "author": "ClawCloud",
28
25
  "license": "MIT",
29
26
  "repository": {
30
27
  "type": "git",
31
- "url": "https://github.com/clawcloud/clawcloud.git",
32
- "directory": "cli"
28
+ "url": "https://github.com/clawcloud/clawcloud-cli.git"
33
29
  },
34
30
  "homepage": "https://clawcloud.co",
35
31
  "bugs": {
36
- "url": "https://github.com/clawcloud/clawcloud/issues"
37
- },
38
- "engines": {
39
- "node": ">=18.0.0"
32
+ "url": "https://github.com/clawcloud/clawcloud-cli/issues"
40
33
  },
41
34
  "dependencies": {
42
- "boxen": "^7.1.1",
43
- "chalk": "^5.3.0",
44
- "cli-table3": "^0.6.3",
45
- "commander": "^11.1.0",
46
- "ethers": "^6.10.0",
47
- "inquirer": "^9.2.12",
48
- "ora": "^7.0.1"
35
+ "ethers": "^6.9.0"
49
36
  },
50
- "files": [
51
- "bin/",
52
- "src/",
53
- "templates/",
54
- "README.md",
55
- "LICENSE"
56
- ]
37
+ "engines": {
38
+ "node": ">=18.0.0"
39
+ }
57
40
  }