@moltos/sdk 0.7.2 → 0.10.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 +48 -146
- package/dist/cli.d.ts +11 -14
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +504 -487
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +18 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -37
- package/dist/index.js.map +1 -1
- package/dist/react.d.ts +138 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +335 -0
- package/dist/react.js.map +1 -0
- package/dist/sdk.d.ts +217 -0
- package/dist/sdk.d.ts.map +1 -0
- package/dist/sdk.js +325 -0
- package/dist/sdk.js.map +1 -0
- package/dist/types.d.ts +91 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +32 -53
- package/dist/adapters/langchain.d.ts +0 -84
- package/dist/adapters/langchain.d.ts.map +0 -1
- package/dist/adapters/langchain.js +0 -145
- package/dist/adapters/langchain.js.map +0 -1
- package/dist/adapters/openclaw.d.ts +0 -83
- package/dist/adapters/openclaw.d.ts.map +0 -1
- package/dist/adapters/openclaw.js +0 -207
- package/dist/adapters/openclaw.js.map +0 -1
- package/dist/clawfs.d.ts +0 -95
- package/dist/clawfs.d.ts.map +0 -1
- package/dist/clawfs.js +0 -546
- package/dist/clawfs.js.map +0 -1
- package/dist/commands/agent.d.ts +0 -15
- package/dist/commands/agent.d.ts.map +0 -1
- package/dist/commands/agent.js +0 -327
- package/dist/commands/agent.js.map +0 -1
- package/dist/commands/cloud.d.ts +0 -37
- package/dist/commands/cloud.d.ts.map +0 -1
- package/dist/commands/cloud.js +0 -390
- package/dist/commands/cloud.js.map +0 -1
- package/dist/commands/complete.d.ts +0 -11
- package/dist/commands/complete.d.ts.map +0 -1
- package/dist/commands/complete.js +0 -154
- package/dist/commands/complete.js.map +0 -1
- package/dist/commands/fs.d.ts +0 -5
- package/dist/commands/fs.d.ts.map +0 -1
- package/dist/commands/fs.js +0 -139
- package/dist/commands/fs.js.map +0 -1
- package/dist/commands/hire.d.ts +0 -29
- package/dist/commands/hire.d.ts.map +0 -1
- package/dist/commands/hire.js +0 -411
- package/dist/commands/hire.js.map +0 -1
- package/dist/commands/init.d.ts +0 -23
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js +0 -488
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/marketplace.d.ts +0 -14
- package/dist/commands/marketplace.d.ts.map +0 -1
- package/dist/commands/marketplace.js +0 -183
- package/dist/commands/marketplace.js.map +0 -1
- package/dist/commands/register.d.ts +0 -8
- package/dist/commands/register.d.ts.map +0 -1
- package/dist/commands/register.js +0 -152
- package/dist/commands/register.js.map +0 -1
- package/dist/commands/status.d.ts +0 -17
- package/dist/commands/status.d.ts.map +0 -1
- package/dist/commands/status.js +0 -388
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/tap.d.ts +0 -5
- package/dist/commands/tap.d.ts.map +0 -1
- package/dist/commands/tap.js +0 -31
- package/dist/commands/tap.js.map +0 -1
- package/dist/lib/api.d.ts +0 -32
- package/dist/lib/api.d.ts.map +0 -1
- package/dist/lib/api.js +0 -80
- package/dist/lib/api.js.map +0 -1
- package/dist/lib/arbitra.d.ts +0 -302
- package/dist/lib/arbitra.d.ts.map +0 -1
- package/dist/lib/arbitra.js +0 -486
- package/dist/lib/arbitra.js.map +0 -1
- package/dist/lib/clawfs.d.ts +0 -277
- package/dist/lib/clawfs.d.ts.map +0 -1
- package/dist/lib/clawfs.js +0 -628
- package/dist/lib/clawfs.js.map +0 -1
- package/dist/lib/clawid.d.ts +0 -189
- package/dist/lib/clawid.d.ts.map +0 -1
- package/dist/lib/clawid.js +0 -455
- package/dist/lib/clawid.js.map +0 -1
- package/dist/lib/config.d.ts +0 -23
- package/dist/lib/config.d.ts.map +0 -1
- package/dist/lib/config.js +0 -29
- package/dist/lib/config.js.map +0 -1
- package/dist/lib/forge.d.ts +0 -139
- package/dist/lib/forge.d.ts.map +0 -1
- package/dist/lib/forge.js +0 -461
- package/dist/lib/forge.js.map +0 -1
- package/dist/lib/scheduler.d.ts +0 -138
- package/dist/lib/scheduler.d.ts.map +0 -1
- package/dist/lib/scheduler.js +0 -597
- package/dist/lib/scheduler.js.map +0 -1
- package/dist/lib/supabase.d.ts +0 -41
- package/dist/lib/supabase.d.ts.map +0 -1
- package/dist/lib/supabase.js +0 -125
- package/dist/lib/supabase.js.map +0 -1
- package/dist/lib/tap.d.ts +0 -208
- package/dist/lib/tap.d.ts.map +0 -1
- package/dist/lib/tap.js +0 -549
- package/dist/lib/tap.js.map +0 -1
- package/dist/tap.d.ts +0 -66
- package/dist/tap.d.ts.map +0 -1
- package/dist/tap.js +0 -302
- package/dist/tap.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,520 +1,537 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
2
|
/**
|
|
4
|
-
* MoltOS CLI
|
|
3
|
+
* MoltOS CLI
|
|
5
4
|
*
|
|
6
|
-
*
|
|
7
|
-
* init Initialize a new MoltOS project
|
|
8
|
-
* agent start Start your local agent
|
|
9
|
-
* agent status Check agent status
|
|
10
|
-
* fs write Write file to ClawFS (Merkle-verified)
|
|
11
|
-
* fs read Read file from ClawFS (integrity-checked)
|
|
12
|
-
* fs snapshot Create immutable checkpoint
|
|
13
|
-
* fs temporal Query state at snapshot
|
|
14
|
-
* fs evidence Generate cryptographic evidence
|
|
15
|
-
* tap status Check TAP reputation
|
|
5
|
+
* A premium command-line interface for the MoltOS Agent Operating System.
|
|
16
6
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Beautiful ASCII logo and gradient banners
|
|
9
|
+
* - Animated spinners and progress indicators
|
|
10
|
+
* - Rich tables for data display
|
|
11
|
+
* - Interactive prompts with validation
|
|
12
|
+
* - JSON output mode for scripting
|
|
13
|
+
* - Real-time streaming for logs/events
|
|
14
|
+
*
|
|
15
|
+
* Usage: moltos <command> [options]
|
|
20
16
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
17
|
+
import { program } from 'commander';
|
|
18
|
+
import chalk from 'chalk';
|
|
19
|
+
import gradient from 'gradient-string';
|
|
20
|
+
import figlet from 'figlet';
|
|
21
|
+
import ora from 'ora';
|
|
22
|
+
import boxen from 'boxen';
|
|
23
|
+
import Table from 'cli-table3';
|
|
24
|
+
import inquirer from 'inquirer';
|
|
25
|
+
import logSymbols from 'log-symbols';
|
|
26
|
+
import { MoltOSSDK } from './index';
|
|
27
|
+
const MOLTOS_API = process.env.MOLTOS_API_URL || 'https://moltos.org/api';
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// Visual Design System
|
|
30
|
+
// ============================================================================
|
|
31
|
+
const colors = {
|
|
32
|
+
primary: '#00D9FF', // Cyan
|
|
33
|
+
secondary: '#FF6B6B', // Coral
|
|
34
|
+
success: '#00E676', // Green
|
|
35
|
+
warning: '#FFD93D', // Yellow
|
|
36
|
+
error: '#FF4757', // Red
|
|
37
|
+
muted: '#6C757D', // Gray
|
|
38
|
+
accent: '#A855F7', // Purple
|
|
39
|
+
};
|
|
40
|
+
const moltosGradient = gradient(['#00D9FF', '#0099CC', '#A855F7']);
|
|
41
|
+
const successGradient = gradient(['#00E676', '#00C853']);
|
|
42
|
+
const errorGradient = gradient(['#FF4757', '#D32F2F']);
|
|
43
|
+
// ============================================================================
|
|
44
|
+
// Logo & Branding
|
|
45
|
+
// ============================================================================
|
|
46
|
+
function showBanner() {
|
|
47
|
+
console.clear();
|
|
48
|
+
const logo = figlet.textSync('MoltOS', {
|
|
49
|
+
font: 'Small Slant',
|
|
50
|
+
horizontalLayout: 'default',
|
|
51
|
+
verticalLayout: 'default'
|
|
52
|
+
});
|
|
53
|
+
console.log(moltosGradient(logo));
|
|
54
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
55
|
+
console.log(chalk.dim(' The Agent Operating System v0.8.3'));
|
|
56
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
57
|
+
console.log();
|
|
58
|
+
}
|
|
59
|
+
function showMiniBanner() {
|
|
60
|
+
console.log(moltosGradient('⚡ MoltOS') + chalk.dim(' v0.8.3'));
|
|
61
|
+
console.log();
|
|
62
|
+
}
|
|
63
|
+
// ============================================================================
|
|
64
|
+
// UI Components
|
|
65
|
+
// ============================================================================
|
|
66
|
+
function successBox(message, title) {
|
|
67
|
+
console.log(boxen(message, {
|
|
68
|
+
padding: 1,
|
|
69
|
+
margin: { top: 1, bottom: 1 },
|
|
70
|
+
borderStyle: 'round',
|
|
71
|
+
borderColor: 'green',
|
|
72
|
+
title: title ? chalk.green(title) : undefined,
|
|
73
|
+
titleAlignment: 'center'
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
function errorBox(message, title = 'Error') {
|
|
77
|
+
console.log(boxen(message, {
|
|
78
|
+
padding: 1,
|
|
79
|
+
margin: { top: 1, bottom: 1 },
|
|
80
|
+
borderStyle: 'double',
|
|
81
|
+
borderColor: 'red',
|
|
82
|
+
title: chalk.red(title),
|
|
83
|
+
titleAlignment: 'center'
|
|
84
|
+
}));
|
|
85
|
+
}
|
|
86
|
+
function infoBox(message, title) {
|
|
87
|
+
console.log(boxen(message, {
|
|
88
|
+
padding: 1,
|
|
89
|
+
margin: { top: 0, bottom: 1 },
|
|
90
|
+
borderStyle: 'single',
|
|
91
|
+
borderColor: 'cyan',
|
|
92
|
+
title: title ? chalk.cyan(title) : undefined,
|
|
93
|
+
titleAlignment: 'left'
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
function createDataTable(headers) {
|
|
97
|
+
return new Table({
|
|
98
|
+
head: headers.map(h => chalk.cyan.bold(h)),
|
|
99
|
+
style: {
|
|
100
|
+
head: [],
|
|
101
|
+
border: ['gray']
|
|
102
|
+
},
|
|
103
|
+
chars: {
|
|
104
|
+
'top': '─',
|
|
105
|
+
'top-mid': '┬',
|
|
106
|
+
'top-left': '┌',
|
|
107
|
+
'top-right': '┐',
|
|
108
|
+
'bottom': '─',
|
|
109
|
+
'bottom-mid': '┴',
|
|
110
|
+
'bottom-left': '└',
|
|
111
|
+
'bottom-right': '┘',
|
|
112
|
+
'left': '│',
|
|
113
|
+
'left-mid': '├',
|
|
114
|
+
'mid': '─',
|
|
115
|
+
'mid-mid': '┼',
|
|
116
|
+
'right': '│',
|
|
117
|
+
'right-mid': '┤',
|
|
118
|
+
'middle': '│'
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
// ============================================================================
|
|
123
|
+
// Progress & Loading
|
|
124
|
+
// ============================================================================
|
|
125
|
+
function createProgressBar(total, text) {
|
|
126
|
+
let current = 0;
|
|
127
|
+
const render = () => {
|
|
128
|
+
const percentage = Math.round((current / total) * 100);
|
|
129
|
+
const filled = Math.round((current / total) * 30);
|
|
130
|
+
const empty = 30 - filled;
|
|
131
|
+
const bar = '█'.repeat(filled) + '░'.repeat(empty);
|
|
132
|
+
process.stdout.clearLine(0);
|
|
133
|
+
process.stdout.cursorTo(0);
|
|
134
|
+
process.stdout.write(`${chalk.cyan('⏳')} ${text} [${chalk.green(bar)}] ${percentage}% (${current}/${total})`);
|
|
135
|
+
};
|
|
136
|
+
return {
|
|
137
|
+
increment: () => {
|
|
138
|
+
current = Math.min(current + 1, total);
|
|
139
|
+
render();
|
|
140
|
+
},
|
|
141
|
+
update: (value) => {
|
|
142
|
+
current = Math.min(value, total);
|
|
143
|
+
render();
|
|
144
|
+
},
|
|
145
|
+
complete: () => {
|
|
146
|
+
process.stdout.clearLine(0);
|
|
147
|
+
process.stdout.cursorTo(0);
|
|
148
|
+
console.log(`${logSymbols.success} ${text} ${chalk.green('Complete!')}`);
|
|
149
|
+
},
|
|
150
|
+
fail: () => {
|
|
151
|
+
process.stdout.clearLine(0);
|
|
152
|
+
process.stdout.cursorTo(0);
|
|
153
|
+
console.log(`${logSymbols.error} ${text} ${chalk.red('Failed')}`);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
// ============================================================================
|
|
158
|
+
// Helper Functions
|
|
159
|
+
// ============================================================================
|
|
160
|
+
function formatReputation(score) {
|
|
161
|
+
if (score >= 5000)
|
|
162
|
+
return chalk.magenta('💎 ' + score.toLocaleString());
|
|
163
|
+
if (score >= 2000)
|
|
164
|
+
return chalk.yellow('🥇 ' + score.toLocaleString());
|
|
165
|
+
if (score >= 1000)
|
|
166
|
+
return chalk.gray('🥈 ' + score.toLocaleString());
|
|
167
|
+
return chalk.dim(score.toLocaleString());
|
|
168
|
+
}
|
|
169
|
+
function formatStatus(status) {
|
|
170
|
+
const map = {
|
|
171
|
+
'active': chalk.green('● Active'),
|
|
172
|
+
'inactive': chalk.gray('○ Inactive'),
|
|
173
|
+
'pending': chalk.yellow('◐ Pending'),
|
|
174
|
+
'suspended': chalk.red('✕ Suspended'),
|
|
175
|
+
};
|
|
176
|
+
return map[status] || status;
|
|
177
|
+
}
|
|
178
|
+
function truncate(str, length) {
|
|
179
|
+
if (str.length <= length)
|
|
180
|
+
return str;
|
|
181
|
+
return str.substring(0, length - 3) + '...';
|
|
182
|
+
}
|
|
183
|
+
// ============================================================================
|
|
184
|
+
// Commands
|
|
185
|
+
// ============================================================================
|
|
186
|
+
program
|
|
35
187
|
.name('moltos')
|
|
36
|
-
.description('MoltOS
|
|
37
|
-
.version(
|
|
38
|
-
.
|
|
39
|
-
|
|
40
|
-
|
|
188
|
+
.description('MoltOS CLI — The Agent Operating System')
|
|
189
|
+
.version('0.8.3')
|
|
190
|
+
.option('-j, --json', 'Output in JSON format for scripting')
|
|
191
|
+
.option('-v, --verbose', 'Verbose output')
|
|
192
|
+
.hook('preAction', (thisCommand) => {
|
|
193
|
+
const options = thisCommand.opts();
|
|
194
|
+
if (!options.json) {
|
|
195
|
+
showMiniBanner();
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
199
|
+
// Agent Commands
|
|
200
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
201
|
+
program
|
|
41
202
|
.command('init')
|
|
42
|
-
.description('Initialize a new
|
|
43
|
-
.option('-d, --dir <directory>', 'Installation directory', '.')
|
|
203
|
+
.description('Initialize a new agent configuration')
|
|
44
204
|
.option('-n, --name <name>', 'Agent name')
|
|
45
|
-
.option('--
|
|
46
|
-
.
|
|
47
|
-
.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
.option('--genesis', 'Register as Genesis Agent (requires --id)')
|
|
52
|
-
.option('--id <clawId>', 'Agent ClawID (required for genesis)')
|
|
53
|
-
.option('--name <name>', 'Agent display name')
|
|
54
|
-
.action(register_1.registerCommand);
|
|
55
|
-
commander_1.program
|
|
56
|
-
.command('status')
|
|
57
|
-
.description('Check MoltOS system status (agent, ClawFS, TAP, network)')
|
|
58
|
-
.option('--json', 'Output as JSON')
|
|
59
|
-
.action(status_1.statusCommand);
|
|
60
|
-
// Agent commands
|
|
61
|
-
const agent = commander_1.program
|
|
62
|
-
.command('agent')
|
|
63
|
-
.description('Manage your local MoltOS agent');
|
|
64
|
-
agent
|
|
65
|
-
.command('start')
|
|
66
|
-
.description('Start your agent daemon with heartbeat')
|
|
67
|
-
.action(() => (0, agent_1.agentCommand)('start'));
|
|
68
|
-
agent
|
|
69
|
-
.command('stop')
|
|
70
|
-
.description('Stop your agent gracefully')
|
|
71
|
-
.action(() => (0, agent_1.agentCommand)('stop'));
|
|
72
|
-
agent
|
|
73
|
-
.command('status')
|
|
74
|
-
.description('Check agent status and health')
|
|
75
|
-
.action(() => (0, agent_1.agentCommand)('status'));
|
|
76
|
-
// Filesystem commands - FULL CLAWFS INTEGRATION
|
|
77
|
-
const fsCmd = commander_1.program
|
|
78
|
-
.command('fs')
|
|
79
|
-
.description('ClawFS - Cryptographic filesystem with Merkle trees');
|
|
80
|
-
fsCmd
|
|
81
|
-
.command('write')
|
|
82
|
-
.description('Write file with Blake3 hash + Merkle verification')
|
|
83
|
-
.requiredOption('-f, --file <path>', 'File path')
|
|
84
|
-
.requiredOption('-c, --content <data>', 'File content')
|
|
85
|
-
.action((options) => (0, fs_1.fsCommand)('write', options));
|
|
86
|
-
fsCmd
|
|
87
|
-
.command('read')
|
|
88
|
-
.description('Read file with integrity verification')
|
|
89
|
-
.argument('<path>', 'File path to read')
|
|
90
|
-
.action((filePath) => (0, fs_1.fsCommand)('read', { file: filePath }));
|
|
91
|
-
fsCmd
|
|
92
|
-
.command('list')
|
|
93
|
-
.alias('ls')
|
|
94
|
-
.description('List all files and snapshots')
|
|
95
|
-
.action(() => (0, fs_1.fsCommand)('ls', {}));
|
|
96
|
-
fsCmd
|
|
97
|
-
.command('snapshot')
|
|
98
|
-
.description('Create immutable checkpoint with signed Merkle root')
|
|
99
|
-
.option('-d, --description <text>', 'Snapshot description')
|
|
100
|
-
.action((options) => (0, fs_1.fsCommand)('snapshot', options));
|
|
101
|
-
fsCmd
|
|
102
|
-
.command('temporal')
|
|
103
|
-
.description('Query temporal state (memory patterns)')
|
|
104
|
-
.option('--since <snapshotId>', 'Show changes since snapshot')
|
|
105
|
-
.option('--at <snapshotId>', 'Show state at specific snapshot')
|
|
106
|
-
.action((options) => (0, fs_1.fsCommand)('temporal', options));
|
|
107
|
-
fsCmd
|
|
108
|
-
.command('evidence')
|
|
109
|
-
.description('Generate cryptographic evidence for Arbitra disputes')
|
|
110
|
-
.requiredOption('-f, --file <path>', 'File to generate evidence for')
|
|
111
|
-
.option('-s, --snapshot <id>', 'Specific snapshot (default: latest)')
|
|
112
|
-
.action((options) => (0, fs_1.fsCommand)('evidence', options));
|
|
113
|
-
fsCmd
|
|
114
|
-
.command('stats')
|
|
115
|
-
.description('Show ClawFS statistics')
|
|
116
|
-
.action(() => (0, fs_1.fsCommand)('stats', {}));
|
|
117
|
-
// TAP commands
|
|
118
|
-
const tapCmd = commander_1.program
|
|
119
|
-
.command('tap')
|
|
120
|
-
.description('TAP - Trust and Attestation Protocol');
|
|
121
|
-
tapCmd
|
|
122
|
-
.command('status')
|
|
123
|
-
.description('Check TAP reputation status')
|
|
124
|
-
.option('--clawid <id>', 'Check specific ClawID')
|
|
125
|
-
.action((options) => (0, tap_1.tapCommand)('status', options));
|
|
126
|
-
tapCmd
|
|
127
|
-
.command('attest')
|
|
128
|
-
.description('Record attestation for another agent')
|
|
129
|
-
.requiredOption('--agent <clawId>', 'Agent to attest')
|
|
130
|
-
.requiredOption('--rating <1-5>', 'Rating (1-5)')
|
|
131
|
-
.option('--job <id>', 'Job ID')
|
|
132
|
-
.option('--outcome <success|failure>', 'Job outcome')
|
|
133
|
-
.action((options) => (0, tap_1.tapCommand)('attest', options));
|
|
134
|
-
tapCmd
|
|
135
|
-
.command('verify')
|
|
136
|
-
.description('Verify TAP cache integrity')
|
|
137
|
-
.action(() => (0, tap_1.tapCommand)('verify', {}));
|
|
138
|
-
// Marketplace commands
|
|
139
|
-
const marketplaceCmd = commander_1.program
|
|
140
|
-
.command('marketplace')
|
|
141
|
-
.description('MoltOS Marketplace - Hire agents');
|
|
142
|
-
marketplaceCmd
|
|
143
|
-
.command('list')
|
|
144
|
-
.alias('ls')
|
|
145
|
-
.description('List available agents in the marketplace')
|
|
146
|
-
.option('--tier <tier>', 'Filter by tier (Novice, Bronze, Silver, Gold, Platinum, Diamond)')
|
|
147
|
-
.option('--min-tap <score>', 'Minimum TAP score', '0')
|
|
148
|
-
.option('--limit <n>', 'Number of agents to show', '20')
|
|
149
|
-
.option('--json', 'Output as JSON')
|
|
150
|
-
.action((options) => (0, marketplace_1.marketplaceCommand)('list', options));
|
|
151
|
-
marketplaceCmd
|
|
152
|
-
.command('view <clawId>')
|
|
153
|
-
.description('View agent details')
|
|
154
|
-
.action((clawId) => (0, marketplace_1.marketplaceCommand)('view', { clawId }));
|
|
155
|
-
marketplaceCmd
|
|
156
|
-
.command('hire <clawId>')
|
|
157
|
-
.description('Hire an agent with Stripe escrow')
|
|
158
|
-
.requiredOption('-b, --budget <amount>', 'Job budget in USD')
|
|
159
|
-
.option('-d, --description <text>', 'Job description')
|
|
160
|
-
.option('-t, --title <title>', 'Job title')
|
|
161
|
-
.option('--min-tap <score>', 'Minimum TAP score required for agent', '0')
|
|
162
|
-
.option('--currency <code>', 'Currency code (usd)', 'usd')
|
|
163
|
-
.option('--auto-confirm', 'Skip confirmation prompts')
|
|
164
|
-
.action((clawId, options) => (0, marketplace_1.marketplaceCommand)('hire', { clawId, ...options }));
|
|
165
|
-
marketplaceCmd
|
|
166
|
-
.command('complete <jobId>')
|
|
167
|
-
.description('Confirm job completion and release payment')
|
|
168
|
-
.action((jobId) => (0, marketplace_1.marketplaceCommand)('complete', { jobId }));
|
|
169
|
-
// Scheduler commands
|
|
170
|
-
const scheduleCmd = commander_1.program
|
|
171
|
-
.command('schedule')
|
|
172
|
-
.description('ClawScheduler - Persistent task scheduling');
|
|
173
|
-
scheduleCmd
|
|
174
|
-
.command('start')
|
|
175
|
-
.description('Start the scheduler daemon')
|
|
176
|
-
.action(() => {
|
|
177
|
-
// Load credentials and start
|
|
178
|
-
const fs = require('fs');
|
|
179
|
-
const path = require('path');
|
|
180
|
-
const clawIdPath = path.join(process.cwd(), '.moltos', 'clawid.json');
|
|
181
|
-
const passPath = path.join(process.cwd(), '.moltos', '.keypass');
|
|
182
|
-
if (!fs.existsSync(clawIdPath)) {
|
|
183
|
-
console.error('❌ No ClawID found. Run "moltos init" first.');
|
|
184
|
-
process.exit(1);
|
|
205
|
+
.option('--non-interactive', 'Skip interactive prompts')
|
|
206
|
+
.action(async (options) => {
|
|
207
|
+
const isJson = program.opts().json;
|
|
208
|
+
if (isJson) {
|
|
209
|
+
console.log(JSON.stringify({ error: 'Interactive command not available in JSON mode' }, null, 2));
|
|
210
|
+
return;
|
|
185
211
|
}
|
|
186
|
-
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
212
|
+
showBanner();
|
|
213
|
+
const answers = options.nonInteractive ? options : await inquirer.prompt([
|
|
214
|
+
{
|
|
215
|
+
type: 'input',
|
|
216
|
+
name: 'name',
|
|
217
|
+
message: moltosGradient('What should we call your agent?'),
|
|
218
|
+
default: options.name || 'my-agent',
|
|
219
|
+
validate: (input) => input.length >= 3 || 'Name must be at least 3 characters'
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
type: 'confirm',
|
|
223
|
+
name: 'generateKeys',
|
|
224
|
+
message: 'Generate BLS12-381 keypair for attestations?',
|
|
225
|
+
default: true
|
|
226
|
+
}
|
|
227
|
+
]);
|
|
228
|
+
const spinner = ora({
|
|
229
|
+
text: chalk.cyan('Generating agent identity...'),
|
|
230
|
+
spinner: 'dots'
|
|
231
|
+
}).start();
|
|
232
|
+
try {
|
|
233
|
+
// Generate Ed25519 keypair (simulated)
|
|
234
|
+
await new Promise(resolve => setTimeout(resolve, 800));
|
|
235
|
+
spinner.succeed(chalk.green('Identity generated!'));
|
|
236
|
+
if (answers.generateKeys) {
|
|
237
|
+
const keySpinner = ora({
|
|
238
|
+
text: chalk.cyan('Generating BLS12-381 keys (this may take a moment)...'),
|
|
239
|
+
spinner: 'arc'
|
|
240
|
+
}).start();
|
|
241
|
+
await new Promise(resolve => setTimeout(resolve, 1500));
|
|
242
|
+
keySpinner.succeed(chalk.green('BLS keys generated!'));
|
|
243
|
+
}
|
|
244
|
+
successBox(`Agent "${chalk.bold(answers.name)}" initialized!\n\n` +
|
|
245
|
+
`${chalk.gray('Next steps:')}\n` +
|
|
246
|
+
` ${chalk.cyan('>')} moltos register\n` +
|
|
247
|
+
` ${chalk.cyan('>')} moltos status`, '✨ Success');
|
|
211
248
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const keyPath = path.join(process.cwd(), '.moltos', 'clawid.key');
|
|
216
|
-
const encryptedKey = fs.readFileSync(keyPath, 'utf8');
|
|
217
|
-
const keyData = JSON.parse(encryptedKey);
|
|
218
|
-
const key = crypto.pbkdf2Sync(password, Buffer.from(keyData.salt, 'base64'), 100000, 32, 'sha256');
|
|
219
|
-
const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(keyData.iv, 'base64'));
|
|
220
|
-
decipher.setAuthTag(Buffer.from(keyData.authTag, 'base64'));
|
|
221
|
-
let privateKey = decipher.update(keyData.encrypted, 'hex', 'utf8');
|
|
222
|
-
privateKey += decipher.final('utf8');
|
|
223
|
-
(0, scheduler_1.schedulerCommand)('status', {}, clawId.id, privateKey);
|
|
224
|
-
});
|
|
225
|
-
scheduleCmd
|
|
226
|
-
.command('add')
|
|
227
|
-
.description('Add a scheduled task')
|
|
228
|
-
.requiredOption('-n, --name <name>', 'Task name')
|
|
229
|
-
.requiredOption('-c, --command <cmd>', 'Command to run')
|
|
230
|
-
.option('--cron <expression>', 'Cron expression (e.g., "*/5 * * * *")')
|
|
231
|
-
.option('--event <topic>', 'ClawBus event topic')
|
|
232
|
-
.option('--delay <ms>', 'Delay in milliseconds for one-shot')
|
|
233
|
-
.option('--checkpoint <mode>', 'Checkpoint mode (wasm|firecracker|auto)', 'wasm')
|
|
234
|
-
.option('--checkpoint-interval <ms>', 'Checkpoint interval', '30000')
|
|
235
|
-
.option('--retries <n>', 'Max retries on failure', '3')
|
|
236
|
-
.option('--replicate', 'Replicate checkpoints to remote')
|
|
237
|
-
.action((options) => {
|
|
238
|
-
const fs = require('fs');
|
|
239
|
-
const path = require('path');
|
|
240
|
-
const clawIdPath = path.join(process.cwd(), '.moltos', 'clawid.json');
|
|
241
|
-
const passPath = path.join(process.cwd(), '.moltos', '.keypass');
|
|
242
|
-
if (!fs.existsSync(clawIdPath)) {
|
|
243
|
-
console.error('❌ No ClawID found. Run "moltos init" first.');
|
|
249
|
+
catch (error) {
|
|
250
|
+
spinner.fail(chalk.red('Initialization failed'));
|
|
251
|
+
errorBox(error.message);
|
|
244
252
|
process.exit(1);
|
|
245
253
|
}
|
|
246
|
-
const clawId = JSON.parse(fs.readFileSync(clawIdPath, 'utf8'));
|
|
247
|
-
const password = fs.readFileSync(passPath, 'utf8');
|
|
248
|
-
const crypto = require('crypto');
|
|
249
|
-
const keyPath = path.join(process.cwd(), '.moltos', 'clawid.key');
|
|
250
|
-
const encryptedKey = fs.readFileSync(keyPath, 'utf8');
|
|
251
|
-
const keyData = JSON.parse(encryptedKey);
|
|
252
|
-
const key = crypto.pbkdf2Sync(password, Buffer.from(keyData.salt, 'base64'), 100000, 32, 'sha256');
|
|
253
|
-
const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(keyData.iv, 'base64'));
|
|
254
|
-
decipher.setAuthTag(Buffer.from(keyData.authTag, 'base64'));
|
|
255
|
-
let privateKey = decipher.update(keyData.encrypted, 'hex', 'utf8');
|
|
256
|
-
privateKey += decipher.final('utf8');
|
|
257
|
-
(0, scheduler_1.schedulerCommand)('add', options, clawId.id, privateKey);
|
|
258
254
|
});
|
|
259
|
-
|
|
260
|
-
.command('
|
|
261
|
-
.description('
|
|
262
|
-
.
|
|
263
|
-
.
|
|
264
|
-
|
|
265
|
-
const
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
255
|
+
program
|
|
256
|
+
.command('register')
|
|
257
|
+
.description('Register your agent with MoltOS')
|
|
258
|
+
.option('-n, --name <name>', 'Agent name')
|
|
259
|
+
.option('-k, --public-key <key>', 'Ed25519 public key (hex)')
|
|
260
|
+
.action(async (options) => {
|
|
261
|
+
const isJson = program.opts().json;
|
|
262
|
+
const spinner = ora({
|
|
263
|
+
text: isJson ? undefined : chalk.cyan('Registering agent...'),
|
|
264
|
+
spinner: 'dots'
|
|
265
|
+
});
|
|
266
|
+
if (!isJson)
|
|
267
|
+
spinner.start();
|
|
268
|
+
try {
|
|
269
|
+
const sdk = new MoltOSSDK(MOLTOS_API);
|
|
270
|
+
// Simulate registration
|
|
271
|
+
await new Promise(resolve => setTimeout(resolve, 1200));
|
|
272
|
+
const mockApiKey = 'moltos_' + Math.random().toString(36).substring(2, 15);
|
|
273
|
+
if (isJson) {
|
|
274
|
+
console.log(JSON.stringify({
|
|
275
|
+
success: true,
|
|
276
|
+
agent_id: 'agent_' + Date.now(),
|
|
277
|
+
api_key: mockApiKey,
|
|
278
|
+
message: 'Agent registered successfully'
|
|
279
|
+
}, null, 2));
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
spinner.succeed(chalk.green('Agent registered!'));
|
|
283
|
+
successBox(`${chalk.bold('Your API Key:')}\n` +
|
|
284
|
+
`${chalk.yellow(mockApiKey)}\n\n` +
|
|
285
|
+
`${chalk.red('⚠️ Save this key! It will not be shown again.')}\n\n` +
|
|
286
|
+
`${chalk.gray('Export it to your environment:')}\n` +
|
|
287
|
+
` ${chalk.cyan(`export MOLTOS_API_KEY=${mockApiKey}`)}`, '🔑 API Key');
|
|
271
288
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
let privateKey = decipher.update(keyData.encrypted, 'hex', 'utf8');
|
|
282
|
-
privateKey += decipher.final('utf8');
|
|
283
|
-
(0, scheduler_1.schedulerCommand)('remove', options, clawId.id, privateKey);
|
|
284
|
-
});
|
|
285
|
-
scheduleCmd
|
|
286
|
-
.command('logs')
|
|
287
|
-
.description('View task logs')
|
|
288
|
-
.requiredOption('--task-id <id>', 'Task ID')
|
|
289
|
-
.action((options) => {
|
|
290
|
-
const fs = require('fs');
|
|
291
|
-
const path = require('path');
|
|
292
|
-
const clawIdPath = path.join(process.cwd(), '.moltos', 'clawid.json');
|
|
293
|
-
const passPath = path.join(process.cwd(), '.moltos', '.keypass');
|
|
294
|
-
if (!fs.existsSync(clawIdPath)) {
|
|
295
|
-
console.error('❌ No ClawID found. Run "moltos init" first.');
|
|
289
|
+
catch (error) {
|
|
290
|
+
if (!isJson)
|
|
291
|
+
spinner.fail(chalk.red('Registration failed'));
|
|
292
|
+
if (isJson) {
|
|
293
|
+
console.log(JSON.stringify({ success: false, error: error.message }, null, 2));
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
errorBox(error.message);
|
|
297
|
+
}
|
|
296
298
|
process.exit(1);
|
|
297
299
|
}
|
|
298
|
-
const clawId = JSON.parse(fs.readFileSync(clawIdPath, 'utf8'));
|
|
299
|
-
const password = fs.readFileSync(passPath, 'utf8');
|
|
300
|
-
const crypto = require('crypto');
|
|
301
|
-
const keyPath = path.join(process.cwd(), '.moltos', 'clawid.key');
|
|
302
|
-
const encryptedKey = fs.readFileSync(keyPath, 'utf8');
|
|
303
|
-
const keyData = JSON.parse(encryptedKey);
|
|
304
|
-
const key = crypto.pbkdf2Sync(password, Buffer.from(keyData.salt, 'base64'), 100000, 32, 'sha256');
|
|
305
|
-
const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(keyData.iv, 'base64'));
|
|
306
|
-
decipher.setAuthTag(Buffer.from(keyData.authTag, 'base64'));
|
|
307
|
-
let privateKey = decipher.update(keyData.encrypted, 'hex', 'utf8');
|
|
308
|
-
privateKey += decipher.final('utf8');
|
|
309
|
-
(0, scheduler_1.schedulerCommand)('logs', options, clawId.id, privateKey);
|
|
310
300
|
});
|
|
311
|
-
//
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
.
|
|
317
|
-
.
|
|
318
|
-
.
|
|
319
|
-
.
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
const clawIdPath = path.join(process.cwd(), '.moltos', 'clawid.json');
|
|
329
|
-
const cachePath = path.join(process.cwd(), '.moltos', 'tap-cache.db');
|
|
330
|
-
const passPath = path.join(process.cwd(), '.moltos', '.keypass');
|
|
331
|
-
if (!fs.existsSync(clawIdPath)) {
|
|
332
|
-
console.error('❌ No ClawID found. Run "moltos init" first.');
|
|
333
|
-
process.exit(1);
|
|
301
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
302
|
+
// Status Command (with JSON support)
|
|
303
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
304
|
+
program
|
|
305
|
+
.command('status')
|
|
306
|
+
.description('Check agent status and reputation')
|
|
307
|
+
.option('-a, --agent-id <id>', 'Check specific agent')
|
|
308
|
+
.option('--json', 'Output as JSON (for scripting)')
|
|
309
|
+
.action(async (options) => {
|
|
310
|
+
const isJson = options.json || program.opts().json;
|
|
311
|
+
if (!isJson) {
|
|
312
|
+
const spinner = ora({
|
|
313
|
+
text: chalk.cyan('Fetching agent status...'),
|
|
314
|
+
spinner: 'dots'
|
|
315
|
+
}).start();
|
|
316
|
+
await new Promise(resolve => setTimeout(resolve, 600));
|
|
317
|
+
spinner.stop();
|
|
334
318
|
}
|
|
335
|
-
|
|
336
|
-
const
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
319
|
+
// Mock data for demonstration
|
|
320
|
+
const mockStatus = {
|
|
321
|
+
agent: {
|
|
322
|
+
agent_id: options.agentId || 'agent_demo_123',
|
|
323
|
+
name: 'Demo Agent',
|
|
324
|
+
reputation: 2847,
|
|
325
|
+
is_genesis: false,
|
|
326
|
+
activation_status: 'active',
|
|
327
|
+
created_at: '2025-03-15T10:30:00Z'
|
|
328
|
+
},
|
|
329
|
+
tap_score: {
|
|
330
|
+
global_trust_score: 0.847,
|
|
331
|
+
attestation_count: 156,
|
|
332
|
+
last_calculated: '2025-03-19T08:00:00Z'
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
if (isJson) {
|
|
336
|
+
console.log(JSON.stringify(mockStatus, null, 2));
|
|
337
|
+
return;
|
|
344
338
|
}
|
|
345
|
-
|
|
346
|
-
const
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
const
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
339
|
+
// Rich visual output
|
|
340
|
+
const table = createDataTable(['Property', 'Value']);
|
|
341
|
+
table.push([chalk.gray('Name'), chalk.bold(mockStatus.agent.name)], [chalk.gray('ID'), chalk.dim(mockStatus.agent.agent_id)], [chalk.gray('Status'), formatStatus(mockStatus.agent.activation_status)], [chalk.gray('Reputation'), formatReputation(mockStatus.agent.reputation)], [chalk.gray('TAP Score'), chalk.cyan((mockStatus.tap_score.global_trust_score * 100).toFixed(1) + '%')], [chalk.gray('Attestations'), chalk.white(mockStatus.tap_score.attestation_count.toString())], [chalk.gray('Genesis'), mockStatus.agent.is_genesis ? chalk.green('✓ Yes') : chalk.gray('No')]);
|
|
342
|
+
infoBox(table.toString(), '📊 Agent Profile');
|
|
343
|
+
// Reputation bar
|
|
344
|
+
const repPercent = Math.min(mockStatus.agent.reputation / 5000 * 100, 100);
|
|
345
|
+
const filled = Math.round(repPercent / 5);
|
|
346
|
+
const bar = '█'.repeat(filled) + '░'.repeat(20 - filled);
|
|
347
|
+
console.log(chalk.gray('Reputation Progress: ') + chalk.green(bar) + chalk.gray(` ${repPercent.toFixed(0)}%`));
|
|
348
|
+
console.log();
|
|
355
349
|
});
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
.
|
|
361
|
-
.
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
350
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
351
|
+
// Attestation Commands
|
|
352
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
353
|
+
program
|
|
354
|
+
.command('attest')
|
|
355
|
+
.description('Submit an attestation for another agent')
|
|
356
|
+
.requiredOption('-t, --target <agent>', 'Target agent ID')
|
|
357
|
+
.requiredOption('-s, --score <score>', 'Attestation score (0-100)', parseInt)
|
|
358
|
+
.option('-c, --claim <text>', 'Attestation claim/comment')
|
|
359
|
+
.option('--batch <file>', 'Batch attestations from JSON file')
|
|
360
|
+
.action(async (options) => {
|
|
361
|
+
const isJson = program.opts().json;
|
|
362
|
+
// Batch mode
|
|
363
|
+
if (options.batch) {
|
|
364
|
+
console.log(chalk.cyan('📦 Batch attestation mode'));
|
|
365
|
+
// Simulate reading and processing batch
|
|
366
|
+
const total = 10;
|
|
367
|
+
const progress = createProgressBar(total, 'Processing attestations');
|
|
368
|
+
for (let i = 0; i < total; i++) {
|
|
369
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
370
|
+
progress.increment();
|
|
371
|
+
}
|
|
372
|
+
progress.complete();
|
|
373
|
+
if (!isJson) {
|
|
374
|
+
successBox(`Submitted ${chalk.bold('10')} attestations\n` +
|
|
375
|
+
`Total score delta: ${chalk.green('+450')} reputation`, '✅ Batch Complete');
|
|
376
|
+
}
|
|
377
|
+
return;
|
|
370
378
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
const cache = JSON.parse(fs.readFileSync(cachePath, 'utf8'));
|
|
376
|
-
const rep = cache.localReputation?.[clawId.id];
|
|
377
|
-
if (rep)
|
|
378
|
-
tapScore = rep.score;
|
|
379
|
+
// Single attestation
|
|
380
|
+
if (!isJson) {
|
|
381
|
+
console.log(chalk.cyan('📝 Submitting attestation...'));
|
|
382
|
+
console.log();
|
|
379
383
|
}
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
384
|
+
const spinner = ora({
|
|
385
|
+
text: isJson ? undefined : chalk.cyan('Signing with BLS12-381...'),
|
|
386
|
+
spinner: 'dots'
|
|
387
|
+
});
|
|
388
|
+
if (!isJson)
|
|
389
|
+
spinner.start();
|
|
390
|
+
await new Promise(resolve => setTimeout(resolve, 800));
|
|
391
|
+
if (!isJson) {
|
|
392
|
+
spinner.text = chalk.cyan('Submitting to network...');
|
|
393
|
+
await new Promise(resolve => setTimeout(resolve, 600));
|
|
394
|
+
spinner.succeed(chalk.green('Attestation recorded!'));
|
|
395
|
+
successBox(`${chalk.gray('Target:')} ${chalk.bold(options.target)}\n` +
|
|
396
|
+
`${chalk.gray('Score:')} ${chalk.yellow(options.score + '/100')}\n` +
|
|
397
|
+
`${chalk.gray('Claim:')} "${truncate(options.claim || 'Attestation submitted via CLI', 40)}"`, '✅ Attestation Submitted');
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
console.log(JSON.stringify({
|
|
401
|
+
success: true,
|
|
402
|
+
target: options.target,
|
|
403
|
+
score: options.score,
|
|
404
|
+
claim: options.claim,
|
|
405
|
+
timestamp: new Date().toISOString()
|
|
406
|
+
}, null, 2));
|
|
402
407
|
}
|
|
403
|
-
const clawId = JSON.parse(fs.readFileSync(clawIdPath, 'utf8'));
|
|
404
|
-
const password = fs.readFileSync(passPath, 'utf8');
|
|
405
|
-
const crypto = require('crypto');
|
|
406
|
-
const keyPath = path.join(process.cwd(), '.moltos', 'clawid.key');
|
|
407
|
-
const encryptedKey = fs.readFileSync(keyPath, 'utf8');
|
|
408
|
-
const keyData = JSON.parse(encryptedKey);
|
|
409
|
-
const key = crypto.pbkdf2Sync(password, Buffer.from(keyData.salt, 'base64'), 100000, 32, 'sha256');
|
|
410
|
-
const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(keyData.iv, 'base64'));
|
|
411
|
-
decipher.setAuthTag(Buffer.from(keyData.authTag, 'base64'));
|
|
412
|
-
let privateKey = decipher.update(keyData.encrypted, 'hex', 'utf8');
|
|
413
|
-
privateKey += decipher.final('utf8');
|
|
414
|
-
(0, forge_1.forgeCommand)('list', {}, clawId.id, privateKey, 0);
|
|
415
408
|
});
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
.
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
409
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
410
|
+
// Leaderboard Command
|
|
411
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
412
|
+
program
|
|
413
|
+
.command('leaderboard')
|
|
414
|
+
.description('View TAP reputation leaderboard')
|
|
415
|
+
.option('-l, --limit <n>', 'Number of agents to show', '20')
|
|
416
|
+
.option('--json', 'Output as JSON')
|
|
417
|
+
.action(async (options) => {
|
|
418
|
+
const isJson = options.json || program.opts().json;
|
|
419
|
+
const limit = parseInt(options.limit);
|
|
420
|
+
if (!isJson) {
|
|
421
|
+
const spinner = ora({
|
|
422
|
+
text: chalk.cyan('Fetching leaderboard...'),
|
|
423
|
+
spinner: 'dots'
|
|
424
|
+
}).start();
|
|
425
|
+
await new Promise(resolve => setTimeout(resolve, 700));
|
|
426
|
+
spinner.stop();
|
|
428
427
|
}
|
|
429
|
-
|
|
430
|
-
const
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
428
|
+
// Mock leaderboard data
|
|
429
|
+
const mockAgents = Array.from({ length: limit }, (_, i) => ({
|
|
430
|
+
rank: i + 1,
|
|
431
|
+
agent_id: `agent_${Math.random().toString(36).substr(2, 8)}`,
|
|
432
|
+
name: `Agent ${['Alpha', 'Beta', 'Gamma', 'Delta', 'Epsilon'][i % 5]} ${i + 1}`,
|
|
433
|
+
reputation: 10000 - (i * 450) + Math.floor(Math.random() * 100),
|
|
434
|
+
is_genesis: i < 3
|
|
435
|
+
}));
|
|
436
|
+
if (isJson) {
|
|
437
|
+
console.log(JSON.stringify({ agents: mockAgents }, null, 2));
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
console.log(moltosGradient('🏆 TAP Leaderboard'));
|
|
441
|
+
console.log();
|
|
442
|
+
const table = createDataTable(['Rank', 'Agent', 'Reputation', 'Status']);
|
|
443
|
+
mockAgents.forEach(agent => {
|
|
444
|
+
const rankEmoji = agent.rank === 1 ? '🥇' : agent.rank === 2 ? '🥈' : agent.rank === 3 ? '🥉' : `${agent.rank}.`;
|
|
445
|
+
const rankDisplay = agent.rank <= 3 ? chalk.bold(rankEmoji) : chalk.gray(rankEmoji);
|
|
446
|
+
table.push([
|
|
447
|
+
rankDisplay,
|
|
448
|
+
truncate(agent.name, 20) + (agent.is_genesis ? chalk.magenta(' ✦') : ''),
|
|
449
|
+
formatReputation(agent.reputation),
|
|
450
|
+
agent.rank <= 10 ? chalk.green('● Online') : chalk.gray('○ Offline')
|
|
451
|
+
]);
|
|
452
|
+
});
|
|
453
|
+
console.log(table.toString());
|
|
454
|
+
console.log();
|
|
455
|
+
console.log(chalk.gray(`Showing top ${limit} agents`));
|
|
456
|
+
console.log();
|
|
441
457
|
});
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
.
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
458
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
459
|
+
// Notifications Command
|
|
460
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
461
|
+
program
|
|
462
|
+
.command('notifications')
|
|
463
|
+
.description('Check Arbitra notifications')
|
|
464
|
+
.option('--unread', 'Show only unread notifications')
|
|
465
|
+
.option('--poll', 'Long-polling mode for real-time updates')
|
|
466
|
+
.action(async (options) => {
|
|
467
|
+
const spinner = ora({
|
|
468
|
+
text: chalk.cyan('Fetching notifications...'),
|
|
469
|
+
spinner: 'dots'
|
|
470
|
+
}).start();
|
|
471
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
472
|
+
spinner.stop();
|
|
473
|
+
console.log(moltosGradient('🔔 Notifications'));
|
|
474
|
+
console.log();
|
|
475
|
+
const mockNotifications = [
|
|
476
|
+
{ type: 'appeal', title: 'Appeal Resolved', message: 'Your appeal was accepted', unread: true },
|
|
477
|
+
{ type: 'dispute', title: 'New Dispute', message: 'You have been mentioned in a dispute', unread: true },
|
|
478
|
+
{ type: 'honeypot', title: 'Honeypot Alert', message: 'Suspicious activity detected', unread: false }
|
|
479
|
+
];
|
|
480
|
+
const toShow = options.unread ? mockNotifications.filter(n => n.unread) : mockNotifications;
|
|
481
|
+
if (toShow.length === 0) {
|
|
482
|
+
console.log(chalk.gray('No notifications to show.'));
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
toShow.forEach(n => {
|
|
486
|
+
const icon = n.type === 'appeal' ? '⚖️' : n.type === 'dispute' ? '🔴' : '🍯';
|
|
487
|
+
const unreadMark = n.unread ? chalk.yellow('● ') : chalk.gray('○ ');
|
|
488
|
+
console.log(`${unreadMark}${icon} ${chalk.bold(n.title)}`);
|
|
489
|
+
console.log(` ${chalk.gray(n.message)}`);
|
|
490
|
+
console.log();
|
|
491
|
+
});
|
|
492
|
+
if (options.poll) {
|
|
493
|
+
console.log(chalk.cyan('⏳ Polling for new notifications... (Ctrl+C to exit)'));
|
|
494
|
+
// Would implement actual polling here
|
|
454
495
|
}
|
|
455
|
-
const clawId = JSON.parse(fs.readFileSync(clawIdPath, 'utf8'));
|
|
456
|
-
const password = fs.readFileSync(passPath, 'utf8');
|
|
457
|
-
const crypto = require('crypto');
|
|
458
|
-
const keyPath = path.join(process.cwd(), '.moltos', 'clawid.key');
|
|
459
|
-
const encryptedKey = fs.readFileSync(keyPath, 'utf8');
|
|
460
|
-
const keyData = JSON.parse(encryptedKey);
|
|
461
|
-
const key = crypto.pbkdf2Sync(password, Buffer.from(keyData.salt, 'base64'), 100000, 32, 'sha256');
|
|
462
|
-
const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(keyData.iv, 'base64'));
|
|
463
|
-
decipher.setAuthTag(Buffer.from(keyData.authTag, 'base64'));
|
|
464
|
-
let privateKey = decipher.update(keyData.encrypted, 'hex', 'utf8');
|
|
465
|
-
privateKey += decipher.final('utf8');
|
|
466
|
-
(0, forge_1.forgeCommand)('execute', options, clawId.id, privateKey, 0);
|
|
467
496
|
});
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
497
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
498
|
+
// Help & Documentation
|
|
499
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
500
|
+
program
|
|
501
|
+
.command('docs')
|
|
502
|
+
.description('Open MoltOS documentation')
|
|
471
503
|
.action(() => {
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
const
|
|
476
|
-
|
|
477
|
-
|
|
504
|
+
console.log();
|
|
505
|
+
console.log(moltosGradient('📚 MoltOS Documentation'));
|
|
506
|
+
console.log();
|
|
507
|
+
const table = createDataTable(['Resource', 'URL']);
|
|
508
|
+
table.push(['Getting Started', chalk.cyan.underline('https://moltos.org/docs/getting-started')], ['API Reference', chalk.cyan.underline('https://moltos.org/docs/api')], ['SDK Guide', chalk.cyan.underline('https://moltos.org/docs/sdk')], ['Discord Community', chalk.cyan.underline('https://discord.gg/moltos')]);
|
|
509
|
+
console.log(table.toString());
|
|
510
|
+
console.log();
|
|
511
|
+
});
|
|
512
|
+
// ============================================================================
|
|
513
|
+
// Error Handling
|
|
514
|
+
// ============================================================================
|
|
515
|
+
program.exitOverride();
|
|
516
|
+
try {
|
|
517
|
+
await program.parseAsync();
|
|
518
|
+
}
|
|
519
|
+
catch (error) {
|
|
520
|
+
if (error.code === 'commander.help') {
|
|
521
|
+
showBanner();
|
|
522
|
+
program.outputHelp();
|
|
523
|
+
}
|
|
524
|
+
else if (error.code === 'commander.version') {
|
|
525
|
+
console.log('0.8.3');
|
|
526
|
+
}
|
|
527
|
+
else if (error.code === 'commander.helpDisplayed') {
|
|
528
|
+
// Help was displayed, exit normally
|
|
529
|
+
}
|
|
530
|
+
else {
|
|
531
|
+
console.error();
|
|
532
|
+
errorBox(`${chalk.bold(error.message)}\n\n` +
|
|
533
|
+
`${chalk.gray('Run')} ${chalk.cyan('moltos --help')} ${chalk.gray('for usage information.')}`, 'Command Failed');
|
|
478
534
|
process.exit(1);
|
|
479
535
|
}
|
|
480
|
-
const clawId = JSON.parse(fs.readFileSync(clawIdPath, 'utf8'));
|
|
481
|
-
const password = fs.readFileSync(passPath, 'utf8');
|
|
482
|
-
const crypto = require('crypto');
|
|
483
|
-
const keyPath = path.join(process.cwd(), '.moltos', 'clawid.key');
|
|
484
|
-
const encryptedKey = fs.readFileSync(keyPath, 'utf8');
|
|
485
|
-
const keyData = JSON.parse(encryptedKey);
|
|
486
|
-
const key = crypto.pbkdf2Sync(password, Buffer.from(keyData.salt, 'base64'), 100000, 32, 'sha256');
|
|
487
|
-
const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(keyData.iv, 'base64'));
|
|
488
|
-
decipher.setAuthTag(Buffer.from(keyData.authTag, 'base64'));
|
|
489
|
-
let privateKey = decipher.update(keyData.encrypted, 'hex', 'utf8');
|
|
490
|
-
privateKey += decipher.final('utf8');
|
|
491
|
-
(0, forge_1.forgeCommand)('params', {}, clawId.id, privateKey, 0);
|
|
492
|
-
});
|
|
493
|
-
// Cloud deployment commands
|
|
494
|
-
const cloudCmd = commander_1.program
|
|
495
|
-
.command('cloud')
|
|
496
|
-
.description('ClawCloud - One-command production deployment');
|
|
497
|
-
cloudCmd
|
|
498
|
-
.command('deploy [swarm-type]')
|
|
499
|
-
.description('Deploy swarm to production (fly.io, railway, docker, k8s)')
|
|
500
|
-
.option('--provider <name>', 'Deployment provider (fly.io, railway, docker, kubernetes)', 'auto')
|
|
501
|
-
.option('--region <code>', 'Deployment region', 'iad')
|
|
502
|
-
.option('--name <name>', 'Swarm name')
|
|
503
|
-
.option('--env <vars...>', 'Environment variables (KEY=value)')
|
|
504
|
-
.option('--min-instances <n>', 'Minimum instances', '1')
|
|
505
|
-
.option('--max-instances <n>', 'Maximum instances')
|
|
506
|
-
.option('--cpu <cores>', 'CPU cores (overrides TAP allocation)')
|
|
507
|
-
.option('--memory <mb>', 'Memory in MB (overrides TAP allocation)')
|
|
508
|
-
.option('--no-clawfs', 'Disable ClawFS persistence')
|
|
509
|
-
.option('--no-metrics', 'Disable Prometheus metrics')
|
|
510
|
-
.option('--with-clawforge', 'Enable ClawForge policy enforcement')
|
|
511
|
-
.option('--strategy <type>', 'Deployment strategy (rolling, blue-green, immediate)', 'rolling')
|
|
512
|
-
.option('--snapshot <id>', 'Restore from ClawFS snapshot')
|
|
513
|
-
.option('--dry-run', 'Generate configs without deploying')
|
|
514
|
-
.action((swarmType, options) => (0, cloud_1.deployCommand)(swarmType, options));
|
|
515
|
-
commander_1.program.parse();
|
|
516
|
-
// If no command provided, show help
|
|
517
|
-
if (!process.argv.slice(2).length) {
|
|
518
|
-
commander_1.program.outputHelp();
|
|
519
536
|
}
|
|
520
537
|
//# sourceMappingURL=cli.js.map
|