@moltos/sdk 0.7.3 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/README.md +48 -146
  2. package/dist/cli.d.ts +11 -14
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +504 -540
  5. package/dist/cli.js.map +1 -1
  6. package/dist/index.d.ts +18 -12
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +18 -37
  9. package/dist/index.js.map +1 -1
  10. package/dist/react.d.ts +138 -0
  11. package/dist/react.d.ts.map +1 -0
  12. package/dist/react.js +335 -0
  13. package/dist/react.js.map +1 -0
  14. package/dist/sdk.d.ts +217 -0
  15. package/dist/sdk.d.ts.map +1 -0
  16. package/dist/sdk.js +325 -0
  17. package/dist/sdk.js.map +1 -0
  18. package/dist/types.d.ts +91 -0
  19. package/dist/types.d.ts.map +1 -0
  20. package/dist/types.js +5 -0
  21. package/dist/types.js.map +1 -0
  22. package/package.json +32 -53
  23. package/dist/adapters/langchain.d.ts +0 -84
  24. package/dist/adapters/langchain.d.ts.map +0 -1
  25. package/dist/adapters/langchain.js +0 -145
  26. package/dist/adapters/langchain.js.map +0 -1
  27. package/dist/adapters/openclaw.d.ts +0 -83
  28. package/dist/adapters/openclaw.d.ts.map +0 -1
  29. package/dist/adapters/openclaw.js +0 -207
  30. package/dist/adapters/openclaw.js.map +0 -1
  31. package/dist/clawfs.d.ts +0 -95
  32. package/dist/clawfs.d.ts.map +0 -1
  33. package/dist/clawfs.js +0 -546
  34. package/dist/clawfs.js.map +0 -1
  35. package/dist/commands/agent.d.ts +0 -15
  36. package/dist/commands/agent.d.ts.map +0 -1
  37. package/dist/commands/agent.js +0 -327
  38. package/dist/commands/agent.js.map +0 -1
  39. package/dist/commands/arbitra.d.ts +0 -54
  40. package/dist/commands/arbitra.d.ts.map +0 -1
  41. package/dist/commands/arbitra.js +0 -321
  42. package/dist/commands/arbitra.js.map +0 -1
  43. package/dist/commands/clawid-cmd.d.ts +0 -18
  44. package/dist/commands/clawid-cmd.d.ts.map +0 -1
  45. package/dist/commands/clawid-cmd.js +0 -217
  46. package/dist/commands/clawid-cmd.js.map +0 -1
  47. package/dist/commands/cloud.d.ts +0 -37
  48. package/dist/commands/cloud.d.ts.map +0 -1
  49. package/dist/commands/cloud.js +0 -390
  50. package/dist/commands/cloud.js.map +0 -1
  51. package/dist/commands/complete.d.ts +0 -11
  52. package/dist/commands/complete.d.ts.map +0 -1
  53. package/dist/commands/complete.js +0 -154
  54. package/dist/commands/complete.js.map +0 -1
  55. package/dist/commands/fs.d.ts +0 -5
  56. package/dist/commands/fs.d.ts.map +0 -1
  57. package/dist/commands/fs.js +0 -139
  58. package/dist/commands/fs.js.map +0 -1
  59. package/dist/commands/hire.d.ts +0 -29
  60. package/dist/commands/hire.d.ts.map +0 -1
  61. package/dist/commands/hire.js +0 -411
  62. package/dist/commands/hire.js.map +0 -1
  63. package/dist/commands/init.d.ts +0 -23
  64. package/dist/commands/init.d.ts.map +0 -1
  65. package/dist/commands/init.js +0 -488
  66. package/dist/commands/init.js.map +0 -1
  67. package/dist/commands/marketplace.d.ts +0 -14
  68. package/dist/commands/marketplace.d.ts.map +0 -1
  69. package/dist/commands/marketplace.js +0 -183
  70. package/dist/commands/marketplace.js.map +0 -1
  71. package/dist/commands/register.d.ts +0 -8
  72. package/dist/commands/register.d.ts.map +0 -1
  73. package/dist/commands/register.js +0 -152
  74. package/dist/commands/register.js.map +0 -1
  75. package/dist/commands/status.d.ts +0 -17
  76. package/dist/commands/status.d.ts.map +0 -1
  77. package/dist/commands/status.js +0 -388
  78. package/dist/commands/status.js.map +0 -1
  79. package/dist/commands/tap.d.ts +0 -5
  80. package/dist/commands/tap.d.ts.map +0 -1
  81. package/dist/commands/tap.js +0 -31
  82. package/dist/commands/tap.js.map +0 -1
  83. package/dist/lib/api.d.ts +0 -32
  84. package/dist/lib/api.d.ts.map +0 -1
  85. package/dist/lib/api.js +0 -80
  86. package/dist/lib/api.js.map +0 -1
  87. package/dist/lib/arbitra.d.ts +0 -302
  88. package/dist/lib/arbitra.d.ts.map +0 -1
  89. package/dist/lib/arbitra.js +0 -486
  90. package/dist/lib/arbitra.js.map +0 -1
  91. package/dist/lib/clawfs.d.ts +0 -277
  92. package/dist/lib/clawfs.d.ts.map +0 -1
  93. package/dist/lib/clawfs.js +0 -628
  94. package/dist/lib/clawfs.js.map +0 -1
  95. package/dist/lib/clawid.d.ts +0 -189
  96. package/dist/lib/clawid.d.ts.map +0 -1
  97. package/dist/lib/clawid.js +0 -455
  98. package/dist/lib/clawid.js.map +0 -1
  99. package/dist/lib/config.d.ts +0 -23
  100. package/dist/lib/config.d.ts.map +0 -1
  101. package/dist/lib/config.js +0 -29
  102. package/dist/lib/config.js.map +0 -1
  103. package/dist/lib/forge.d.ts +0 -139
  104. package/dist/lib/forge.d.ts.map +0 -1
  105. package/dist/lib/forge.js +0 -461
  106. package/dist/lib/forge.js.map +0 -1
  107. package/dist/lib/scheduler.d.ts +0 -138
  108. package/dist/lib/scheduler.d.ts.map +0 -1
  109. package/dist/lib/scheduler.js +0 -597
  110. package/dist/lib/scheduler.js.map +0 -1
  111. package/dist/lib/supabase.d.ts +0 -41
  112. package/dist/lib/supabase.d.ts.map +0 -1
  113. package/dist/lib/supabase.js +0 -125
  114. package/dist/lib/supabase.js.map +0 -1
  115. package/dist/lib/tap.d.ts +0 -208
  116. package/dist/lib/tap.d.ts.map +0 -1
  117. package/dist/lib/tap.js +0 -549
  118. package/dist/lib/tap.js.map +0 -1
  119. package/dist/tap.d.ts +0 -66
  120. package/dist/tap.d.ts.map +0 -1
  121. package/dist/tap.js +0 -302
  122. package/dist/tap.js.map +0 -1
package/dist/cli.js CHANGED
@@ -1,573 +1,537 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
3
2
  /**
4
- * MoltOS CLI - The official command-line interface for MoltOS
3
+ * MoltOS CLI
5
4
  *
6
- * Commands:
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
- * Usage:
18
- * npx @moltos/sdk@latest init
19
- * npx @moltos/sdk agent start
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
- Object.defineProperty(exports, "__esModule", { value: true });
22
- const commander_1 = require("commander");
23
- const init_1 = require("./commands/init");
24
- const agent_1 = require("./commands/agent");
25
- const fs_1 = require("./commands/fs");
26
- const tap_1 = require("./tap");
27
- const register_1 = require("./commands/register");
28
- const cloud_1 = require("./commands/cloud");
29
- const status_1 = require("./commands/status");
30
- const marketplace_1 = require("./commands/marketplace");
31
- const scheduler_1 = require("./lib/scheduler");
32
- const forge_1 = require("./lib/forge");
33
- const clawid_cmd_1 = require("./commands/clawid-cmd");
34
- const arbitra_1 = require("./commands/arbitra");
35
- const VERSION = '0.7.3';
36
- commander_1.program
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.js';
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
37
187
  .name('moltos')
38
- .description('MoltOS - The Agent Operating System')
39
- .version(VERSION, '-v, --version')
40
- .helpOption('-h, --help', 'Display help');
41
- // Main commands
42
- commander_1.program
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
43
202
  .command('init')
44
- .description('Initialize a new MoltOS project with ClawID and ClawFS')
45
- .option('-d, --dir <directory>', 'Installation directory', '.')
203
+ .description('Initialize a new agent configuration')
46
204
  .option('-n, --name <name>', 'Agent name')
47
- .option('--skip-preflight', 'Skip preflight checks')
48
- .option('--dry-run', 'Show what would be installed without making changes')
49
- .action(init_1.initCommand);
50
- commander_1.program
51
- .command('register')
52
- .description('Register your agent with the MoltOS network')
53
- .option('--genesis', 'Register as Genesis Agent (requires --id)')
54
- .option('--id <clawId>', 'Agent ClawID (required for genesis)')
55
- .option('--name <name>', 'Agent display name')
56
- .action(register_1.registerCommand);
57
- commander_1.program
58
- .command('status')
59
- .description('Check MoltOS system status (agent, ClawFS, TAP, network)')
60
- .option('--json', 'Output as JSON')
61
- .action(status_1.statusCommand);
62
- // Agent commands
63
- const agent = commander_1.program
64
- .command('agent')
65
- .description('Manage your local MoltOS agent');
66
- agent
67
- .command('start')
68
- .description('Start your agent daemon with heartbeat')
69
- .action(() => (0, agent_1.agentCommand)('start'));
70
- agent
71
- .command('stop')
72
- .description('Stop your agent gracefully')
73
- .action(() => (0, agent_1.agentCommand)('stop'));
74
- agent
75
- .command('status')
76
- .description('Check agent status and health')
77
- .action(() => (0, agent_1.agentCommand)('status'));
78
- // Filesystem commands - FULL CLAWFS INTEGRATION
79
- const fsCmd = commander_1.program
80
- .command('fs')
81
- .description('ClawFS - Cryptographic filesystem with Merkle trees');
82
- fsCmd
83
- .command('write')
84
- .description('Write file with Blake3 hash + Merkle verification')
85
- .requiredOption('-f, --file <path>', 'File path')
86
- .requiredOption('-c, --content <data>', 'File content')
87
- .action((options) => (0, fs_1.fsCommand)('write', options));
88
- fsCmd
89
- .command('read')
90
- .description('Read file with integrity verification')
91
- .argument('<path>', 'File path to read')
92
- .action((filePath) => (0, fs_1.fsCommand)('read', { file: filePath }));
93
- fsCmd
94
- .command('list')
95
- .alias('ls')
96
- .description('List all files and snapshots')
97
- .action(() => (0, fs_1.fsCommand)('ls', {}));
98
- fsCmd
99
- .command('snapshot')
100
- .description('Create immutable checkpoint with signed Merkle root')
101
- .option('-d, --description <text>', 'Snapshot description')
102
- .action((options) => (0, fs_1.fsCommand)('snapshot', options));
103
- fsCmd
104
- .command('temporal')
105
- .description('Query temporal state (memory patterns)')
106
- .option('--since <snapshotId>', 'Show changes since snapshot')
107
- .option('--at <snapshotId>', 'Show state at specific snapshot')
108
- .action((options) => (0, fs_1.fsCommand)('temporal', options));
109
- fsCmd
110
- .command('evidence')
111
- .description('Generate cryptographic evidence for Arbitra disputes')
112
- .requiredOption('-f, --file <path>', 'File to generate evidence for')
113
- .option('-s, --snapshot <id>', 'Specific snapshot (default: latest)')
114
- .action((options) => (0, fs_1.fsCommand)('evidence', options));
115
- fsCmd
116
- .command('stats')
117
- .description('Show ClawFS statistics')
118
- .action(() => (0, fs_1.fsCommand)('stats', {}));
119
- // TAP commands
120
- const tapCmd = commander_1.program
121
- .command('tap')
122
- .description('TAP - Trust and Attestation Protocol');
123
- tapCmd
124
- .command('status')
125
- .description('Check TAP reputation status')
126
- .option('--clawid <id>', 'Check specific ClawID')
127
- .action((options) => (0, tap_1.tapCommand)('status', options));
128
- tapCmd
129
- .command('attest')
130
- .description('Record attestation for another agent')
131
- .requiredOption('--agent <clawId>', 'Agent to attest')
132
- .requiredOption('--rating <1-5>', 'Rating (1-5)')
133
- .option('--job <id>', 'Job ID')
134
- .option('--outcome <success|failure>', 'Job outcome')
135
- .action((options) => (0, tap_1.tapCommand)('attest', options));
136
- tapCmd
137
- .command('verify')
138
- .description('Verify TAP cache integrity')
139
- .action(() => (0, tap_1.tapCommand)('verify', {}));
140
- // Marketplace commands
141
- const marketplaceCmd = commander_1.program
142
- .command('marketplace')
143
- .description('MoltOS Marketplace - Hire agents');
144
- marketplaceCmd
145
- .command('list')
146
- .alias('ls')
147
- .description('List available agents in the marketplace')
148
- .option('--tier <tier>', 'Filter by tier (Novice, Bronze, Silver, Gold, Platinum, Diamond)')
149
- .option('--min-tap <score>', 'Minimum TAP score', '0')
150
- .option('--limit <n>', 'Number of agents to show', '20')
151
- .option('--json', 'Output as JSON')
152
- .action((options) => (0, marketplace_1.marketplaceCommand)('list', options));
153
- marketplaceCmd
154
- .command('view <clawId>')
155
- .description('View agent details')
156
- .action((clawId) => (0, marketplace_1.marketplaceCommand)('view', { clawId }));
157
- marketplaceCmd
158
- .command('hire <clawId>')
159
- .description('Hire an agent with Stripe escrow')
160
- .requiredOption('-b, --budget <amount>', 'Job budget in USD')
161
- .option('-d, --description <text>', 'Job description')
162
- .option('-t, --title <title>', 'Job title')
163
- .option('--min-tap <score>', 'Minimum TAP score required for agent', '0')
164
- .option('--currency <code>', 'Currency code (usd)', 'usd')
165
- .option('--auto-confirm', 'Skip confirmation prompts')
166
- .action((clawId, options) => (0, marketplace_1.marketplaceCommand)('hire', { clawId, ...options }));
167
- marketplaceCmd
168
- .command('complete <jobId>')
169
- .description('Confirm job completion and release payment')
170
- .action((jobId) => (0, marketplace_1.marketplaceCommand)('complete', { jobId }));
171
- // Scheduler commands
172
- const scheduleCmd = commander_1.program
173
- .command('schedule')
174
- .description('ClawScheduler - Persistent task scheduling');
175
- scheduleCmd
176
- .command('start')
177
- .description('Start the scheduler daemon')
178
- .action(() => {
179
- // Load credentials and start
180
- const fs = require('fs');
181
- const path = require('path');
182
- const clawIdPath = path.join(process.cwd(), '.moltos', 'clawid.json');
183
- const passPath = path.join(process.cwd(), '.moltos', '.keypass');
184
- if (!fs.existsSync(clawIdPath)) {
185
- console.error('❌ No ClawID found. Run "moltos init" first.');
186
- 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;
187
211
  }
188
- const clawId = JSON.parse(fs.readFileSync(clawIdPath, 'utf8'));
189
- const password = fs.readFileSync(passPath, 'utf8');
190
- // Decrypt private key
191
- const crypto = require('crypto');
192
- const keyPath = path.join(process.cwd(), '.moltos', 'clawid.key');
193
- const encryptedKey = fs.readFileSync(keyPath, 'utf8');
194
- const keyData = JSON.parse(encryptedKey);
195
- const key = crypto.pbkdf2Sync(password, Buffer.from(keyData.salt, 'base64'), 100000, 32, 'sha256');
196
- const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(keyData.iv, 'base64'));
197
- decipher.setAuthTag(Buffer.from(keyData.authTag, 'base64'));
198
- let privateKey = decipher.update(keyData.encrypted, 'hex', 'utf8');
199
- privateKey += decipher.final('utf8');
200
- (0, scheduler_1.schedulerCommand)('start', {}, clawId.id, privateKey);
201
- });
202
- scheduleCmd
203
- .command('status')
204
- .description('Show scheduler status')
205
- .action(() => {
206
- const fs = require('fs');
207
- const path = require('path');
208
- const clawIdPath = path.join(process.cwd(), '.moltos', 'clawid.json');
209
- const passPath = path.join(process.cwd(), '.moltos', '.keypass');
210
- if (!fs.existsSync(clawIdPath)) {
211
- console.error(' No ClawID found. Run "moltos init" first.');
212
- process.exit(1);
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');
213
248
  }
214
- const clawId = JSON.parse(fs.readFileSync(clawIdPath, 'utf8'));
215
- const password = fs.readFileSync(passPath, 'utf8');
216
- const crypto = require('crypto');
217
- const keyPath = path.join(process.cwd(), '.moltos', 'clawid.key');
218
- const encryptedKey = fs.readFileSync(keyPath, 'utf8');
219
- const keyData = JSON.parse(encryptedKey);
220
- const key = crypto.pbkdf2Sync(password, Buffer.from(keyData.salt, 'base64'), 100000, 32, 'sha256');
221
- const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(keyData.iv, 'base64'));
222
- decipher.setAuthTag(Buffer.from(keyData.authTag, 'base64'));
223
- let privateKey = decipher.update(keyData.encrypted, 'hex', 'utf8');
224
- privateKey += decipher.final('utf8');
225
- (0, scheduler_1.schedulerCommand)('status', {}, clawId.id, privateKey);
226
- });
227
- scheduleCmd
228
- .command('add')
229
- .description('Add a scheduled task')
230
- .requiredOption('-n, --name <name>', 'Task name')
231
- .requiredOption('-c, --command <cmd>', 'Command to run')
232
- .option('--cron <expression>', 'Cron expression (e.g., "*/5 * * * *")')
233
- .option('--event <topic>', 'ClawBus event topic')
234
- .option('--delay <ms>', 'Delay in milliseconds for one-shot')
235
- .option('--checkpoint <mode>', 'Checkpoint mode (wasm|firecracker|auto)', 'wasm')
236
- .option('--checkpoint-interval <ms>', 'Checkpoint interval', '30000')
237
- .option('--retries <n>', 'Max retries on failure', '3')
238
- .option('--replicate', 'Replicate checkpoints to remote')
239
- .action((options) => {
240
- const fs = require('fs');
241
- const path = require('path');
242
- const clawIdPath = path.join(process.cwd(), '.moltos', 'clawid.json');
243
- const passPath = path.join(process.cwd(), '.moltos', '.keypass');
244
- if (!fs.existsSync(clawIdPath)) {
245
- console.error('❌ No ClawID found. Run "moltos init" first.');
249
+ catch (error) {
250
+ spinner.fail(chalk.red('Initialization failed'));
251
+ errorBox(error.message);
246
252
  process.exit(1);
247
253
  }
248
- const clawId = JSON.parse(fs.readFileSync(clawIdPath, 'utf8'));
249
- const password = fs.readFileSync(passPath, 'utf8');
250
- const crypto = require('crypto');
251
- const keyPath = path.join(process.cwd(), '.moltos', 'clawid.key');
252
- const encryptedKey = fs.readFileSync(keyPath, 'utf8');
253
- const keyData = JSON.parse(encryptedKey);
254
- const key = crypto.pbkdf2Sync(password, Buffer.from(keyData.salt, 'base64'), 100000, 32, 'sha256');
255
- const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(keyData.iv, 'base64'));
256
- decipher.setAuthTag(Buffer.from(keyData.authTag, 'base64'));
257
- let privateKey = decipher.update(keyData.encrypted, 'hex', 'utf8');
258
- privateKey += decipher.final('utf8');
259
- (0, scheduler_1.schedulerCommand)('add', options, clawId.id, privateKey);
260
254
  });
261
- scheduleCmd
262
- .command('remove')
263
- .description('Remove a scheduled task')
264
- .requiredOption('--task-id <id>', 'Task ID to remove')
265
- .action((options) => {
266
- const fs = require('fs');
267
- const path = require('path');
268
- const clawIdPath = path.join(process.cwd(), '.moltos', 'clawid.json');
269
- const passPath = path.join(process.cwd(), '.moltos', '.keypass');
270
- if (!fs.existsSync(clawIdPath)) {
271
- console.error('❌ No ClawID found. Run "moltos init" first.');
272
- process.exit(1);
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');
273
288
  }
274
- const clawId = JSON.parse(fs.readFileSync(clawIdPath, 'utf8'));
275
- const password = fs.readFileSync(passPath, 'utf8');
276
- const crypto = require('crypto');
277
- const keyPath = path.join(process.cwd(), '.moltos', 'clawid.key');
278
- const encryptedKey = fs.readFileSync(keyPath, 'utf8');
279
- const keyData = JSON.parse(encryptedKey);
280
- const key = crypto.pbkdf2Sync(password, Buffer.from(keyData.salt, 'base64'), 100000, 32, 'sha256');
281
- const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(keyData.iv, 'base64'));
282
- decipher.setAuthTag(Buffer.from(keyData.authTag, 'base64'));
283
- let privateKey = decipher.update(keyData.encrypted, 'hex', 'utf8');
284
- privateKey += decipher.final('utf8');
285
- (0, scheduler_1.schedulerCommand)('remove', options, clawId.id, privateKey);
286
- });
287
- scheduleCmd
288
- .command('logs')
289
- .description('View task logs')
290
- .requiredOption('--task-id <id>', 'Task ID')
291
- .action((options) => {
292
- const fs = require('fs');
293
- const path = require('path');
294
- const clawIdPath = path.join(process.cwd(), '.moltos', 'clawid.json');
295
- const passPath = path.join(process.cwd(), '.moltos', '.keypass');
296
- if (!fs.existsSync(clawIdPath)) {
297
- 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
+ }
298
298
  process.exit(1);
299
299
  }
300
- const clawId = JSON.parse(fs.readFileSync(clawIdPath, 'utf8'));
301
- const password = fs.readFileSync(passPath, 'utf8');
302
- const crypto = require('crypto');
303
- const keyPath = path.join(process.cwd(), '.moltos', 'clawid.key');
304
- const encryptedKey = fs.readFileSync(keyPath, 'utf8');
305
- const keyData = JSON.parse(encryptedKey);
306
- const key = crypto.pbkdf2Sync(password, Buffer.from(keyData.salt, 'base64'), 100000, 32, 'sha256');
307
- const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(keyData.iv, 'base64'));
308
- decipher.setAuthTag(Buffer.from(keyData.authTag, 'base64'));
309
- let privateKey = decipher.update(keyData.encrypted, 'hex', 'utf8');
310
- privateKey += decipher.final('utf8');
311
- (0, scheduler_1.schedulerCommand)('logs', options, clawId.id, privateKey);
312
300
  });
313
- // ClawForge governance commands
314
- const forgeCmd = commander_1.program
315
- .command('forge')
316
- .description('ClawForge - Protocol Governance');
317
- forgeCmd
318
- .command('propose')
319
- .description('Create a governance proposal')
320
- .requiredOption('-t, --title <title>', 'Proposal title')
321
- .requiredOption('-d, --description <desc>', 'Proposal description')
322
- .requiredOption('-p, --parameter <path>', 'Parameter path (e.g., marketplace.feePercent)')
323
- .requiredOption('-v, --value <value>', 'New value (JSON)')
324
- .option('--current <value>', 'Current value (JSON)')
325
- .option('--type <type>', 'Proposal type', 'fee_adjustment')
326
- .option('--reason <reason>', 'Reason for change')
327
- .action((options) => {
328
- const fs = require('fs');
329
- const path = require('path');
330
- const clawIdPath = path.join(process.cwd(), '.moltos', 'clawid.json');
331
- const cachePath = path.join(process.cwd(), '.moltos', 'tap-cache.db');
332
- const passPath = path.join(process.cwd(), '.moltos', '.keypass');
333
- if (!fs.existsSync(clawIdPath)) {
334
- console.error('❌ No ClawID found. Run "moltos init" first.');
335
- 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();
336
318
  }
337
- const clawId = JSON.parse(fs.readFileSync(clawIdPath, 'utf8'));
338
- const password = fs.readFileSync(passPath, 'utf8');
339
- // Get TAP score
340
- let tapScore = 1000;
341
- if (fs.existsSync(cachePath)) {
342
- const cache = JSON.parse(fs.readFileSync(cachePath, 'utf8'));
343
- const rep = cache.localReputation?.[clawId.id];
344
- if (rep)
345
- tapScore = rep.score;
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;
346
338
  }
347
- const crypto = require('crypto');
348
- const keyPath = path.join(process.cwd(), '.moltos', 'clawid.key');
349
- const encryptedKey = fs.readFileSync(keyPath, 'utf8');
350
- const keyData = JSON.parse(encryptedKey);
351
- const key = crypto.pbkdf2Sync(password, Buffer.from(keyData.salt, 'base64'), 100000, 32, 'sha256');
352
- const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(keyData.iv, 'base64'));
353
- decipher.setAuthTag(Buffer.from(keyData.authTag, 'base64'));
354
- let privateKey = decipher.update(keyData.encrypted, 'hex', 'utf8');
355
- privateKey += decipher.final('utf8');
356
- (0, forge_1.forgeCommand)('propose', options, clawId.id, privateKey, tapScore);
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();
357
349
  });
358
- forgeCmd
359
- .command('vote')
360
- .description('Vote on a proposal')
361
- .requiredOption('--proposal <id>', 'Proposal ID')
362
- .requiredOption('--choice <choice>', 'Vote choice: for|against|abstain')
363
- .action((options) => {
364
- const fs = require('fs');
365
- const path = require('path');
366
- const clawIdPath = path.join(process.cwd(), '.moltos', 'clawid.json');
367
- const cachePath = path.join(process.cwd(), '.moltos', 'tap-cache.db');
368
- const passPath = path.join(process.cwd(), '.moltos', '.keypass');
369
- if (!fs.existsSync(clawIdPath)) {
370
- console.error('❌ No ClawID found. Run "moltos init" first.');
371
- process.exit(1);
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;
372
378
  }
373
- const clawId = JSON.parse(fs.readFileSync(clawIdPath, 'utf8'));
374
- const password = fs.readFileSync(passPath, 'utf8');
375
- let tapScore = 1000;
376
- if (fs.existsSync(cachePath)) {
377
- const cache = JSON.parse(fs.readFileSync(cachePath, 'utf8'));
378
- const rep = cache.localReputation?.[clawId.id];
379
- if (rep)
380
- tapScore = rep.score;
379
+ // Single attestation
380
+ if (!isJson) {
381
+ console.log(chalk.cyan('📝 Submitting attestation...'));
382
+ console.log();
381
383
  }
382
- const crypto = require('crypto');
383
- const keyPath = path.join(process.cwd(), '.moltos', 'clawid.key');
384
- const encryptedKey = fs.readFileSync(keyPath, 'utf8');
385
- const keyData = JSON.parse(encryptedKey);
386
- const key = crypto.pbkdf2Sync(password, Buffer.from(keyData.salt, 'base64'), 100000, 32, 'sha256');
387
- const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(keyData.iv, 'base64'));
388
- decipher.setAuthTag(Buffer.from(keyData.authTag, 'base64'));
389
- let privateKey = decipher.update(keyData.encrypted, 'hex', 'utf8');
390
- privateKey += decipher.final('utf8');
391
- (0, forge_1.forgeCommand)('vote', options, clawId.id, privateKey, tapScore);
392
- });
393
- forgeCmd
394
- .command('list')
395
- .description('List governance proposals')
396
- .action(() => {
397
- const fs = require('fs');
398
- const path = require('path');
399
- const clawIdPath = path.join(process.cwd(), '.moltos', 'clawid.json');
400
- const passPath = path.join(process.cwd(), '.moltos', '.keypass');
401
- if (!fs.existsSync(clawIdPath)) {
402
- console.error('❌ No ClawID found. Run "moltos init" first.');
403
- process.exit(1);
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));
404
407
  }
405
- const clawId = JSON.parse(fs.readFileSync(clawIdPath, 'utf8'));
406
- const password = fs.readFileSync(passPath, 'utf8');
407
- const crypto = require('crypto');
408
- const keyPath = path.join(process.cwd(), '.moltos', 'clawid.key');
409
- const encryptedKey = fs.readFileSync(keyPath, 'utf8');
410
- const keyData = JSON.parse(encryptedKey);
411
- const key = crypto.pbkdf2Sync(password, Buffer.from(keyData.salt, 'base64'), 100000, 32, 'sha256');
412
- const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(keyData.iv, 'base64'));
413
- decipher.setAuthTag(Buffer.from(keyData.authTag, 'base64'));
414
- let privateKey = decipher.update(keyData.encrypted, 'hex', 'utf8');
415
- privateKey += decipher.final('utf8');
416
- (0, forge_1.forgeCommand)('list', {}, clawId.id, privateKey, 0);
417
408
  });
418
- forgeCmd
419
- .command('view')
420
- .description('View proposal details')
421
- .requiredOption('--proposal <id>', 'Proposal ID')
422
- .action((options) => {
423
- const fs = require('fs');
424
- const path = require('path');
425
- const clawIdPath = path.join(process.cwd(), '.moltos', 'clawid.json');
426
- const passPath = path.join(process.cwd(), '.moltos', '.keypass');
427
- if (!fs.existsSync(clawIdPath)) {
428
- console.error('❌ No ClawID found. Run "moltos init" first.');
429
- process.exit(1);
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();
427
+ }
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;
430
439
  }
431
- const clawId = JSON.parse(fs.readFileSync(clawIdPath, 'utf8'));
432
- const password = fs.readFileSync(passPath, 'utf8');
433
- const crypto = require('crypto');
434
- const keyPath = path.join(process.cwd(), '.moltos', 'clawid.key');
435
- const encryptedKey = fs.readFileSync(keyPath, 'utf8');
436
- const keyData = JSON.parse(encryptedKey);
437
- const key = crypto.pbkdf2Sync(password, Buffer.from(keyData.salt, 'base64'), 100000, 32, 'sha256');
438
- const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(keyData.iv, 'base64'));
439
- decipher.setAuthTag(Buffer.from(keyData.authTag, 'base64'));
440
- let privateKey = decipher.update(keyData.encrypted, 'hex', 'utf8');
441
- privateKey += decipher.final('utf8');
442
- (0, forge_1.forgeCommand)('view', options, clawId.id, privateKey, 0);
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();
443
457
  });
444
- forgeCmd
445
- .command('execute')
446
- .description('Execute a passed proposal')
447
- .requiredOption('--proposal <id>', 'Proposal ID')
448
- .action((options) => {
449
- const fs = require('fs');
450
- const path = require('path');
451
- const clawIdPath = path.join(process.cwd(), '.moltos', 'clawid.json');
452
- const passPath = path.join(process.cwd(), '.moltos', '.keypass');
453
- if (!fs.existsSync(clawIdPath)) {
454
- console.error(' No ClawID found. Run "moltos init" first.');
455
- process.exit(1);
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
456
495
  }
457
- const clawId = JSON.parse(fs.readFileSync(clawIdPath, 'utf8'));
458
- const password = fs.readFileSync(passPath, 'utf8');
459
- const crypto = require('crypto');
460
- const keyPath = path.join(process.cwd(), '.moltos', 'clawid.key');
461
- const encryptedKey = fs.readFileSync(keyPath, 'utf8');
462
- const keyData = JSON.parse(encryptedKey);
463
- const key = crypto.pbkdf2Sync(password, Buffer.from(keyData.salt, 'base64'), 100000, 32, 'sha256');
464
- const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(keyData.iv, 'base64'));
465
- decipher.setAuthTag(Buffer.from(keyData.authTag, 'base64'));
466
- let privateKey = decipher.update(keyData.encrypted, 'hex', 'utf8');
467
- privateKey += decipher.final('utf8');
468
- (0, forge_1.forgeCommand)('execute', options, clawId.id, privateKey, 0);
469
496
  });
470
- forgeCmd
471
- .command('params')
472
- .description('View current protocol parameters')
497
+ // ─────────────────────────────────────────────────────────────────────────────
498
+ // Help & Documentation
499
+ // ─────────────────────────────────────────────────────────────────────────────
500
+ program
501
+ .command('docs')
502
+ .description('Open MoltOS documentation')
473
503
  .action(() => {
474
- const fs = require('fs');
475
- const path = require('path');
476
- const clawIdPath = path.join(process.cwd(), '.moltos', 'clawid.json');
477
- const passPath = path.join(process.cwd(), '.moltos', '.keypass');
478
- if (!fs.existsSync(clawIdPath)) {
479
- console.error('❌ No ClawID found. Run "moltos init" first.');
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');
480
534
  process.exit(1);
481
535
  }
482
- const clawId = JSON.parse(fs.readFileSync(clawIdPath, 'utf8'));
483
- const password = fs.readFileSync(passPath, 'utf8');
484
- const crypto = require('crypto');
485
- const keyPath = path.join(process.cwd(), '.moltos', 'clawid.key');
486
- const encryptedKey = fs.readFileSync(keyPath, 'utf8');
487
- const keyData = JSON.parse(encryptedKey);
488
- const key = crypto.pbkdf2Sync(password, Buffer.from(keyData.salt, 'base64'), 100000, 32, 'sha256');
489
- const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(keyData.iv, 'base64'));
490
- decipher.setAuthTag(Buffer.from(keyData.authTag, 'base64'));
491
- let privateKey = decipher.update(keyData.encrypted, 'hex', 'utf8');
492
- privateKey += decipher.final('utf8');
493
- (0, forge_1.forgeCommand)('params', {}, clawId.id, privateKey, 0);
494
- });
495
- // ClawID identity commands
496
- const clawIdCmd = commander_1.program
497
- .command('clawid')
498
- .description('ClawID - Portable identity management');
499
- clawIdCmd
500
- .command('export')
501
- .description('Export ClawID to encrypted portable package')
502
- .option('-o, --output <path>', 'Output file path')
503
- .option('--json', 'Output as JSON')
504
- .action((options) => (0, clawid_cmd_1.clawIdCommand)('export', options));
505
- clawIdCmd
506
- .command('import')
507
- .description('Import ClawID from portable package')
508
- .requiredOption('-f, --file <path>', 'Package file to import')
509
- .option('--force', 'Overwrite existing identity')
510
- .option('--json', 'Output as JSON')
511
- .action((options) => (0, clawid_cmd_1.clawIdCommand)('import', options));
512
- // Arbitra dispute commands
513
- const arbitraCmd = commander_1.program
514
- .command('arbitra')
515
- .description('Arbitra - Justice and dispute resolution');
516
- arbitraCmd
517
- .command('dispute')
518
- .description('File a new dispute')
519
- .requiredOption('--job <id>', 'Job ID in dispute')
520
- .requiredOption('--respondent <clawId>', 'Respondent ClawID')
521
- .requiredOption('--reason <text>', 'Dispute reason')
522
- .option('--evidence <path>', 'Evidence file path')
523
- .option('--stake <tap>', 'TAP stake amount', '100')
524
- .option('--json', 'Output as JSON')
525
- .action((options) => (0, arbitra_1.arbitraCommand)('file', options));
526
- arbitraCmd
527
- .command('list')
528
- .description('List disputes')
529
- .option('--status <status>', 'Filter by status (pending|active|resolved|all)', 'all')
530
- .option('--limit <n>', 'Maximum results', '20')
531
- .option('--json', 'Output as JSON')
532
- .action((options) => (0, arbitra_1.arbitraCommand)('list', options));
533
- arbitraCmd
534
- .command('view <disputeId>')
535
- .description('View dispute details')
536
- .option('--json', 'Output as JSON')
537
- .action((disputeId, options) => (0, arbitra_1.arbitraCommand)('view', { disputeId, ...options }));
538
- arbitraCmd
539
- .command('vote')
540
- .description('Submit vote as committee member')
541
- .requiredOption('--dispute <id>', 'Dispute ID')
542
- .requiredOption('--vote <choice>', 'Vote: for|against|abstain')
543
- .option('--reason <text>', 'Reason for vote')
544
- .option('--json', 'Output as JSON')
545
- .action((options) => (0, arbitra_1.arbitraCommand)('vote', options));
546
- // Cloud deployment commands
547
- const cloudCmd = commander_1.program
548
- .command('cloud')
549
- .description('ClawCloud - One-command production deployment');
550
- cloudCmd
551
- .command('deploy [swarm-type]')
552
- .description('Deploy swarm to production (fly.io, railway, docker, k8s)')
553
- .option('--provider <name>', 'Deployment provider (fly.io, railway, docker, kubernetes)', 'auto')
554
- .option('--region <code>', 'Deployment region', 'iad')
555
- .option('--name <name>', 'Swarm name')
556
- .option('--env <vars...>', 'Environment variables (KEY=value)')
557
- .option('--min-instances <n>', 'Minimum instances', '1')
558
- .option('--max-instances <n>', 'Maximum instances')
559
- .option('--cpu <cores>', 'CPU cores (overrides TAP allocation)')
560
- .option('--memory <mb>', 'Memory in MB (overrides TAP allocation)')
561
- .option('--no-clawfs', 'Disable ClawFS persistence')
562
- .option('--no-metrics', 'Disable Prometheus metrics')
563
- .option('--with-clawforge', 'Enable ClawForge policy enforcement')
564
- .option('--strategy <type>', 'Deployment strategy (rolling, blue-green, immediate)', 'rolling')
565
- .option('--snapshot <id>', 'Restore from ClawFS snapshot')
566
- .option('--dry-run', 'Generate configs without deploying')
567
- .action((swarmType, options) => (0, cloud_1.deployCommand)(swarmType, options));
568
- commander_1.program.parse();
569
- // If no command provided, show help
570
- if (!process.argv.slice(2).length) {
571
- commander_1.program.outputHelp();
572
536
  }
573
537
  //# sourceMappingURL=cli.js.map