pluribus-cli 0.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.
- package/bin/pluribus.js +120 -0
- package/package.json +24 -0
- package/src/commands/balance.js +50 -0
- package/src/commands/config.js +108 -0
- package/src/commands/deploy.js +58 -0
- package/src/commands/import.js +128 -0
- package/src/commands/init.js +220 -0
- package/src/commands/list.js +46 -0
- package/src/commands/logs.js +44 -0
- package/src/commands/register.js +101 -0
- package/src/commands/stake.js +85 -0
- package/src/commands/status.js +45 -0
- package/src/commands/submit.js +84 -0
- package/src/utils/banner.js +45 -0
package/bin/pluribus.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { program } from 'commander';
|
|
3
|
+
import { printBanner } from '../src/utils/banner.js';
|
|
4
|
+
import { importAgent } from '../src/commands/import.js';
|
|
5
|
+
import { registerAgent } from '../src/commands/register.js';
|
|
6
|
+
import { initAgent } from '../src/commands/init.js';
|
|
7
|
+
import { deployAgent } from '../src/commands/deploy.js';
|
|
8
|
+
import { listAgents } from '../src/commands/list.js';
|
|
9
|
+
import { networkStatus } from '../src/commands/status.js';
|
|
10
|
+
import { submitTask } from '../src/commands/submit.js';
|
|
11
|
+
import { stake, unstake } from '../src/commands/stake.js';
|
|
12
|
+
import { balance } from '../src/commands/balance.js';
|
|
13
|
+
import { logs } from '../src/commands/logs.js';
|
|
14
|
+
import { configCmd } from '../src/commands/config.js';
|
|
15
|
+
|
|
16
|
+
program
|
|
17
|
+
.name('pluribus')
|
|
18
|
+
.description('Pluribus CLI — Many Agents. One Mind.')
|
|
19
|
+
.version('0.1.0', '-v, --version', 'Show CLI version')
|
|
20
|
+
.addHelpText('beforeAll', () => {
|
|
21
|
+
printBanner();
|
|
22
|
+
return '';
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// ─── import ─────────────────────────────────────────────────────────────────
|
|
26
|
+
program
|
|
27
|
+
.command('import [agent-id]')
|
|
28
|
+
.description('Import an existing agent into the Pluribus network')
|
|
29
|
+
.option('-p, --platform <platform>', 'Agent framework (virtuals, eliza, langchain, etc.)')
|
|
30
|
+
.option('-s, --stake <amount>', '$PLUR to stake')
|
|
31
|
+
.action(importAgent);
|
|
32
|
+
|
|
33
|
+
// ─── register ───────────────────────────────────────────────────────────────
|
|
34
|
+
program
|
|
35
|
+
.command('register')
|
|
36
|
+
.description('Register a new agent and stake $PLUR to join the network')
|
|
37
|
+
.option('-n, --name <name>', 'Agent name')
|
|
38
|
+
.option('-e, --endpoint <url>', 'Webhook endpoint URL')
|
|
39
|
+
.action(registerAgent);
|
|
40
|
+
|
|
41
|
+
// ─── init ────────────────────────────────────────────────────────────────────
|
|
42
|
+
program
|
|
43
|
+
.command('init [name]')
|
|
44
|
+
.description('Scaffold a new Pluribus agent project')
|
|
45
|
+
.option('-t, --template <template>', 'Starter template (default, research, social, onchain)')
|
|
46
|
+
.action(initAgent);
|
|
47
|
+
|
|
48
|
+
// ─── deploy ──────────────────────────────────────────────────────────────────
|
|
49
|
+
program
|
|
50
|
+
.command('deploy')
|
|
51
|
+
.description('Deploy your agent to the Pluribus network')
|
|
52
|
+
.option('-c, --config <path>', 'Path to pluribus.config.json', 'pluribus.config.json')
|
|
53
|
+
.action(deployAgent);
|
|
54
|
+
|
|
55
|
+
// ─── list ─────────────────────────────────────────────────────────────────────
|
|
56
|
+
program
|
|
57
|
+
.command('list')
|
|
58
|
+
.alias('ls')
|
|
59
|
+
.description('List agents registered on the network')
|
|
60
|
+
.option('-t, --type <type>', 'Filter by capability type')
|
|
61
|
+
.option('--mine', 'Show only your registered agents')
|
|
62
|
+
.action(listAgents);
|
|
63
|
+
|
|
64
|
+
// ─── status ──────────────────────────────────────────────────────────────────
|
|
65
|
+
program
|
|
66
|
+
.command('status')
|
|
67
|
+
.description('Show Pluribus network and protocol status')
|
|
68
|
+
.action(networkStatus);
|
|
69
|
+
|
|
70
|
+
// ─── submit ──────────────────────────────────────────────────────────────────
|
|
71
|
+
program
|
|
72
|
+
.command('submit [task]')
|
|
73
|
+
.description('Submit a task to the Pluribus agent network')
|
|
74
|
+
.option('-t, --type <type>', 'Task type (research, social, monitoring, onchain, auto)')
|
|
75
|
+
.option('-p, --plur <amount>', '$PLUR payment for the task', '0.5')
|
|
76
|
+
.action(submitTask);
|
|
77
|
+
|
|
78
|
+
// ─── stake ───────────────────────────────────────────────────────────────────
|
|
79
|
+
program
|
|
80
|
+
.command('stake [amount]')
|
|
81
|
+
.description('Stake $PLUR to earn yield from network task fees')
|
|
82
|
+
.option('-w, --wallet <address>', 'Wallet address')
|
|
83
|
+
.option('--tier <tier>', 'Staking tier (sentinel, archon, sovereign)')
|
|
84
|
+
.action(stake);
|
|
85
|
+
|
|
86
|
+
// ─── unstake ─────────────────────────────────────────────────────────────────
|
|
87
|
+
program
|
|
88
|
+
.command('unstake [amount]')
|
|
89
|
+
.description('Unstake $PLUR from the network')
|
|
90
|
+
.option('-w, --wallet <address>', 'Wallet address')
|
|
91
|
+
.action(unstake);
|
|
92
|
+
|
|
93
|
+
// ─── balance ─────────────────────────────────────────────────────────────────
|
|
94
|
+
program
|
|
95
|
+
.command('balance [address]')
|
|
96
|
+
.description('Check $PLUR balance for a wallet address')
|
|
97
|
+
.action(balance);
|
|
98
|
+
|
|
99
|
+
// ─── logs ─────────────────────────────────────────────────────────────────────
|
|
100
|
+
program
|
|
101
|
+
.command('logs [agent-id]')
|
|
102
|
+
.description('Stream live logs from an agent or task')
|
|
103
|
+
.option('-f, --follow', 'Follow log output in real time')
|
|
104
|
+
.option('-n, --lines <n>', 'Number of recent lines to show', '50')
|
|
105
|
+
.action(logs);
|
|
106
|
+
|
|
107
|
+
// ─── config ───────────────────────────────────────────────────────────────────
|
|
108
|
+
program
|
|
109
|
+
.command('config [action]')
|
|
110
|
+
.description('Manage CLI configuration (show | set | reset)')
|
|
111
|
+
.action(configCmd);
|
|
112
|
+
|
|
113
|
+
// Default: show banner + help if no command
|
|
114
|
+
if (process.argv.length === 2) {
|
|
115
|
+
printBanner();
|
|
116
|
+
program.outputHelp();
|
|
117
|
+
process.exit(0);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
program.parse();
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pluribus-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Pluribus CLI — Register, manage, and deploy AI agents on the Pluribus multi-agent coordination protocol",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"pluribus": "./bin/pluribus.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "node bin/pluribus.js"
|
|
11
|
+
},
|
|
12
|
+
"keywords": ["pluribus", "ai", "agents", "base", "web3", "cli", "multi-agent"],
|
|
13
|
+
"author": "Pluribus Protocol",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"chalk": "^5.6.2",
|
|
17
|
+
"commander": "^14.0.3",
|
|
18
|
+
"inquirer": "^13.3.0",
|
|
19
|
+
"ora": "^9.3.0"
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=18.0.0"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { label, printDivider, info, warn } from '../utils/banner.js';
|
|
4
|
+
|
|
5
|
+
function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
|
|
6
|
+
|
|
7
|
+
export async function balance(address, options) {
|
|
8
|
+
const inquirer = (await import('inquirer')).default;
|
|
9
|
+
|
|
10
|
+
console.log('');
|
|
11
|
+
console.log(chalk.cyan.bold(' → $PLUR Balance'));
|
|
12
|
+
console.log('');
|
|
13
|
+
|
|
14
|
+
if (!address) {
|
|
15
|
+
const answers = await inquirer.prompt([
|
|
16
|
+
{
|
|
17
|
+
type: 'input',
|
|
18
|
+
name: 'address',
|
|
19
|
+
message: chalk.white('Wallet address (0x...):'),
|
|
20
|
+
prefix: chalk.cyan(' ▸'),
|
|
21
|
+
validate: v => v.startsWith('0x') && v.length === 42 ? true : 'Enter a valid Ethereum address',
|
|
22
|
+
},
|
|
23
|
+
]);
|
|
24
|
+
address = answers.address;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
console.log('');
|
|
28
|
+
const spinner = ora({ text: chalk.dim('Querying Base network...'), spinner: 'dots', color: 'cyan' }).start();
|
|
29
|
+
await sleep(900);
|
|
30
|
+
spinner.succeed(chalk.green('Balance retrieved'));
|
|
31
|
+
|
|
32
|
+
console.log('');
|
|
33
|
+
console.log(chalk.cyan.bold(' Wallet'));
|
|
34
|
+
printDivider();
|
|
35
|
+
label('Address:', address);
|
|
36
|
+
label('Network:', 'Base Mainnet');
|
|
37
|
+
console.log('');
|
|
38
|
+
|
|
39
|
+
console.log(chalk.cyan.bold(' $PLUR Balance'));
|
|
40
|
+
printDivider();
|
|
41
|
+
label('Available:', chalk.cyan('— (token not yet launched)'));
|
|
42
|
+
label('Staked:', chalk.cyan('—'));
|
|
43
|
+
label('Earned:', chalk.cyan('—'));
|
|
44
|
+
label('Total:', chalk.cyan('—'));
|
|
45
|
+
console.log('');
|
|
46
|
+
|
|
47
|
+
warn('$PLUR launches with the Pluribus network. Stay tuned.');
|
|
48
|
+
info(`Track launch: ${chalk.underline('https://pluribus.xyz')}`);
|
|
49
|
+
console.log('');
|
|
50
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { label, printDivider, info, success } from '../utils/banner.js';
|
|
7
|
+
|
|
8
|
+
function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
|
|
9
|
+
|
|
10
|
+
const CONFIG_PATH = path.join(os.homedir(), '.pluribus', 'config.json');
|
|
11
|
+
|
|
12
|
+
function loadConfig() {
|
|
13
|
+
try {
|
|
14
|
+
return JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8'));
|
|
15
|
+
} catch {
|
|
16
|
+
return {
|
|
17
|
+
rpcUrl: 'https://mainnet.base.org',
|
|
18
|
+
wallet: '',
|
|
19
|
+
apiKey: '',
|
|
20
|
+
network: 'base-mainnet',
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function saveConfig(cfg) {
|
|
26
|
+
fs.mkdirSync(path.dirname(CONFIG_PATH), { recursive: true });
|
|
27
|
+
fs.writeFileSync(CONFIG_PATH, JSON.stringify(cfg, null, 2));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export async function configCmd(action, options) {
|
|
31
|
+
const inquirer = (await import('inquirer')).default;
|
|
32
|
+
|
|
33
|
+
console.log('');
|
|
34
|
+
console.log(chalk.cyan.bold(' → CLI Configuration'));
|
|
35
|
+
console.log('');
|
|
36
|
+
|
|
37
|
+
const cfg = loadConfig();
|
|
38
|
+
|
|
39
|
+
if (action === 'show' || !action) {
|
|
40
|
+
console.log(chalk.cyan.bold(' Current Configuration'));
|
|
41
|
+
printDivider();
|
|
42
|
+
label('Config file:', CONFIG_PATH);
|
|
43
|
+
label('Network:', cfg.network || 'base-mainnet');
|
|
44
|
+
label('RPC URL:', cfg.rpcUrl || chalk.dim('not set'));
|
|
45
|
+
label('Wallet:', cfg.wallet || chalk.dim('not set'));
|
|
46
|
+
label('API Key:', cfg.apiKey ? chalk.green('● set') : chalk.dim('not set'));
|
|
47
|
+
console.log('');
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (action === 'set') {
|
|
52
|
+
const answers = await inquirer.prompt([
|
|
53
|
+
{
|
|
54
|
+
type: 'list',
|
|
55
|
+
name: 'network',
|
|
56
|
+
message: chalk.white('Network:'),
|
|
57
|
+
prefix: chalk.cyan(' ▸'),
|
|
58
|
+
choices: [
|
|
59
|
+
{ name: 'Base Mainnet', value: 'base-mainnet' },
|
|
60
|
+
{ name: 'Base Sepolia (testnet)', value: 'base-sepolia' },
|
|
61
|
+
],
|
|
62
|
+
default: cfg.network,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
type: 'input',
|
|
66
|
+
name: 'rpcUrl',
|
|
67
|
+
message: chalk.white('RPC URL:'),
|
|
68
|
+
prefix: chalk.cyan(' ▸'),
|
|
69
|
+
default: cfg.rpcUrl || 'https://mainnet.base.org',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
type: 'input',
|
|
73
|
+
name: 'wallet',
|
|
74
|
+
message: chalk.white('Default wallet address (0x...):'),
|
|
75
|
+
prefix: chalk.cyan(' ▸'),
|
|
76
|
+
default: cfg.wallet,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
type: 'password',
|
|
80
|
+
name: 'apiKey',
|
|
81
|
+
message: chalk.white('Pluribus API key (leave blank to skip):'),
|
|
82
|
+
prefix: chalk.cyan(' ▸'),
|
|
83
|
+
mask: '●',
|
|
84
|
+
},
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
const newCfg = {
|
|
88
|
+
network: answers.network,
|
|
89
|
+
rpcUrl: answers.rpcUrl,
|
|
90
|
+
wallet: answers.wallet,
|
|
91
|
+
apiKey: answers.apiKey || cfg.apiKey,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const spinner = ora({ text: chalk.dim('Saving configuration...'), spinner: 'dots', color: 'cyan' }).start();
|
|
95
|
+
await sleep(400);
|
|
96
|
+
saveConfig(newCfg);
|
|
97
|
+
spinner.succeed(chalk.green('Configuration saved'));
|
|
98
|
+
console.log('');
|
|
99
|
+
label('Saved to:', CONFIG_PATH);
|
|
100
|
+
console.log('');
|
|
101
|
+
|
|
102
|
+
} else if (action === 'reset') {
|
|
103
|
+
const defaultCfg = { rpcUrl: 'https://mainnet.base.org', wallet: '', apiKey: '', network: 'base-mainnet' };
|
|
104
|
+
saveConfig(defaultCfg);
|
|
105
|
+
success('Configuration reset to defaults.');
|
|
106
|
+
console.log('');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import { label, printDivider, warn, info, success, error } from '../utils/banner.js';
|
|
5
|
+
|
|
6
|
+
function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
|
|
7
|
+
|
|
8
|
+
export async function deployAgent(options) {
|
|
9
|
+
console.log('');
|
|
10
|
+
console.log(chalk.cyan.bold(' → Deploy Agent'));
|
|
11
|
+
console.log(chalk.dim(' Deploy your agent to the Pluribus network'));
|
|
12
|
+
console.log('');
|
|
13
|
+
|
|
14
|
+
// Check for pluribus.config.json
|
|
15
|
+
if (!fs.existsSync('pluribus.config.json')) {
|
|
16
|
+
error('No pluribus.config.json found in current directory.');
|
|
17
|
+
info(`Run ${chalk.cyan('pluribus init')} to scaffold a new agent, or navigate to your agent directory.`);
|
|
18
|
+
console.log('');
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let config;
|
|
23
|
+
try {
|
|
24
|
+
config = JSON.parse(fs.readFileSync('pluribus.config.json', 'utf8'));
|
|
25
|
+
} catch {
|
|
26
|
+
error('Invalid pluribus.config.json — check JSON syntax.');
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
console.log(chalk.cyan.bold(' Deployment Config'));
|
|
31
|
+
printDivider();
|
|
32
|
+
label('Agent Name:', config.name || '—');
|
|
33
|
+
label('Version:', config.version || '0.1.0');
|
|
34
|
+
label('Capabilities:', (config.capabilities || []).join(', '));
|
|
35
|
+
label('Endpoint:', config.endpoint || '—');
|
|
36
|
+
label('Network:', config.network || 'base-mainnet');
|
|
37
|
+
label('Stake Tier:', config.stake?.tier || '—');
|
|
38
|
+
console.log('');
|
|
39
|
+
|
|
40
|
+
const spinner = ora({ text: chalk.dim('Validating configuration...'), spinner: 'dots', color: 'cyan' }).start();
|
|
41
|
+
await sleep(700);
|
|
42
|
+
spinner.text = chalk.dim('Checking endpoint health...');
|
|
43
|
+
await sleep(600);
|
|
44
|
+
spinner.text = chalk.dim('Verifying stake requirements...');
|
|
45
|
+
await sleep(500);
|
|
46
|
+
spinner.text = chalk.dim('Staging on-chain deployment...');
|
|
47
|
+
await sleep(800);
|
|
48
|
+
spinner.succeed(chalk.green('Deployment staged'));
|
|
49
|
+
|
|
50
|
+
console.log('');
|
|
51
|
+
label('Status:', chalk.yellow('Staged — pending network launch'));
|
|
52
|
+
label('Estimated Launch:', chalk.cyan('Soon™'));
|
|
53
|
+
console.log('');
|
|
54
|
+
|
|
55
|
+
warn('Deployment will execute when the Pluribus network goes live on Base.');
|
|
56
|
+
info(`Monitor status: ${chalk.cyan('pluribus status')}`);
|
|
57
|
+
console.log('');
|
|
58
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { createRequire } from 'module';
|
|
4
|
+
import { success, error, info, warn, label, printDivider } from '../utils/banner.js';
|
|
5
|
+
|
|
6
|
+
export async function importAgent(agentId, options) {
|
|
7
|
+
const { select, input, confirm } = await import('@inquirer/prompts').catch(() => {
|
|
8
|
+
return import('inquirer').then(m => m.default.prompt ? { select: null, input: null, confirm: null } : {});
|
|
9
|
+
}).catch(() => ({ select: null, input: null, confirm: null }));
|
|
10
|
+
|
|
11
|
+
console.log('');
|
|
12
|
+
console.log(chalk.cyan.bold(' → Import Agent into Pluribus'));
|
|
13
|
+
console.log(chalk.dim(' Connect an existing agent to the network'));
|
|
14
|
+
console.log('');
|
|
15
|
+
|
|
16
|
+
if (!agentId) {
|
|
17
|
+
// Interactive mode
|
|
18
|
+
const inquirer = (await import('inquirer')).default;
|
|
19
|
+
|
|
20
|
+
const answers = await inquirer.prompt([
|
|
21
|
+
{
|
|
22
|
+
type: 'input',
|
|
23
|
+
name: 'agentId',
|
|
24
|
+
message: chalk.white('Agent ID or endpoint URL:'),
|
|
25
|
+
prefix: chalk.cyan(' ▸'),
|
|
26
|
+
validate: v => v.length > 0 ? true : 'Agent ID is required',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
type: 'list',
|
|
30
|
+
name: 'platform',
|
|
31
|
+
message: chalk.white('Agent framework:'),
|
|
32
|
+
prefix: chalk.cyan(' ▸'),
|
|
33
|
+
choices: [
|
|
34
|
+
{ name: 'Virtuals Protocol', value: 'virtuals' },
|
|
35
|
+
{ name: 'ElizaOS', value: 'eliza' },
|
|
36
|
+
{ name: 'LangChain', value: 'langchain' },
|
|
37
|
+
{ name: 'AutoGPT', value: 'autogpt' },
|
|
38
|
+
{ name: 'CrewAI', value: 'crewai' },
|
|
39
|
+
{ name: 'Custom / Other', value: 'custom' },
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
type: 'checkbox',
|
|
44
|
+
name: 'capabilities',
|
|
45
|
+
message: chalk.white('Declare capabilities:'),
|
|
46
|
+
prefix: chalk.cyan(' ▸'),
|
|
47
|
+
choices: [
|
|
48
|
+
{ name: 'Research & Analysis', value: 'research' },
|
|
49
|
+
{ name: 'Social Media', value: 'social' },
|
|
50
|
+
{ name: 'Onchain Execution', value: 'onchain' },
|
|
51
|
+
{ name: 'Wallet Monitoring', value: 'monitoring' },
|
|
52
|
+
{ name: 'Content Generation', value: 'content' },
|
|
53
|
+
{ name: 'Data Retrieval', value: 'data' },
|
|
54
|
+
],
|
|
55
|
+
validate: v => v.length > 0 ? true : 'Select at least one capability',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
type: 'input',
|
|
59
|
+
name: 'stakeAmount',
|
|
60
|
+
message: chalk.white('$PLUR to stake (minimum required to join):'),
|
|
61
|
+
prefix: chalk.cyan(' ▸'),
|
|
62
|
+
default: '1000',
|
|
63
|
+
validate: v => !isNaN(Number(v)) && Number(v) > 0 ? true : 'Enter a valid amount',
|
|
64
|
+
},
|
|
65
|
+
]);
|
|
66
|
+
|
|
67
|
+
agentId = answers.agentId;
|
|
68
|
+
|
|
69
|
+
console.log('');
|
|
70
|
+
printDivider();
|
|
71
|
+
console.log('');
|
|
72
|
+
|
|
73
|
+
const spinner = ora({
|
|
74
|
+
text: chalk.dim('Verifying agent endpoint...'),
|
|
75
|
+
spinner: 'dots',
|
|
76
|
+
color: 'cyan',
|
|
77
|
+
}).start();
|
|
78
|
+
|
|
79
|
+
await sleep(1200);
|
|
80
|
+
spinner.text = chalk.dim('Checking stake requirements...');
|
|
81
|
+
await sleep(800);
|
|
82
|
+
spinner.text = chalk.dim('Validating capabilities...');
|
|
83
|
+
await sleep(700);
|
|
84
|
+
spinner.succeed(chalk.green('Agent verified'));
|
|
85
|
+
|
|
86
|
+
console.log('');
|
|
87
|
+
console.log(chalk.cyan.bold(' Registration Preview'));
|
|
88
|
+
printDivider();
|
|
89
|
+
label('Agent ID:', agentId);
|
|
90
|
+
label('Platform:', answers.platform);
|
|
91
|
+
label('Capabilities:', answers.capabilities.join(', '));
|
|
92
|
+
label('Stake Amount:', `${Number(answers.stakeAmount).toLocaleString()} $PLUR`);
|
|
93
|
+
label('Status:', chalk.yellow('Pending — awaiting mainnet launch'));
|
|
94
|
+
console.log('');
|
|
95
|
+
|
|
96
|
+
warn('Mainnet launch is coming soon. Your agent config has been saved locally.');
|
|
97
|
+
info('Run ' + chalk.cyan('pluribus list') + ' to view your staged agents.');
|
|
98
|
+
info('Run ' + chalk.cyan('pluribus deploy') + ' once the network is live.');
|
|
99
|
+
console.log('');
|
|
100
|
+
|
|
101
|
+
} else {
|
|
102
|
+
// Direct import with ID
|
|
103
|
+
const spinner = ora({
|
|
104
|
+
text: chalk.dim(`Importing agent ${chalk.cyan(agentId)}...`),
|
|
105
|
+
spinner: 'dots',
|
|
106
|
+
color: 'cyan',
|
|
107
|
+
}).start();
|
|
108
|
+
|
|
109
|
+
await sleep(900);
|
|
110
|
+
spinner.text = chalk.dim('Resolving agent metadata...');
|
|
111
|
+
await sleep(700);
|
|
112
|
+
spinner.text = chalk.dim('Staging registration...');
|
|
113
|
+
await sleep(600);
|
|
114
|
+
spinner.succeed(chalk.green(`Agent ${chalk.cyan(agentId)} staged for import`));
|
|
115
|
+
|
|
116
|
+
console.log('');
|
|
117
|
+
label('Agent ID:', agentId);
|
|
118
|
+
label('Network:', 'Base (Mainnet)');
|
|
119
|
+
label('Status:', chalk.yellow('Staged — deploy when network launches'));
|
|
120
|
+
console.log('');
|
|
121
|
+
info(`Run ${chalk.cyan('pluribus deploy')} once the Pluribus network goes live.`);
|
|
122
|
+
console.log('');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function sleep(ms) {
|
|
127
|
+
return new Promise(r => setTimeout(r, ms));
|
|
128
|
+
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { success, info, warn, label, printDivider } from '../utils/banner.js';
|
|
6
|
+
|
|
7
|
+
function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
|
|
8
|
+
|
|
9
|
+
const AGENT_TEMPLATE = (name, capabilities) => `import { PluribusAgent } from '@pluribus/agent-sdk';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* ${name} — Pluribus Agent
|
|
13
|
+
* Capabilities: ${capabilities.join(', ')}
|
|
14
|
+
*
|
|
15
|
+
* Docs: https://pluribus.xyz/docs/sdk
|
|
16
|
+
*/
|
|
17
|
+
const agent = new PluribusAgent({
|
|
18
|
+
name: '${name}',
|
|
19
|
+
capabilities: ${JSON.stringify(capabilities)},
|
|
20
|
+
version: '0.1.0',
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// Handle incoming tasks routed by the Pluribus orchestrator
|
|
24
|
+
agent.on('task', async (task) => {
|
|
25
|
+
const { id, type, payload, respond } = task;
|
|
26
|
+
|
|
27
|
+
console.log(\`Received task \${id} of type \${type}\`);
|
|
28
|
+
|
|
29
|
+
// TODO: Implement your agent logic here
|
|
30
|
+
const result = await processTask(type, payload);
|
|
31
|
+
|
|
32
|
+
await respond({
|
|
33
|
+
taskId: id,
|
|
34
|
+
result,
|
|
35
|
+
confidence: 0.95,
|
|
36
|
+
metadata: {
|
|
37
|
+
processingTime: Date.now(),
|
|
38
|
+
agentVersion: agent.version,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
async function processTask(type, payload) {
|
|
44
|
+
// Add your agent logic here
|
|
45
|
+
switch (type) {
|
|
46
|
+
case 'research':
|
|
47
|
+
return { summary: 'Research result placeholder', sources: [] };
|
|
48
|
+
case 'social':
|
|
49
|
+
return { content: 'Generated content placeholder', platform: payload.platform };
|
|
50
|
+
default:
|
|
51
|
+
throw new Error(\`Unsupported task type: \${type}\`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
agent.start().then(() => {
|
|
56
|
+
console.log(\`Agent "${name}" is live and listening for tasks\`);
|
|
57
|
+
});
|
|
58
|
+
`;
|
|
59
|
+
|
|
60
|
+
const PLURIBUS_CONFIG = (name, capabilities) => JSON.stringify({
|
|
61
|
+
name,
|
|
62
|
+
version: '0.1.0',
|
|
63
|
+
capabilities,
|
|
64
|
+
endpoint: 'https://your-agent-endpoint.com/webhook',
|
|
65
|
+
network: 'base-mainnet',
|
|
66
|
+
stake: {
|
|
67
|
+
tier: 'sentinel',
|
|
68
|
+
amount: 1000,
|
|
69
|
+
},
|
|
70
|
+
metadata: {
|
|
71
|
+
description: `${name} — Pluribus agent`,
|
|
72
|
+
framework: 'custom',
|
|
73
|
+
created: new Date().toISOString(),
|
|
74
|
+
},
|
|
75
|
+
}, null, 2);
|
|
76
|
+
|
|
77
|
+
const DOCKERFILE = (name) => `FROM node:20-alpine
|
|
78
|
+
|
|
79
|
+
WORKDIR /app
|
|
80
|
+
COPY package*.json ./
|
|
81
|
+
RUN npm ci --production
|
|
82
|
+
COPY . .
|
|
83
|
+
|
|
84
|
+
EXPOSE 3000
|
|
85
|
+
|
|
86
|
+
ENV NODE_ENV=production
|
|
87
|
+
ENV AGENT_NAME="${name}"
|
|
88
|
+
|
|
89
|
+
CMD ["node", "agent.js"]
|
|
90
|
+
`;
|
|
91
|
+
|
|
92
|
+
const PACKAGE_JSON = (name) => JSON.stringify({
|
|
93
|
+
name: name.toLowerCase().replace(/\s+/g, '-'),
|
|
94
|
+
version: '0.1.0',
|
|
95
|
+
type: 'module',
|
|
96
|
+
main: 'agent.js',
|
|
97
|
+
scripts: {
|
|
98
|
+
start: 'node agent.js',
|
|
99
|
+
dev: 'node --watch agent.js',
|
|
100
|
+
test: 'node --test',
|
|
101
|
+
},
|
|
102
|
+
dependencies: {
|
|
103
|
+
'@pluribus/agent-sdk': '^0.1.0',
|
|
104
|
+
},
|
|
105
|
+
}, null, 2);
|
|
106
|
+
|
|
107
|
+
const README = (name) => `# ${name}
|
|
108
|
+
|
|
109
|
+
A Pluribus agent for the multi-agent coordination protocol on Base.
|
|
110
|
+
|
|
111
|
+
## Setup
|
|
112
|
+
|
|
113
|
+
\`\`\`bash
|
|
114
|
+
npm install
|
|
115
|
+
npm run dev
|
|
116
|
+
\`\`\`
|
|
117
|
+
|
|
118
|
+
## Deploy
|
|
119
|
+
|
|
120
|
+
\`\`\`bash
|
|
121
|
+
npx pluribus deploy
|
|
122
|
+
\`\`\`
|
|
123
|
+
|
|
124
|
+
## Configuration
|
|
125
|
+
|
|
126
|
+
Edit \`pluribus.config.json\` to configure your agent's capabilities, stake tier, and endpoint.
|
|
127
|
+
|
|
128
|
+
## Docs
|
|
129
|
+
|
|
130
|
+
https://pluribus.xyz/docs/sdk
|
|
131
|
+
`;
|
|
132
|
+
|
|
133
|
+
export async function initAgent(name, options) {
|
|
134
|
+
const inquirer = (await import('inquirer')).default;
|
|
135
|
+
|
|
136
|
+
console.log('');
|
|
137
|
+
console.log(chalk.cyan.bold(' → Initialize New Agent Project'));
|
|
138
|
+
console.log(chalk.dim(' Scaffold a production-ready Pluribus agent'));
|
|
139
|
+
console.log('');
|
|
140
|
+
|
|
141
|
+
let agentName = name;
|
|
142
|
+
let capabilities;
|
|
143
|
+
let dir;
|
|
144
|
+
|
|
145
|
+
if (!agentName) {
|
|
146
|
+
const answers = await inquirer.prompt([
|
|
147
|
+
{
|
|
148
|
+
type: 'input',
|
|
149
|
+
name: 'name',
|
|
150
|
+
message: chalk.white('Agent name:'),
|
|
151
|
+
prefix: chalk.cyan(' ▸'),
|
|
152
|
+
validate: v => v.length >= 2 ? true : 'Name must be at least 2 characters',
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
type: 'checkbox',
|
|
156
|
+
name: 'capabilities',
|
|
157
|
+
message: chalk.white('Capabilities this agent will handle:'),
|
|
158
|
+
prefix: chalk.cyan(' ▸'),
|
|
159
|
+
choices: [
|
|
160
|
+
{ name: 'research — Market analysis, risk scoring', value: 'research', checked: true },
|
|
161
|
+
{ name: 'social — Content, posting, engagement', value: 'social' },
|
|
162
|
+
{ name: 'onchain — DeFi, swaps, bridge ops', value: 'onchain' },
|
|
163
|
+
{ name: 'monitoring — Wallets, TXs, alerts', value: 'monitoring' },
|
|
164
|
+
{ name: 'data — APIs, retrieval', value: 'data' },
|
|
165
|
+
{ name: 'content — Writing, summarization', value: 'content' },
|
|
166
|
+
],
|
|
167
|
+
validate: v => v.length > 0 ? true : 'Select at least one capability',
|
|
168
|
+
},
|
|
169
|
+
]);
|
|
170
|
+
agentName = answers.name;
|
|
171
|
+
capabilities = answers.capabilities;
|
|
172
|
+
} else {
|
|
173
|
+
capabilities = ['research'];
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
dir = agentName.toLowerCase().replace(/\s+/g, '-');
|
|
177
|
+
|
|
178
|
+
console.log('');
|
|
179
|
+
printDivider();
|
|
180
|
+
console.log('');
|
|
181
|
+
|
|
182
|
+
const spinner = ora({ text: chalk.dim(`Scaffolding agent project in ./${dir}/`), spinner: 'dots', color: 'cyan' }).start();
|
|
183
|
+
|
|
184
|
+
await sleep(400);
|
|
185
|
+
|
|
186
|
+
// Create directory
|
|
187
|
+
if (!fs.existsSync(dir)) {
|
|
188
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Write files
|
|
192
|
+
fs.writeFileSync(path.join(dir, 'agent.js'), AGENT_TEMPLATE(agentName, capabilities));
|
|
193
|
+
fs.writeFileSync(path.join(dir, 'package.json'), PACKAGE_JSON(agentName));
|
|
194
|
+
fs.writeFileSync(path.join(dir, 'pluribus.config.json'), PLURIBUS_CONFIG(agentName, capabilities));
|
|
195
|
+
fs.writeFileSync(path.join(dir, 'Dockerfile'), DOCKERFILE(agentName));
|
|
196
|
+
fs.writeFileSync(path.join(dir, 'README.md'), README(agentName));
|
|
197
|
+
fs.writeFileSync(path.join(dir, '.gitignore'), 'node_modules/\n.env\n*.log\n');
|
|
198
|
+
fs.writeFileSync(path.join(dir, '.env.example'), 'PLURIBUS_API_KEY=\nAGENT_WEBHOOK_SECRET=\nRPC_URL=https://mainnet.base.org\n');
|
|
199
|
+
|
|
200
|
+
await sleep(600);
|
|
201
|
+
spinner.succeed(chalk.green(`Agent project created at ${chalk.cyan('./' + dir + '/')}`));
|
|
202
|
+
|
|
203
|
+
console.log('');
|
|
204
|
+
console.log(chalk.cyan.bold(' Files created:'));
|
|
205
|
+
printDivider();
|
|
206
|
+
const files = ['agent.js', 'package.json', 'pluribus.config.json', 'Dockerfile', 'README.md', '.gitignore', '.env.example'];
|
|
207
|
+
files.forEach(f => console.log(` ${chalk.dim('+')} ${chalk.white(path.join(dir, f))}`));
|
|
208
|
+
console.log('');
|
|
209
|
+
|
|
210
|
+
console.log(chalk.cyan.bold(' Next steps:'));
|
|
211
|
+
printDivider();
|
|
212
|
+
console.log(` ${chalk.dim('1.')} ${chalk.white(`cd ${dir}`)}`);
|
|
213
|
+
console.log(` ${chalk.dim('2.')} ${chalk.white('npm install')}`);
|
|
214
|
+
console.log(` ${chalk.dim('3.')} ${chalk.white('npm run dev')} ${chalk.dim('# develop locally')}`);
|
|
215
|
+
console.log(` ${chalk.dim('4.')} ${chalk.white('npx pluribus register')} ${chalk.dim('# register when network launches')}`);
|
|
216
|
+
console.log(` ${chalk.dim('5.')} ${chalk.white('npx pluribus deploy')} ${chalk.dim('# deploy to Pluribus network')}`);
|
|
217
|
+
console.log('');
|
|
218
|
+
info(`Docs: ${chalk.underline('https://pluribus.xyz/sdk')}`);
|
|
219
|
+
console.log('');
|
|
220
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { label, printDivider, info, warn } from '../utils/banner.js';
|
|
4
|
+
|
|
5
|
+
function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
|
|
6
|
+
|
|
7
|
+
export async function listAgents(options) {
|
|
8
|
+
console.log('');
|
|
9
|
+
console.log(chalk.cyan.bold(' → Agent Registry'));
|
|
10
|
+
console.log(chalk.dim(' Browse agents registered on the Pluribus network'));
|
|
11
|
+
console.log('');
|
|
12
|
+
|
|
13
|
+
const spinner = ora({ text: chalk.dim('Querying agent registry...'), spinner: 'dots', color: 'cyan' }).start();
|
|
14
|
+
await sleep(1000);
|
|
15
|
+
spinner.succeed(chalk.green('Registry queried'));
|
|
16
|
+
|
|
17
|
+
console.log('');
|
|
18
|
+
printDivider();
|
|
19
|
+
console.log('');
|
|
20
|
+
|
|
21
|
+
console.log(` ${chalk.cyan('No agents registered yet')} ${chalk.dim('— network is pre-launch')}`);
|
|
22
|
+
console.log('');
|
|
23
|
+
|
|
24
|
+
console.log(chalk.cyan.bold(' Staged Agents (local)'));
|
|
25
|
+
printDivider();
|
|
26
|
+
info('No local agents staged. Run ' + chalk.cyan('pluribus register') + ' to stage one.');
|
|
27
|
+
console.log('');
|
|
28
|
+
|
|
29
|
+
console.log(chalk.cyan.bold(' Supported Frameworks'));
|
|
30
|
+
printDivider();
|
|
31
|
+
const frameworks = [
|
|
32
|
+
{ name: 'Virtuals Protocol', tag: 'virtuals' },
|
|
33
|
+
{ name: 'ElizaOS', tag: 'eliza' },
|
|
34
|
+
{ name: 'LangChain', tag: 'langchain' },
|
|
35
|
+
{ name: 'AutoGPT', tag: 'autogpt' },
|
|
36
|
+
{ name: 'CrewAI', tag: 'crewai' },
|
|
37
|
+
{ name: 'Custom / Other', tag: 'custom' },
|
|
38
|
+
];
|
|
39
|
+
frameworks.forEach(f => {
|
|
40
|
+
console.log(` ${chalk.cyan('▸')} ${chalk.white(f.name.padEnd(22))} ${chalk.dim('[' + f.tag + ']')}`);
|
|
41
|
+
});
|
|
42
|
+
console.log('');
|
|
43
|
+
|
|
44
|
+
info(`Docs: ${chalk.underline('https://pluribus.xyz/agents')}`);
|
|
45
|
+
console.log('');
|
|
46
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { label, printDivider, info, warn } from '../utils/banner.js';
|
|
4
|
+
|
|
5
|
+
function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
|
|
6
|
+
|
|
7
|
+
export async function logs(agentId, options) {
|
|
8
|
+
const inquirer = (await import('inquirer')).default;
|
|
9
|
+
|
|
10
|
+
console.log('');
|
|
11
|
+
console.log(chalk.cyan.bold(' → Agent Logs'));
|
|
12
|
+
console.log('');
|
|
13
|
+
|
|
14
|
+
if (!agentId) {
|
|
15
|
+
const answers = await inquirer.prompt([
|
|
16
|
+
{
|
|
17
|
+
type: 'input',
|
|
18
|
+
name: 'agentId',
|
|
19
|
+
message: chalk.white('Agent ID (PLR-XXXXXX or task ID):'),
|
|
20
|
+
prefix: chalk.cyan(' ▸'),
|
|
21
|
+
validate: v => v.length > 0 ? true : 'Agent ID is required',
|
|
22
|
+
},
|
|
23
|
+
]);
|
|
24
|
+
agentId = answers.agentId;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const spinner = ora({ text: chalk.dim(`Connecting to agent ${chalk.cyan(agentId)}...`), spinner: 'dots', color: 'cyan' }).start();
|
|
28
|
+
await sleep(900);
|
|
29
|
+
spinner.succeed(chalk.green('Connected'));
|
|
30
|
+
|
|
31
|
+
console.log('');
|
|
32
|
+
printDivider();
|
|
33
|
+
|
|
34
|
+
console.log(` ${chalk.dim('No logs available')} ${chalk.cyan('—')} ${chalk.dim('network is pre-launch')}`);
|
|
35
|
+
console.log('');
|
|
36
|
+
|
|
37
|
+
label('Agent:', agentId);
|
|
38
|
+
label('Status:', chalk.yellow('Awaiting network launch'));
|
|
39
|
+
label('Log stream:', chalk.yellow('Available post-launch'));
|
|
40
|
+
console.log('');
|
|
41
|
+
|
|
42
|
+
info('Once live, this command streams real-time task execution logs.');
|
|
43
|
+
console.log('');
|
|
44
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { success, error, info, warn, label, printDivider } from '../utils/banner.js';
|
|
4
|
+
|
|
5
|
+
function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
|
|
6
|
+
|
|
7
|
+
export async function registerAgent(options) {
|
|
8
|
+
const inquirer = (await import('inquirer')).default;
|
|
9
|
+
|
|
10
|
+
console.log('');
|
|
11
|
+
console.log(chalk.cyan.bold(' → Register New Agent'));
|
|
12
|
+
console.log(chalk.dim(' Create a new agent and stake $PLUR to join the network'));
|
|
13
|
+
console.log('');
|
|
14
|
+
|
|
15
|
+
const answers = await inquirer.prompt([
|
|
16
|
+
{
|
|
17
|
+
type: 'input',
|
|
18
|
+
name: 'name',
|
|
19
|
+
message: chalk.white('Agent name:'),
|
|
20
|
+
prefix: chalk.cyan(' ▸'),
|
|
21
|
+
validate: v => v.length >= 3 ? true : 'Name must be at least 3 characters',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
type: 'input',
|
|
25
|
+
name: 'endpoint',
|
|
26
|
+
message: chalk.white('Agent webhook endpoint (https://...):'),
|
|
27
|
+
prefix: chalk.cyan(' ▸'),
|
|
28
|
+
validate: v => v.startsWith('http') ? true : 'Must be a valid URL',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
type: 'list',
|
|
32
|
+
name: 'tier',
|
|
33
|
+
message: chalk.white('Staking tier:'),
|
|
34
|
+
prefix: chalk.cyan(' ▸'),
|
|
35
|
+
choices: [
|
|
36
|
+
{ name: `Sentinel ${chalk.dim('— Entry tier, basic yield')}`, value: 'sentinel' },
|
|
37
|
+
{ name: `Archon ${chalk.dim('— Mid tier, enhanced yield + priority routing')}`, value: 'archon' },
|
|
38
|
+
{ name: `Sovereign ${chalk.dim('— Elite tier, max yield + governance seat')}`, value: 'sovereign' },
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
type: 'checkbox',
|
|
43
|
+
name: 'capabilities',
|
|
44
|
+
message: chalk.white('Capability tags:'),
|
|
45
|
+
prefix: chalk.cyan(' ▸'),
|
|
46
|
+
choices: [
|
|
47
|
+
{ name: 'research — Token analysis, risk scoring, market research', value: 'research' },
|
|
48
|
+
{ name: 'social — Twitter/X, Farcaster, content generation', value: 'social' },
|
|
49
|
+
{ name: 'onchain — DeFi execution, bridge ops, LP management', value: 'onchain' },
|
|
50
|
+
{ name: 'monitoring — Wallet watch, TX alerts, MEV detection', value: 'monitoring' },
|
|
51
|
+
{ name: 'data — APIs, retrieval, aggregation', value: 'data' },
|
|
52
|
+
{ name: 'content — Writing, summarization, translation', value: 'content' },
|
|
53
|
+
],
|
|
54
|
+
validate: v => v.length > 0 ? true : 'Select at least one capability',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
type: 'input',
|
|
58
|
+
name: 'wallet',
|
|
59
|
+
message: chalk.white('Wallet address (0x...):'),
|
|
60
|
+
prefix: chalk.cyan(' ▸'),
|
|
61
|
+
validate: v => v.startsWith('0x') && v.length === 42 ? true : 'Enter a valid Ethereum address',
|
|
62
|
+
},
|
|
63
|
+
]);
|
|
64
|
+
|
|
65
|
+
const tierStake = { sentinel: '1,000', archon: '25,000', sovereign: '100,000' };
|
|
66
|
+
|
|
67
|
+
console.log('');
|
|
68
|
+
printDivider();
|
|
69
|
+
console.log('');
|
|
70
|
+
|
|
71
|
+
const spinner = ora({ text: chalk.dim('Generating agent identity...'), spinner: 'dots', color: 'cyan' }).start();
|
|
72
|
+
await sleep(900);
|
|
73
|
+
spinner.text = chalk.dim('Validating endpoint...');
|
|
74
|
+
await sleep(700);
|
|
75
|
+
spinner.text = chalk.dim('Computing capability fingerprint...');
|
|
76
|
+
await sleep(600);
|
|
77
|
+
spinner.text = chalk.dim('Staging on-chain registration...');
|
|
78
|
+
await sleep(800);
|
|
79
|
+
spinner.succeed(chalk.green('Agent staged for registration'));
|
|
80
|
+
|
|
81
|
+
const agentId = 'PLR-' + Math.random().toString(36).substring(2, 8).toUpperCase();
|
|
82
|
+
|
|
83
|
+
console.log('');
|
|
84
|
+
console.log(chalk.cyan.bold(' Registration Summary'));
|
|
85
|
+
printDivider();
|
|
86
|
+
label('Agent ID:', chalk.cyan(agentId));
|
|
87
|
+
label('Name:', answers.name);
|
|
88
|
+
label('Endpoint:', answers.endpoint);
|
|
89
|
+
label('Tier:', answers.tier.charAt(0).toUpperCase() + answers.tier.slice(1));
|
|
90
|
+
label('Stake Required:', `${tierStake[answers.tier]} $PLUR`);
|
|
91
|
+
label('Capabilities:', answers.capabilities.join(', '));
|
|
92
|
+
label('Wallet:', answers.wallet);
|
|
93
|
+
label('Network:', 'Base Mainnet');
|
|
94
|
+
label('Status:', chalk.yellow('Staged — pending launch'));
|
|
95
|
+
console.log('');
|
|
96
|
+
|
|
97
|
+
warn('Registration will finalize when the Pluribus network launches.');
|
|
98
|
+
info(`Your agent ID is ${chalk.cyan(agentId)} — save this for reference.`);
|
|
99
|
+
info(`Run ${chalk.cyan('pluribus status')} to check network launch status.`);
|
|
100
|
+
console.log('');
|
|
101
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { label, printDivider, warn, info, success } from '../utils/banner.js';
|
|
4
|
+
|
|
5
|
+
function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
|
|
6
|
+
|
|
7
|
+
export async function stake(amount, options) {
|
|
8
|
+
const inquirer = (await import('inquirer')).default;
|
|
9
|
+
|
|
10
|
+
console.log('');
|
|
11
|
+
console.log(chalk.cyan.bold(' → Stake $PLUR'));
|
|
12
|
+
console.log(chalk.dim(' Stake tokens to earn yield from network task fees'));
|
|
13
|
+
console.log('');
|
|
14
|
+
|
|
15
|
+
if (!amount) {
|
|
16
|
+
const answers = await inquirer.prompt([
|
|
17
|
+
{
|
|
18
|
+
type: 'list',
|
|
19
|
+
name: 'tier',
|
|
20
|
+
message: chalk.white('Select staking tier:'),
|
|
21
|
+
prefix: chalk.cyan(' ▸'),
|
|
22
|
+
choices: [
|
|
23
|
+
{ name: `Sentinel ${chalk.dim('Entry tier — basic yield')}`, value: 'sentinel' },
|
|
24
|
+
{ name: `Archon ${chalk.dim('Mid tier — enhanced yield + routing')}`, value: 'archon' },
|
|
25
|
+
{ name: `Sovereign ${chalk.dim('Elite tier — max yield + governance')}`, value: 'sovereign' },
|
|
26
|
+
],
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
type: 'input',
|
|
30
|
+
name: 'amount',
|
|
31
|
+
message: chalk.white('Amount of $PLUR to stake:'),
|
|
32
|
+
prefix: chalk.cyan(' ▸'),
|
|
33
|
+
validate: v => !isNaN(Number(v)) && Number(v) > 0 ? true : 'Enter a valid amount',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
type: 'input',
|
|
37
|
+
name: 'wallet',
|
|
38
|
+
message: chalk.white('Wallet address (0x...):'),
|
|
39
|
+
prefix: chalk.cyan(' ▸'),
|
|
40
|
+
validate: v => v.startsWith('0x') && v.length === 42 ? true : 'Enter a valid Ethereum address',
|
|
41
|
+
},
|
|
42
|
+
]);
|
|
43
|
+
amount = answers.amount;
|
|
44
|
+
|
|
45
|
+
console.log('');
|
|
46
|
+
printDivider();
|
|
47
|
+
console.log('');
|
|
48
|
+
|
|
49
|
+
const spinner = ora({ text: chalk.dim('Preparing stake transaction...'), spinner: 'dots', color: 'cyan' }).start();
|
|
50
|
+
await sleep(700);
|
|
51
|
+
spinner.text = chalk.dim('Validating wallet...');
|
|
52
|
+
await sleep(600);
|
|
53
|
+
spinner.text = chalk.dim('Staging stake...');
|
|
54
|
+
await sleep(500);
|
|
55
|
+
spinner.succeed(chalk.green('Stake staged'));
|
|
56
|
+
|
|
57
|
+
console.log('');
|
|
58
|
+
label('Tier:', answers.tier.charAt(0).toUpperCase() + answers.tier.slice(1));
|
|
59
|
+
label('Amount:', `${Number(amount).toLocaleString()} $PLUR`);
|
|
60
|
+
label('Wallet:', answers.wallet);
|
|
61
|
+
label('APY:', chalk.cyan('TBA at launch'));
|
|
62
|
+
label('Status:', chalk.yellow('Staged — pending network launch'));
|
|
63
|
+
console.log('');
|
|
64
|
+
warn('Staking goes live when the Pluribus network launches on Base.');
|
|
65
|
+
info(`Run ${chalk.cyan('pluribus balance')} to check your $PLUR balance.`);
|
|
66
|
+
console.log('');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export async function unstake(amount, options) {
|
|
71
|
+
console.log('');
|
|
72
|
+
console.log(chalk.cyan.bold(' → Unstake $PLUR'));
|
|
73
|
+
console.log('');
|
|
74
|
+
|
|
75
|
+
const spinner = ora({ text: chalk.dim('Preparing unstake...'), spinner: 'dots', color: 'cyan' }).start();
|
|
76
|
+
await sleep(1000);
|
|
77
|
+
spinner.succeed(chalk.green('Unstake staged'));
|
|
78
|
+
|
|
79
|
+
console.log('');
|
|
80
|
+
label('Amount:', amount ? `${Number(amount).toLocaleString()} $PLUR` : 'All staked $PLUR');
|
|
81
|
+
label('Status:', chalk.yellow('Staged — pending network launch'));
|
|
82
|
+
console.log('');
|
|
83
|
+
warn('Unstake will execute when the Pluribus staking contract is live.');
|
|
84
|
+
console.log('');
|
|
85
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { label, printDivider, info } from '../utils/banner.js';
|
|
4
|
+
|
|
5
|
+
function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
|
|
6
|
+
|
|
7
|
+
export async function networkStatus() {
|
|
8
|
+
console.log('');
|
|
9
|
+
console.log(chalk.cyan.bold(' → Network Status'));
|
|
10
|
+
console.log('');
|
|
11
|
+
|
|
12
|
+
const spinner = ora({ text: chalk.dim('Querying Pluribus network...'), spinner: 'dots', color: 'cyan' }).start();
|
|
13
|
+
await sleep(1100);
|
|
14
|
+
spinner.succeed(chalk.green('Status retrieved'));
|
|
15
|
+
|
|
16
|
+
console.log('');
|
|
17
|
+
console.log(chalk.cyan.bold(' Protocol Status'));
|
|
18
|
+
printDivider();
|
|
19
|
+
label('Network:', 'Base Mainnet');
|
|
20
|
+
label('Launch Phase:', chalk.yellow('Pre-Launch'));
|
|
21
|
+
label('Protocol Status:', chalk.yellow('● Staging'));
|
|
22
|
+
label('Contracts:', chalk.yellow('Deploying soon'));
|
|
23
|
+
label('Agent Registry:', chalk.yellow('Opening soon'));
|
|
24
|
+
label('Task Queue:', chalk.yellow('Coming soon'));
|
|
25
|
+
console.log('');
|
|
26
|
+
|
|
27
|
+
console.log(chalk.cyan.bold(' Network Metrics'));
|
|
28
|
+
printDivider();
|
|
29
|
+
label('Agents Staged:', chalk.cyan('—'));
|
|
30
|
+
label('Tasks Processed:', chalk.cyan('—'));
|
|
31
|
+
label('$PLUR Burned:', chalk.cyan('—'));
|
|
32
|
+
label('Staker APY:', chalk.cyan('TBA at launch'));
|
|
33
|
+
label('Uptime:', chalk.cyan('—'));
|
|
34
|
+
console.log('');
|
|
35
|
+
|
|
36
|
+
console.log(chalk.cyan.bold(' CLI Version'));
|
|
37
|
+
printDivider();
|
|
38
|
+
label('CLI:', '0.1.0');
|
|
39
|
+
label('SDK Target:', '0.1.0');
|
|
40
|
+
label('Node.js:', process.version);
|
|
41
|
+
console.log('');
|
|
42
|
+
|
|
43
|
+
info(`Follow ${chalk.underline('https://pluribus.xyz')} for launch updates.`);
|
|
44
|
+
console.log('');
|
|
45
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { label, printDivider, warn, info } from '../utils/banner.js';
|
|
4
|
+
|
|
5
|
+
function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
|
|
6
|
+
|
|
7
|
+
export async function submitTask(taskDescription, options) {
|
|
8
|
+
const inquirer = (await import('inquirer')).default;
|
|
9
|
+
|
|
10
|
+
console.log('');
|
|
11
|
+
console.log(chalk.cyan.bold(' → Submit Task'));
|
|
12
|
+
console.log(chalk.dim(' Submit a task to the Pluribus agent network'));
|
|
13
|
+
console.log('');
|
|
14
|
+
|
|
15
|
+
let task = taskDescription;
|
|
16
|
+
let taskType, plur;
|
|
17
|
+
|
|
18
|
+
if (!task) {
|
|
19
|
+
const answers = await inquirer.prompt([
|
|
20
|
+
{
|
|
21
|
+
type: 'input',
|
|
22
|
+
name: 'task',
|
|
23
|
+
message: chalk.white('Describe your task:'),
|
|
24
|
+
prefix: chalk.cyan(' ▸'),
|
|
25
|
+
validate: v => v.length >= 10 ? true : 'Please provide a meaningful task description',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
type: 'list',
|
|
29
|
+
name: 'type',
|
|
30
|
+
message: chalk.white('Task type:'),
|
|
31
|
+
prefix: chalk.cyan(' ▸'),
|
|
32
|
+
choices: [
|
|
33
|
+
{ name: 'research — Analysis, research, risk scoring', value: 'research' },
|
|
34
|
+
{ name: 'social — Post, thread, engagement', value: 'social' },
|
|
35
|
+
{ name: 'monitoring — Watch wallet or contract', value: 'monitoring' },
|
|
36
|
+
{ name: 'onchain — Execute onchain action', value: 'onchain' },
|
|
37
|
+
{ name: 'auto — Let the orchestrator decide', value: 'auto' },
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
type: 'input',
|
|
42
|
+
name: 'plur',
|
|
43
|
+
message: chalk.white('$PLUR to pay (determines priority):'),
|
|
44
|
+
prefix: chalk.cyan(' ▸'),
|
|
45
|
+
default: '0.5',
|
|
46
|
+
validate: v => !isNaN(Number(v)) && Number(v) > 0 ? true : 'Enter a valid amount',
|
|
47
|
+
},
|
|
48
|
+
]);
|
|
49
|
+
task = answers.task;
|
|
50
|
+
taskType = answers.type;
|
|
51
|
+
plur = answers.plur;
|
|
52
|
+
} else {
|
|
53
|
+
taskType = options.type || 'auto';
|
|
54
|
+
plur = options.plur || '0.5';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
console.log('');
|
|
58
|
+
printDivider();
|
|
59
|
+
console.log('');
|
|
60
|
+
|
|
61
|
+
const spinner = ora({ text: chalk.dim('Connecting to orchestrator...'), spinner: 'dots', color: 'cyan' }).start();
|
|
62
|
+
await sleep(800);
|
|
63
|
+
spinner.text = chalk.dim('Routing to best agents...');
|
|
64
|
+
await sleep(600);
|
|
65
|
+
spinner.text = chalk.dim('Staging task submission...');
|
|
66
|
+
await sleep(700);
|
|
67
|
+
spinner.succeed(chalk.green('Task staged'));
|
|
68
|
+
|
|
69
|
+
const taskId = '#' + Math.floor(Math.random() * 90000 + 10000);
|
|
70
|
+
|
|
71
|
+
console.log('');
|
|
72
|
+
console.log(chalk.cyan.bold(' Task Summary'));
|
|
73
|
+
printDivider();
|
|
74
|
+
label('Task ID:', chalk.cyan(taskId));
|
|
75
|
+
label('Description:', task.length > 50 ? task.slice(0, 50) + '...' : task);
|
|
76
|
+
label('Type:', taskType);
|
|
77
|
+
label('$PLUR:', plur);
|
|
78
|
+
label('Status:', chalk.yellow('Staged — pending network launch'));
|
|
79
|
+
console.log('');
|
|
80
|
+
|
|
81
|
+
warn('Task submission goes live when the Pluribus network launches.');
|
|
82
|
+
info(`Task ID ${chalk.cyan(taskId)} saved. Run ${chalk.cyan('pluribus logs ' + taskId)} post-launch to track results.`);
|
|
83
|
+
console.log('');
|
|
84
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
|
|
3
|
+
export function printBanner() {
|
|
4
|
+
const cyan = chalk.cyan;
|
|
5
|
+
const dim = chalk.dim;
|
|
6
|
+
const bold = chalk.bold;
|
|
7
|
+
|
|
8
|
+
console.log('');
|
|
9
|
+
console.log(cyan.bold(' ██████╗ ██╗ ██╗ ██╗██████╗ ██╗██████╗ ██╗ ██╗███████╗'));
|
|
10
|
+
console.log(cyan.bold(' ██╔══██╗██║ ██║ ██║██╔══██╗██║██╔══██╗██║ ██║██╔════╝'));
|
|
11
|
+
console.log(cyan.bold(' ██████╔╝██║ ██║ ██║██████╔╝██║██████╔╝██║ ██║███████╗'));
|
|
12
|
+
console.log(cyan.bold(' ██╔═══╝ ██║ ██║ ██║██╔══██╗██║██╔══██╗██║ ██║╚════██║'));
|
|
13
|
+
console.log(cyan.bold(' ██║ ███████╗╚██████╔╝██║ ██║██║██████╔╝╚██████╔╝███████║'));
|
|
14
|
+
console.log(cyan.bold(' ╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═════╝ ╚═════╝ ╚══════╝'));
|
|
15
|
+
console.log('');
|
|
16
|
+
console.log(` ${chalk.magenta('E PLURIBUS UNUM')} ${dim('—')} ${chalk.white.bold('Many Agents. One Mind.')}`);
|
|
17
|
+
console.log(` ${dim('Multi-Agent Coordination Protocol on Base')}`);
|
|
18
|
+
console.log('');
|
|
19
|
+
console.log(` ${dim('Version')} ${chalk.cyan('0.1.0')} ${dim('·')} ${chalk.underline.dim('https://pluribus.xyz')}`);
|
|
20
|
+
console.log('');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function printDivider() {
|
|
24
|
+
console.log(chalk.dim(' ' + '─'.repeat(60)));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function success(msg) {
|
|
28
|
+
console.log(` ${chalk.green('✓')} ${chalk.white(msg)}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function error(msg) {
|
|
32
|
+
console.log(` ${chalk.red('✗')} ${chalk.white(msg)}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function info(msg) {
|
|
36
|
+
console.log(` ${chalk.cyan('ℹ')} ${chalk.white(msg)}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function warn(msg) {
|
|
40
|
+
console.log(` ${chalk.yellow('⚠')} ${chalk.white(msg)}`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function label(key, val) {
|
|
44
|
+
console.log(` ${chalk.dim(key.padEnd(20))} ${chalk.white(val)}`);
|
|
45
|
+
}
|