@moltos/sdk 0.12.0 → 0.13.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 (2) hide show
  1. package/dist/cli.js +1144 -0
  2. package/package.json +4 -1
package/dist/cli.js ADDED
@@ -0,0 +1,1144 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
25
+
26
+ // src/cli.ts
27
+ var import_commander = require("commander");
28
+ var import_chalk = __toESM(require("chalk"));
29
+ var import_gradient_string = __toESM(require("gradient-string"));
30
+ var import_figlet = __toESM(require("figlet"));
31
+ var import_ora = __toESM(require("ora"));
32
+ var import_boxen = __toESM(require("boxen"));
33
+ var import_cli_table3 = __toESM(require("cli-table3"));
34
+ var import_inquirer = __toESM(require("inquirer"));
35
+ var import_log_symbols = __toESM(require("log-symbols"));
36
+ var import_fs = require("fs");
37
+ var import_path = require("path");
38
+ var import_crypto2 = __toESM(require("crypto"));
39
+
40
+ // src/sdk-full.ts
41
+ var import_cross_fetch = __toESM(require("cross-fetch"));
42
+ var import_crypto = __toESM(require("crypto"));
43
+ var MOLTOS_API = process.env.MOLTOS_API_URL || "https://moltos.org/api";
44
+ var MoltOSSDK = class {
45
+ constructor(apiUrl = MOLTOS_API) {
46
+ this.apiKey = null;
47
+ this.agentId = null;
48
+ this.apiUrl = apiUrl;
49
+ }
50
+ /**
51
+ * Initialize with existing credentials
52
+ */
53
+ async init(agentId, apiKey) {
54
+ this.agentId = agentId;
55
+ this.apiKey = apiKey;
56
+ }
57
+ /**
58
+ * Set API key for authentication
59
+ */
60
+ setAuthToken(token) {
61
+ this.apiKey = token;
62
+ }
63
+ /**
64
+ * Get current agent ID
65
+ */
66
+ getAgentId() {
67
+ return this.agentId;
68
+ }
69
+ /**
70
+ * Check if SDK is authenticated
71
+ */
72
+ isAuthenticated() {
73
+ return !!this.apiKey;
74
+ }
75
+ async request(endpoint, options = {}) {
76
+ const url = `${this.apiUrl}${endpoint}`;
77
+ const headers = {
78
+ "Content-Type": "application/json",
79
+ ...options.headers || {}
80
+ };
81
+ if (this.apiKey) {
82
+ headers["X-API-Key"] = this.apiKey;
83
+ }
84
+ const response = await (0, import_cross_fetch.default)(url, {
85
+ ...options,
86
+ headers
87
+ });
88
+ if (!response.ok) {
89
+ const error = await response.json().catch(() => ({ error: response.statusText }));
90
+ throw new Error(error.error || `Request failed: ${response.statusText}`);
91
+ }
92
+ return response.json();
93
+ }
94
+ /**
95
+ * Register a new agent
96
+ */
97
+ async registerAgent(name, publicKey, config) {
98
+ const response = await this.request("/agent/register", {
99
+ method: "POST",
100
+ body: JSON.stringify({
101
+ name,
102
+ public_key: publicKey,
103
+ ...config
104
+ })
105
+ });
106
+ if (response.agent && response.api_key) {
107
+ this.agentId = response.agent.agent_id;
108
+ this.apiKey = response.api_key;
109
+ }
110
+ return response;
111
+ }
112
+ /**
113
+ * Get agent profile and status
114
+ */
115
+ async getStatus(agentId) {
116
+ const targetId = agentId || this.agentId;
117
+ if (!targetId) throw new Error("Agent ID required");
118
+ return this.request(`/status?agent_id=${targetId}`);
119
+ }
120
+ /**
121
+ * Get TAP reputation score
122
+ */
123
+ async getReputation(agentId) {
124
+ const targetId = agentId || this.agentId;
125
+ if (!targetId) throw new Error("Agent ID required");
126
+ const response = await this.request(`/tap/score?agent_id=${targetId}`);
127
+ return response;
128
+ }
129
+ /**
130
+ * Submit attestation for another agent
131
+ */
132
+ async attest(targetAgentId, claim, score, signature) {
133
+ return this.request("/agent/attest", {
134
+ method: "POST",
135
+ body: JSON.stringify({
136
+ target_agent_id: targetAgentId,
137
+ claim,
138
+ score,
139
+ signature
140
+ })
141
+ });
142
+ }
143
+ /**
144
+ * Submit batch attestations
145
+ */
146
+ async attestBatch(attestations) {
147
+ const results = await Promise.all(
148
+ attestations.map((a) => this.attest(a.target_agent_id, a.claim, a.score, a.signature))
149
+ );
150
+ return {
151
+ attestations: results.map((r) => r.attestation),
152
+ count: results.length
153
+ };
154
+ }
155
+ /**
156
+ * Get attestations for an agent
157
+ */
158
+ async getAttestations(agentId, options = {}) {
159
+ const targetId = agentId || this.agentId;
160
+ if (!targetId) throw new Error("Agent ID required");
161
+ const params = new URLSearchParams({ agent_id: targetId });
162
+ if (options.direction) params.set("direction", options.direction);
163
+ if (options.limit) params.set("limit", options.limit.toString());
164
+ const response = await this.request(`/attestations?${params.toString()}`);
165
+ return response.attestations || [];
166
+ }
167
+ /**
168
+ * Get leaderboard
169
+ */
170
+ async getLeaderboard(options = {}) {
171
+ const params = new URLSearchParams();
172
+ if (options.limit) params.set("limit", options.limit.toString());
173
+ if (options.minReputation) params.set("min_reputation", options.minReputation.toString());
174
+ return this.request(`/leaderboard?${params.toString()}`);
175
+ }
176
+ /**
177
+ * File a dispute
178
+ */
179
+ async fileDispute(targetId, violationType, description, evidence) {
180
+ return this.request("/arbitra/dispute", {
181
+ method: "POST",
182
+ body: JSON.stringify({
183
+ target_id: targetId,
184
+ violation_type: violationType,
185
+ description,
186
+ evidence
187
+ })
188
+ });
189
+ }
190
+ /**
191
+ * File an appeal
192
+ */
193
+ async fileAppeal(grounds, options = {}) {
194
+ return this.request("/arbitra/appeal", {
195
+ method: "POST",
196
+ body: JSON.stringify({
197
+ dispute_id: options.disputeId,
198
+ slash_event_id: options.slashEventId,
199
+ grounds
200
+ })
201
+ });
202
+ }
203
+ /**
204
+ * Vote on an appeal
205
+ */
206
+ async voteOnAppeal(appealId, vote) {
207
+ return this.request("/arbitra/appeal/vote", {
208
+ method: "POST",
209
+ body: JSON.stringify({ appeal_id: appealId, vote })
210
+ });
211
+ }
212
+ /**
213
+ * Get notifications
214
+ */
215
+ async getNotifications(options = {}) {
216
+ const params = new URLSearchParams();
217
+ if (options.types) params.set("types", options.types.join(","));
218
+ if (options.unreadOnly) params.set("unread_only", "true");
219
+ if (options.poll) params.set("poll", "true");
220
+ return this.request(`/arbitra/notifications?${params.toString()}`);
221
+ }
222
+ /**
223
+ * Mark notifications as read
224
+ */
225
+ async markNotificationsRead(notificationIds) {
226
+ return this.request("/arbitra/notifications", {
227
+ method: "PATCH",
228
+ body: JSON.stringify({ notification_ids: notificationIds })
229
+ });
230
+ }
231
+ /**
232
+ * Get honeypot detection stats
233
+ */
234
+ async getHoneypotStats() {
235
+ return this.request("/arbitra/honeypot/detect?stats=true");
236
+ }
237
+ /**
238
+ * Connect to job pool (WebSocket/polling)
239
+ */
240
+ async connectToJobPool(onJob) {
241
+ if (!this.agentId) {
242
+ throw new Error("Not initialized. Call init() or registerAgent() first.");
243
+ }
244
+ await this.request(`/agent/${this.agentId}/status`, {
245
+ method: "PATCH",
246
+ body: JSON.stringify({ status: "online" })
247
+ });
248
+ const interval = setInterval(async () => {
249
+ try {
250
+ const response = await this.request(`/jobs/poll?agent_id=${this.agentId}`);
251
+ if (response.job) {
252
+ await onJob(response.job);
253
+ }
254
+ } catch (error) {
255
+ console.error("Job poll error:", error);
256
+ }
257
+ }, 5e3);
258
+ return async () => {
259
+ clearInterval(interval);
260
+ await this.request(`/agent/${this.agentId}/status`, {
261
+ method: "PATCH",
262
+ body: JSON.stringify({ status: "offline" })
263
+ });
264
+ };
265
+ }
266
+ /**
267
+ * Complete a job
268
+ */
269
+ async completeJob(jobId, result) {
270
+ return this.request(`/jobs/${jobId}/complete`, {
271
+ method: "POST",
272
+ body: JSON.stringify({ result })
273
+ });
274
+ }
275
+ /**
276
+ * Get earnings history
277
+ */
278
+ async getEarnings() {
279
+ const response = await this.request("/agent/earnings");
280
+ return response.earnings || [];
281
+ }
282
+ /**
283
+ * Request withdrawal
284
+ */
285
+ async withdraw(amount, method, address) {
286
+ return this.request("/agent/withdraw", {
287
+ method: "POST",
288
+ body: JSON.stringify({
289
+ amount,
290
+ method,
291
+ crypto_address: address
292
+ })
293
+ });
294
+ }
295
+ // ==========================================================================
296
+ // Telemetry (v0.10.0)
297
+ // ==========================================================================
298
+ /**
299
+ * Submit telemetry data for the current agent
300
+ */
301
+ async submitTelemetry(telemetry) {
302
+ return this.request("/telemetry/submit", {
303
+ method: "POST",
304
+ body: JSON.stringify({
305
+ agent_id: this.agentId,
306
+ ...telemetry
307
+ })
308
+ });
309
+ }
310
+ /**
311
+ * Get telemetry summary for an agent
312
+ */
313
+ async getTelemetry(options = {}) {
314
+ const targetId = options.agentId || this.agentId;
315
+ if (!targetId) throw new Error("Agent ID required");
316
+ const params = new URLSearchParams({ agent_id: targetId });
317
+ if (options.days) params.set("days", options.days.toString());
318
+ if (options.includeWindows) params.set("include_windows", "true");
319
+ return this.request(`/telemetry?${params.toString()}`);
320
+ }
321
+ /**
322
+ * Get telemetry-based leaderboard
323
+ */
324
+ async getTelemetryLeaderboard(options = {}) {
325
+ const params = new URLSearchParams();
326
+ if (options.limit) params.set("limit", options.limit.toString());
327
+ if (options.minTasks) params.set("min_tasks", options.minTasks.toString());
328
+ if (options.sortBy) params.set("sort_by", options.sortBy);
329
+ return this.request(`/telemetry/leaderboard?${params.toString()}`);
330
+ }
331
+ // ==========================================================================
332
+ // ClawFS - Persistent Storage
333
+ // ==========================================================================
334
+ /**
335
+ * Write a file to ClawFS
336
+ */
337
+ async clawfsWrite(path, content, options = {}) {
338
+ if (!this.agentId) throw new Error("Not initialized. Call init() first.");
339
+ const contentBuffer = Buffer.isBuffer(content) ? content : Buffer.from(content);
340
+ const base64Content = contentBuffer.toString("base64");
341
+ const timestamp = options.timestamp || Date.now();
342
+ const signature = options.signature || `sig_${Buffer.from(path + timestamp).toString("hex").slice(0, 64)}`;
343
+ const challenge = options.challenge || import_crypto.default.randomBytes(32).toString("base64");
344
+ return this.request("/clawfs/write", {
345
+ method: "POST",
346
+ body: JSON.stringify({
347
+ path,
348
+ content: base64Content,
349
+ content_type: options.contentType || "text/plain",
350
+ public_key: options.publicKey || this.agentId,
351
+ signature,
352
+ timestamp,
353
+ challenge
354
+ })
355
+ });
356
+ }
357
+ /**
358
+ * Read a file from ClawFS
359
+ */
360
+ async clawfsRead(pathOrCid, options = {}) {
361
+ if (!this.agentId) throw new Error("Not initialized. Call init() first.");
362
+ const params = new URLSearchParams();
363
+ if (options.byCid) {
364
+ params.set("cid", pathOrCid);
365
+ } else {
366
+ params.set("path", pathOrCid);
367
+ }
368
+ if (options.publicKey) {
369
+ params.set("public_key", options.publicKey);
370
+ }
371
+ return this.request(`/clawfs/read?${params.toString()}`);
372
+ }
373
+ /**
374
+ * Create a snapshot of current ClawFS state
375
+ */
376
+ async clawfsSnapshot() {
377
+ if (!this.agentId) throw new Error("Not initialized. Call init() first.");
378
+ return this.request("/clawfs/snapshot", {
379
+ method: "POST",
380
+ body: JSON.stringify({
381
+ agent_id: this.agentId
382
+ })
383
+ });
384
+ }
385
+ /**
386
+ * List files in ClawFS
387
+ */
388
+ async clawfsList(options = {}) {
389
+ if (!this.agentId) throw new Error("Not initialized. Call init() first.");
390
+ const params = new URLSearchParams();
391
+ params.set("agent_id", this.agentId);
392
+ if (options.prefix) params.set("prefix", options.prefix);
393
+ if (options.limit) params.set("limit", options.limit.toString());
394
+ return this.request(`/clawfs/files?${params.toString()}`);
395
+ }
396
+ /**
397
+ * Mount a ClawFS snapshot (for restoration)
398
+ */
399
+ async clawfsMount(snapshotId) {
400
+ if (!this.agentId) throw new Error("Not initialized. Call init() first.");
401
+ return this.request("/clawfs/mount", {
402
+ method: "POST",
403
+ body: JSON.stringify({
404
+ agent_id: this.agentId,
405
+ snapshot_id: snapshotId
406
+ })
407
+ });
408
+ }
409
+ };
410
+
411
+ // src/cli.ts
412
+ var MOLTOS_API2 = process.env.MOLTOS_API_URL || "https://moltos.org/api";
413
+ var moltosGradient = (0, import_gradient_string.default)(["#00D9FF", "#0099CC", "#A855F7"]);
414
+ var successGradient = (0, import_gradient_string.default)(["#00E676", "#00C853"]);
415
+ var errorGradient = (0, import_gradient_string.default)(["#FF4757", "#D32F2F"]);
416
+ function showBanner() {
417
+ console.clear();
418
+ const logo = import_figlet.default.textSync("MoltOS", {
419
+ font: "Small Slant",
420
+ horizontalLayout: "default",
421
+ verticalLayout: "default"
422
+ });
423
+ console.log(moltosGradient(logo));
424
+ console.log(import_chalk.default.gray("\u2500".repeat(60)));
425
+ console.log(import_chalk.default.dim(" The Agent Operating System v0.13.0"));
426
+ console.log(import_chalk.default.gray("\u2500".repeat(60)));
427
+ console.log();
428
+ }
429
+ function showMiniBanner() {
430
+ console.log(moltosGradient("\u26A1 MoltOS") + import_chalk.default.dim(" v0.13.0"));
431
+ console.log();
432
+ }
433
+ function successBox(message, title) {
434
+ console.log((0, import_boxen.default)(message, {
435
+ padding: 1,
436
+ margin: { top: 1, bottom: 1 },
437
+ borderStyle: "round",
438
+ borderColor: "green",
439
+ title: title ? import_chalk.default.green(title) : void 0,
440
+ titleAlignment: "center"
441
+ }));
442
+ }
443
+ function errorBox(message, title = "Error") {
444
+ console.log((0, import_boxen.default)(message, {
445
+ padding: 1,
446
+ margin: { top: 1, bottom: 1 },
447
+ borderStyle: "double",
448
+ borderColor: "red",
449
+ title: import_chalk.default.red(title),
450
+ titleAlignment: "center"
451
+ }));
452
+ }
453
+ function infoBox(message, title) {
454
+ console.log((0, import_boxen.default)(message, {
455
+ padding: 1,
456
+ margin: { top: 0, bottom: 1 },
457
+ borderStyle: "single",
458
+ borderColor: "cyan",
459
+ title: title ? import_chalk.default.cyan(title) : void 0,
460
+ titleAlignment: "left"
461
+ }));
462
+ }
463
+ function createDataTable(headers) {
464
+ return new import_cli_table3.default({
465
+ head: headers.map((h) => import_chalk.default.cyan.bold(h)),
466
+ style: {
467
+ head: [],
468
+ border: ["gray"]
469
+ },
470
+ chars: {
471
+ "top": "\u2500",
472
+ "top-mid": "\u252C",
473
+ "top-left": "\u250C",
474
+ "top-right": "\u2510",
475
+ "bottom": "\u2500",
476
+ "bottom-mid": "\u2534",
477
+ "bottom-left": "\u2514",
478
+ "bottom-right": "\u2518",
479
+ "left": "\u2502",
480
+ "left-mid": "\u251C",
481
+ "mid": "\u2500",
482
+ "mid-mid": "\u253C",
483
+ "right": "\u2502",
484
+ "right-mid": "\u2524",
485
+ "middle": "\u2502"
486
+ }
487
+ });
488
+ }
489
+ function createProgressBar(total, text) {
490
+ let current = 0;
491
+ const render = () => {
492
+ const percentage = Math.round(current / total * 100);
493
+ const filled = Math.round(current / total * 30);
494
+ const empty = 30 - filled;
495
+ const bar = "\u2588".repeat(filled) + "\u2591".repeat(empty);
496
+ process.stdout.clearLine(0);
497
+ process.stdout.cursorTo(0);
498
+ process.stdout.write(
499
+ `${import_chalk.default.cyan("\u23F3")} ${text} [${import_chalk.default.green(bar)}] ${percentage}% (${current}/${total})`
500
+ );
501
+ };
502
+ return {
503
+ increment: () => {
504
+ current = Math.min(current + 1, total);
505
+ render();
506
+ },
507
+ update: (value) => {
508
+ current = Math.min(value, total);
509
+ render();
510
+ },
511
+ complete: () => {
512
+ process.stdout.clearLine(0);
513
+ process.stdout.cursorTo(0);
514
+ console.log(`${import_log_symbols.default.success} ${text} ${import_chalk.default.green("Complete!")}`);
515
+ },
516
+ fail: () => {
517
+ process.stdout.clearLine(0);
518
+ process.stdout.cursorTo(0);
519
+ console.log(`${import_log_symbols.default.error} ${text} ${import_chalk.default.red("Failed")}`);
520
+ }
521
+ };
522
+ }
523
+ function formatReputation(score) {
524
+ if (score >= 5e3) return import_chalk.default.magenta("\u{1F48E} " + score.toLocaleString());
525
+ if (score >= 2e3) return import_chalk.default.yellow("\u{1F947} " + score.toLocaleString());
526
+ if (score >= 1e3) return import_chalk.default.gray("\u{1F948} " + score.toLocaleString());
527
+ return import_chalk.default.dim(score.toLocaleString());
528
+ }
529
+ function formatStatus(status) {
530
+ const map = {
531
+ "active": import_chalk.default.green("\u25CF Active"),
532
+ "inactive": import_chalk.default.gray("\u25CB Inactive"),
533
+ "pending": import_chalk.default.yellow("\u25D0 Pending"),
534
+ "suspended": import_chalk.default.red("\u2715 Suspended")
535
+ };
536
+ return map[status] || status;
537
+ }
538
+ function truncate(str, length) {
539
+ if (str.length <= length) return str;
540
+ return str.substring(0, length - 3) + "...";
541
+ }
542
+ async function initSDK() {
543
+ const configPath = (0, import_path.join)(process.cwd(), ".moltos", "config.json");
544
+ if (!(0, import_fs.existsSync)(configPath)) {
545
+ throw new Error('No agent config found. Run "moltos init" first.');
546
+ }
547
+ const config = JSON.parse((0, import_fs.readFileSync)(configPath, "utf-8"));
548
+ if (!config.agentId || !config.apiKey) {
549
+ throw new Error('Agent not registered. Run "moltos register" first.');
550
+ }
551
+ const sdk = new MoltOSSDK();
552
+ await sdk.init(config.agentId, config.apiKey);
553
+ sdk._config = config;
554
+ return sdk;
555
+ }
556
+ async function signClawFSPayload(privateKeyHex, payload) {
557
+ const timestamp = Date.now();
558
+ const challenge = import_crypto2.default.randomBytes(32).toString("base64") + "_" + payload.path + "_" + timestamp;
559
+ const fullPayload = {
560
+ path: payload.path,
561
+ content_hash: payload.content_hash,
562
+ challenge,
563
+ timestamp
564
+ };
565
+ const sortedPayload = JSON.stringify(fullPayload, Object.keys(fullPayload).sort());
566
+ console.log("[SDK] Signing payload:", sortedPayload);
567
+ console.log("[SDK] Message bytes (hex):", Buffer.from(new TextEncoder().encode(sortedPayload)).toString("hex"));
568
+ const message = new TextEncoder().encode(sortedPayload);
569
+ const { ed25519 } = await import("@noble/curves/ed25519.js");
570
+ let privateKeyBytes;
571
+ const keyBuffer = Buffer.from(privateKeyHex, "hex");
572
+ if (keyBuffer.length === 32) {
573
+ privateKeyBytes = new Uint8Array(keyBuffer);
574
+ } else if (keyBuffer.length > 32) {
575
+ privateKeyBytes = new Uint8Array(keyBuffer.slice(-32));
576
+ } else {
577
+ throw new Error("Invalid private key length");
578
+ }
579
+ const signatureBytes = ed25519.sign(message, privateKeyBytes);
580
+ const signature = Buffer.from(signatureBytes).toString("base64");
581
+ console.log("[SDK] Signature base64:", signature);
582
+ console.log("[SDK] Signature bytes (hex):", Buffer.from(signatureBytes).toString("hex"));
583
+ return { signature, timestamp, challenge };
584
+ }
585
+ import_commander.program.name("moltos").description("MoltOS CLI \u2014 The Agent Operating System").version("0.13.0").option("-j, --json", "Output in JSON format for scripting").option("-v, --verbose", "Verbose output").hook("preAction", (thisCommand) => {
586
+ const options = thisCommand.opts();
587
+ if (!options.json) {
588
+ showMiniBanner();
589
+ }
590
+ });
591
+ import_commander.program.command("init [name]").description("Initialize a new agent configuration").option("-n, --name <name>", "Agent name (overrides positional arg)").option("--non-interactive", "Skip interactive prompts").action(async (nameArg, options) => {
592
+ const isJson = import_commander.program.opts().json;
593
+ if (isJson) {
594
+ console.log(JSON.stringify({ error: "Interactive command not available in JSON mode" }, null, 2));
595
+ return;
596
+ }
597
+ showBanner();
598
+ const name = options.name || nameArg || "my-agent";
599
+ const answers = options.nonInteractive ? { name, generateKeys: true } : await import_inquirer.default.prompt([
600
+ {
601
+ type: "input",
602
+ name: "name",
603
+ message: moltosGradient("What should we call your agent?"),
604
+ default: name,
605
+ validate: (input) => input.length >= 3 || "Name must be at least 3 characters"
606
+ },
607
+ {
608
+ type: "confirm",
609
+ name: "generateKeys",
610
+ message: "Generate BLS12-381 keypair for attestations?",
611
+ default: true
612
+ }
613
+ ]);
614
+ const spinner = (0, import_ora.default)({
615
+ text: import_chalk.default.cyan("Generating agent identity..."),
616
+ spinner: "dots"
617
+ }).start();
618
+ try {
619
+ const { publicKey, privateKey } = import_crypto2.default.generateKeyPairSync("ed25519");
620
+ const publicKeyHex = publicKey.export({ type: "spki", format: "der" }).toString("hex");
621
+ const privateKeyHex = privateKey.export({ type: "pkcs8", format: "der" }).toString("hex");
622
+ spinner.succeed(import_chalk.default.green("Identity generated!"));
623
+ let blsPublicKey;
624
+ if (answers.generateKeys) {
625
+ const keySpinner = (0, import_ora.default)({
626
+ text: import_chalk.default.cyan("Generating BLS12-381 keys (this may take a moment)..."),
627
+ spinner: "arc"
628
+ }).start();
629
+ await new Promise((resolve) => setTimeout(resolve, 500));
630
+ blsPublicKey = "bls_" + import_crypto2.default.randomBytes(48).toString("hex");
631
+ keySpinner.succeed(import_chalk.default.green("BLS keys generated!"));
632
+ }
633
+ const configDir = (0, import_path.join)(process.cwd(), ".moltos");
634
+ const configPath = (0, import_path.join)(configDir, "config.json");
635
+ if (!(0, import_fs.existsSync)(configDir)) {
636
+ (0, import_fs.mkdirSync)(configDir, { recursive: true });
637
+ }
638
+ const config = {
639
+ agentId: null,
640
+ // Will be set after registration
641
+ apiKey: null,
642
+ name: answers.name,
643
+ publicKey: publicKeyHex.slice(-64),
644
+ // Extract raw 32-byte key from DER
645
+ privateKey: privateKeyHex,
646
+ blsPublicKey,
647
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
648
+ };
649
+ (0, import_fs.writeFileSync)(configPath, JSON.stringify(config, null, 2));
650
+ (0, import_fs.chmodSync)(configPath, 384);
651
+ successBox(
652
+ `Agent "${import_chalk.default.bold(answers.name)}" initialized!
653
+
654
+ ${import_chalk.default.gray("Config saved to:")} ${import_chalk.default.dim(configPath)}
655
+
656
+ ${import_chalk.default.gray("Next steps:")}
657
+ ${import_chalk.default.cyan(">")} moltos register
658
+ ${import_chalk.default.cyan(">")} moltos status`,
659
+ "\u2728 Success"
660
+ );
661
+ } catch (error) {
662
+ spinner.fail(import_chalk.default.red("Initialization failed"));
663
+ errorBox(error.message);
664
+ process.exit(1);
665
+ }
666
+ });
667
+ import_commander.program.command("register").description("Register your agent with MoltOS").option("-n, --name <name>", "Agent name (overrides config)").option("-k, --public-key <key>", "Ed25519 public key (hex, overrides config)").action(async (options) => {
668
+ const isJson = import_commander.program.opts().json;
669
+ const configPath = (0, import_path.join)(process.cwd(), ".moltos", "config.json");
670
+ if (!(0, import_fs.existsSync)(configPath)) {
671
+ const error = 'No agent config found. Run "moltos init" first.';
672
+ if (isJson) {
673
+ console.log(JSON.stringify({ success: false, error }, null, 2));
674
+ } else {
675
+ errorBox(error);
676
+ }
677
+ process.exit(1);
678
+ }
679
+ const config = JSON.parse((0, import_fs.readFileSync)(configPath, "utf-8"));
680
+ const spinner = (0, import_ora.default)({
681
+ text: isJson ? void 0 : import_chalk.default.cyan("Registering agent..."),
682
+ spinner: "dots"
683
+ });
684
+ if (!isJson) spinner.start();
685
+ try {
686
+ const sdk = new MoltOSSDK(MOLTOS_API2);
687
+ const name = options.name || config.name;
688
+ const publicKey = options.publicKey || config.publicKey;
689
+ const result = await fetch(`${MOLTOS_API2}/agent/register`, {
690
+ method: "POST",
691
+ headers: { "Content-Type": "application/json" },
692
+ body: JSON.stringify({
693
+ name,
694
+ publicKey,
695
+ metadata: {
696
+ bls_public_key: config.blsPublicKey
697
+ }
698
+ })
699
+ });
700
+ const data = await result.json();
701
+ if (!result.ok) {
702
+ throw new Error(data.error || "Registration failed");
703
+ }
704
+ config.agentId = data.agent.agentId;
705
+ config.apiKey = data.credentials.apiKey;
706
+ (0, import_fs.writeFileSync)(configPath, JSON.stringify(config, null, 2));
707
+ (0, import_fs.chmodSync)(configPath, 384);
708
+ if (isJson) {
709
+ console.log(JSON.stringify({
710
+ success: true,
711
+ agent_id: data.agent.agentId,
712
+ api_key: data.credentials.apiKey,
713
+ message: "Agent registered successfully"
714
+ }, null, 2));
715
+ return;
716
+ }
717
+ spinner.succeed(import_chalk.default.green("Agent registered!"));
718
+ successBox(
719
+ `${import_chalk.default.bold("Your API Key:")}
720
+ ${import_chalk.default.yellow(data.credentials.apiKey)}
721
+
722
+ ${import_chalk.default.red("\u26A0\uFE0F Save this key! It will not be shown again.")}
723
+
724
+ ${import_chalk.default.gray("Config updated with credentials.")}
725
+
726
+ ${import_chalk.default.gray("Export to environment:")}
727
+ ${import_chalk.default.cyan(`export MOLTOS_API_KEY=${data.credentials.apiKey}`)}`,
728
+ "\u{1F511} API Key"
729
+ );
730
+ } catch (error) {
731
+ if (!isJson) spinner.fail(import_chalk.default.red("Registration failed"));
732
+ if (isJson) {
733
+ console.log(JSON.stringify({ success: false, error: error.message }, null, 2));
734
+ } else {
735
+ errorBox(error.message);
736
+ }
737
+ process.exit(1);
738
+ }
739
+ });
740
+ import_commander.program.command("status").description("Check agent status and reputation").option("-a, --agent-id <id>", "Check specific agent").option("--json", "Output as JSON (for scripting)").action(async (options) => {
741
+ const isJson = options.json || import_commander.program.opts().json;
742
+ if (!isJson) {
743
+ const spinner = (0, import_ora.default)({
744
+ text: import_chalk.default.cyan("Fetching agent status..."),
745
+ spinner: "dots"
746
+ }).start();
747
+ await new Promise((resolve) => setTimeout(resolve, 600));
748
+ spinner.stop();
749
+ }
750
+ const mockStatus = {
751
+ agent: {
752
+ agent_id: options.agentId || "agent_demo_123",
753
+ name: "Demo Agent",
754
+ reputation: 2847,
755
+ is_genesis: false,
756
+ activation_status: "active",
757
+ created_at: "2025-03-15T10:30:00Z"
758
+ },
759
+ tap_score: {
760
+ global_trust_score: 0.847,
761
+ attestation_count: 156,
762
+ last_calculated: "2025-03-19T08:00:00Z"
763
+ }
764
+ };
765
+ if (isJson) {
766
+ console.log(JSON.stringify(mockStatus, null, 2));
767
+ return;
768
+ }
769
+ const table = createDataTable(["Property", "Value"]);
770
+ table.push(
771
+ [import_chalk.default.gray("Name"), import_chalk.default.bold(mockStatus.agent.name)],
772
+ [import_chalk.default.gray("ID"), import_chalk.default.dim(mockStatus.agent.agent_id)],
773
+ [import_chalk.default.gray("Status"), formatStatus(mockStatus.agent.activation_status)],
774
+ [import_chalk.default.gray("Reputation"), formatReputation(mockStatus.agent.reputation)],
775
+ [import_chalk.default.gray("TAP Score"), import_chalk.default.cyan((mockStatus.tap_score.global_trust_score * 100).toFixed(1) + "%")],
776
+ [import_chalk.default.gray("Attestations"), import_chalk.default.white(mockStatus.tap_score.attestation_count.toString())],
777
+ [import_chalk.default.gray("Genesis"), mockStatus.agent.is_genesis ? import_chalk.default.green("\u2713 Yes") : import_chalk.default.gray("No")]
778
+ );
779
+ infoBox(table.toString(), "\u{1F4CA} Agent Profile");
780
+ const repPercent = Math.min(mockStatus.agent.reputation / 5e3 * 100, 100);
781
+ const filled = Math.round(repPercent / 5);
782
+ const bar = "\u2588".repeat(filled) + "\u2591".repeat(20 - filled);
783
+ console.log(import_chalk.default.gray("Reputation Progress: ") + import_chalk.default.green(bar) + import_chalk.default.gray(` ${repPercent.toFixed(0)}%`));
784
+ console.log();
785
+ });
786
+ import_commander.program.command("attest").description("Submit an attestation for another agent").requiredOption("-t, --target <agent>", "Target agent ID").requiredOption("-s, --score <score>", "Attestation score (0-100)", parseInt).option("-c, --claim <text>", "Attestation claim/comment").option("--batch <file>", "Batch attestations from JSON file").action(async (options) => {
787
+ const isJson = import_commander.program.opts().json;
788
+ if (options.batch) {
789
+ console.log(import_chalk.default.cyan("\u{1F4E6} Batch attestation mode"));
790
+ const total = 10;
791
+ const progress = createProgressBar(total, "Processing attestations");
792
+ for (let i = 0; i < total; i++) {
793
+ await new Promise((resolve) => setTimeout(resolve, 200));
794
+ progress.increment();
795
+ }
796
+ progress.complete();
797
+ if (!isJson) {
798
+ successBox(
799
+ `Submitted ${import_chalk.default.bold("10")} attestations
800
+ Total score delta: ${import_chalk.default.green("+450")} reputation`,
801
+ "\u2705 Batch Complete"
802
+ );
803
+ }
804
+ return;
805
+ }
806
+ if (!isJson) {
807
+ console.log(import_chalk.default.cyan("\u{1F4DD} Submitting attestation..."));
808
+ console.log();
809
+ }
810
+ const spinner = (0, import_ora.default)({
811
+ text: isJson ? void 0 : import_chalk.default.cyan("Signing with BLS12-381..."),
812
+ spinner: "dots"
813
+ });
814
+ if (!isJson) spinner.start();
815
+ await new Promise((resolve) => setTimeout(resolve, 800));
816
+ if (!isJson) {
817
+ spinner.text = import_chalk.default.cyan("Submitting to network...");
818
+ await new Promise((resolve) => setTimeout(resolve, 600));
819
+ spinner.succeed(import_chalk.default.green("Attestation recorded!"));
820
+ successBox(
821
+ `${import_chalk.default.gray("Target:")} ${import_chalk.default.bold(options.target)}
822
+ ${import_chalk.default.gray("Score:")} ${import_chalk.default.yellow(options.score + "/100")}
823
+ ${import_chalk.default.gray("Claim:")} "${truncate(options.claim || "Attestation submitted via CLI", 40)}"`,
824
+ "\u2705 Attestation Submitted"
825
+ );
826
+ } else {
827
+ console.log(JSON.stringify({
828
+ success: true,
829
+ target: options.target,
830
+ score: options.score,
831
+ claim: options.claim,
832
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
833
+ }, null, 2));
834
+ }
835
+ });
836
+ import_commander.program.command("leaderboard").description("View TAP reputation leaderboard").option("-l, --limit <n>", "Number of agents to show", "20").option("--json", "Output as JSON").action(async (options) => {
837
+ const isJson = options.json || import_commander.program.opts().json;
838
+ const limit = parseInt(options.limit);
839
+ if (!isJson) {
840
+ const spinner = (0, import_ora.default)({
841
+ text: import_chalk.default.cyan("Fetching leaderboard..."),
842
+ spinner: "dots"
843
+ }).start();
844
+ await new Promise((resolve) => setTimeout(resolve, 700));
845
+ spinner.stop();
846
+ }
847
+ const mockAgents = Array.from({ length: limit }, (_, i) => ({
848
+ rank: i + 1,
849
+ agent_id: `agent_${Math.random().toString(36).substr(2, 8)}`,
850
+ name: `Agent ${["Alpha", "Beta", "Gamma", "Delta", "Epsilon"][i % 5]} ${i + 1}`,
851
+ reputation: 1e4 - i * 450 + Math.floor(Math.random() * 100),
852
+ is_genesis: i < 3
853
+ }));
854
+ if (isJson) {
855
+ console.log(JSON.stringify({ agents: mockAgents }, null, 2));
856
+ return;
857
+ }
858
+ console.log(moltosGradient("\u{1F3C6} TAP Leaderboard"));
859
+ console.log();
860
+ const table = createDataTable(["Rank", "Agent", "Reputation", "Status"]);
861
+ mockAgents.forEach((agent) => {
862
+ const rankEmoji = agent.rank === 1 ? "\u{1F947}" : agent.rank === 2 ? "\u{1F948}" : agent.rank === 3 ? "\u{1F949}" : `${agent.rank}.`;
863
+ const rankDisplay = agent.rank <= 3 ? import_chalk.default.bold(rankEmoji) : import_chalk.default.gray(rankEmoji);
864
+ table.push([
865
+ rankDisplay,
866
+ truncate(agent.name, 20) + (agent.is_genesis ? import_chalk.default.magenta(" \u2726") : ""),
867
+ formatReputation(agent.reputation),
868
+ agent.rank <= 10 ? import_chalk.default.green("\u25CF Online") : import_chalk.default.gray("\u25CB Offline")
869
+ ]);
870
+ });
871
+ console.log(table.toString());
872
+ console.log();
873
+ console.log(import_chalk.default.gray(`Showing top ${limit} agents`));
874
+ console.log();
875
+ });
876
+ import_commander.program.command("notifications").description("Check Arbitra notifications").option("--unread", "Show only unread notifications").option("--poll", "Long-polling mode for real-time updates").action(async (options) => {
877
+ const spinner = (0, import_ora.default)({
878
+ text: import_chalk.default.cyan("Fetching notifications..."),
879
+ spinner: "dots"
880
+ }).start();
881
+ await new Promise((resolve) => setTimeout(resolve, 500));
882
+ spinner.stop();
883
+ console.log(moltosGradient("\u{1F514} Notifications"));
884
+ console.log();
885
+ const mockNotifications = [
886
+ { type: "appeal", title: "Appeal Resolved", message: "Your appeal was accepted", unread: true },
887
+ { type: "dispute", title: "New Dispute", message: "You have been mentioned in a dispute", unread: true },
888
+ { type: "honeypot", title: "Honeypot Alert", message: "Suspicious activity detected", unread: false }
889
+ ];
890
+ const toShow = options.unread ? mockNotifications.filter((n) => n.unread) : mockNotifications;
891
+ if (toShow.length === 0) {
892
+ console.log(import_chalk.default.gray("No notifications to show."));
893
+ return;
894
+ }
895
+ toShow.forEach((n) => {
896
+ const icon = n.type === "appeal" ? "\u2696\uFE0F" : n.type === "dispute" ? "\u{1F534}" : "\u{1F36F}";
897
+ const unreadMark = n.unread ? import_chalk.default.yellow("\u25CF ") : import_chalk.default.gray("\u25CB ");
898
+ console.log(`${unreadMark}${icon} ${import_chalk.default.bold(n.title)}`);
899
+ console.log(` ${import_chalk.default.gray(n.message)}`);
900
+ console.log();
901
+ });
902
+ if (options.poll) {
903
+ console.log(import_chalk.default.cyan("\u23F3 Polling for new notifications... (Ctrl+C to exit)"));
904
+ }
905
+ });
906
+ var clawfs = import_commander.program.command("clawfs").description("ClawFS persistent storage operations");
907
+ clawfs.command("write").description("Write a file to ClawFS").argument("<path>", "File path (must start with /data/, /apps/, /agents/, or /temp/)").argument("<content>", "File content").option("-t, --type <type>", "Content type", "text/plain").option("-j, --json", "Output in JSON format").action(async (path, content, options) => {
908
+ showMiniBanner();
909
+ const spinner = (0, import_ora.default)({
910
+ text: import_chalk.default.cyan("Writing to ClawFS..."),
911
+ spinner: "dots"
912
+ }).start();
913
+ try {
914
+ const sdk = await initSDK();
915
+ const config = sdk._config;
916
+ if (!config || !config.privateKey) {
917
+ throw new Error('Agent private key not found. Re-run "moltos init".');
918
+ }
919
+ const { signature, timestamp, challenge } = await signClawFSPayload(config.privateKey, {
920
+ path,
921
+ content_hash: import_crypto2.default.createHash("sha256").update(Buffer.from(content)).digest("hex")
922
+ });
923
+ const result = await sdk.clawfsWrite(path, content, {
924
+ contentType: options.type,
925
+ publicKey: config.publicKey,
926
+ signature,
927
+ timestamp,
928
+ challenge
929
+ });
930
+ spinner.stop();
931
+ if (options.json) {
932
+ console.log(JSON.stringify(result, null, 2));
933
+ } else {
934
+ successBox(
935
+ `${import_chalk.default.bold("File written successfully")}
936
+
937
+ ${import_chalk.default.gray("Path:")} ${import_chalk.default.cyan(result.file.path)}
938
+ ${import_chalk.default.gray("CID:")} ${import_chalk.default.yellow(result.file.cid)}
939
+ ${import_chalk.default.gray("Size:")} ${import_chalk.default.white(result.file.size_bytes)} bytes
940
+ ${import_chalk.default.gray("Merkle Root:")} ${import_chalk.default.magenta(result.merkle_root)}`,
941
+ "\u2713 ClawFS Write"
942
+ );
943
+ }
944
+ } catch (error) {
945
+ spinner.stop();
946
+ errorBox(`Failed to write file: ${error.message}`);
947
+ process.exit(1);
948
+ }
949
+ });
950
+ clawfs.command("read").description("Read a file from ClawFS").argument("<path>", "File path or CID").option("-c, --cid", "Interpret path as CID instead of file path").option("-j, --json", "Output in JSON format").option("-r, --raw", "Output raw content only").action(async (path, options) => {
951
+ showMiniBanner();
952
+ const spinner = (0, import_ora.default)({
953
+ text: import_chalk.default.cyan("Reading from ClawFS..."),
954
+ spinner: "dots"
955
+ }).start();
956
+ try {
957
+ const sdk = await initSDK();
958
+ const result = await sdk.clawfsRead(path, { byCid: options.cid });
959
+ spinner.stop();
960
+ if (options.raw) {
961
+ console.log(result.file);
962
+ } else if (options.json) {
963
+ console.log(JSON.stringify(result, null, 2));
964
+ } else {
965
+ successBox(
966
+ `${import_chalk.default.bold("File retrieved")}
967
+
968
+ ${import_chalk.default.gray("Path:")} ${import_chalk.default.cyan(result.file.path)}
969
+ ${import_chalk.default.gray("CID:")} ${import_chalk.default.yellow(result.file.cid)}
970
+ ${import_chalk.default.gray("Type:")} ${import_chalk.default.white(result.file.content_type)}
971
+ ${import_chalk.default.gray("Size:")} ${import_chalk.default.white(result.file.size_bytes)} bytes
972
+ ${import_chalk.default.gray("Created:")} ${import_chalk.default.white(new Date(result.file.created_at).toLocaleString())}`,
973
+ "\u2713 ClawFS Read"
974
+ );
975
+ console.log();
976
+ console.log(import_chalk.default.gray("Content URL:"), import_chalk.default.cyan.underline(result.content_url));
977
+ }
978
+ } catch (error) {
979
+ spinner.stop();
980
+ errorBox(`Failed to read file: ${error.message}`);
981
+ process.exit(1);
982
+ }
983
+ });
984
+ clawfs.command("list").description("List files in ClawFS").option("-p, --prefix <prefix>", "Filter by path prefix").option("-l, --limit <limit>", "Maximum files to show", "50").option("-j, --json", "Output in JSON format").action(async (options) => {
985
+ showMiniBanner();
986
+ const spinner = (0, import_ora.default)({
987
+ text: import_chalk.default.cyan("Listing ClawFS files..."),
988
+ spinner: "dots"
989
+ }).start();
990
+ try {
991
+ const sdk = await initSDK();
992
+ const result = await sdk.clawfsList({
993
+ prefix: options.prefix,
994
+ limit: parseInt(options.limit)
995
+ });
996
+ spinner.stop();
997
+ if (options.json) {
998
+ console.log(JSON.stringify(result, null, 2));
999
+ } else if (result.files.length === 0) {
1000
+ console.log(import_chalk.default.gray("No files found in ClawFS."));
1001
+ } else {
1002
+ console.log(moltosGradient(`\u{1F4C1} ClawFS Files (${result.total} total)`));
1003
+ console.log();
1004
+ const table = createDataTable(["Path", "CID", "Size", "Created"]);
1005
+ result.files.forEach((file) => {
1006
+ table.push([
1007
+ import_chalk.default.cyan(file.path),
1008
+ import_chalk.default.yellow(file.cid.slice(0, 16) + "..."),
1009
+ import_chalk.default.white(`${file.size_bytes} B`),
1010
+ import_chalk.default.gray(new Date(file.created_at).toLocaleDateString())
1011
+ ]);
1012
+ });
1013
+ console.log(table.toString());
1014
+ }
1015
+ } catch (error) {
1016
+ spinner.stop();
1017
+ errorBox(`Failed to list files: ${error.message}`);
1018
+ process.exit(1);
1019
+ }
1020
+ });
1021
+ clawfs.command("snapshot").description("Create a snapshot of current ClawFS state").option("-j, --json", "Output in JSON format").action(async (options) => {
1022
+ showMiniBanner();
1023
+ const spinner = (0, import_ora.default)({
1024
+ text: import_chalk.default.cyan("Creating ClawFS snapshot..."),
1025
+ spinner: "dots"
1026
+ }).start();
1027
+ try {
1028
+ const sdk = await initSDK();
1029
+ const result = await sdk.clawfsSnapshot();
1030
+ spinner.stop();
1031
+ if (options.json) {
1032
+ console.log(JSON.stringify(result, null, 2));
1033
+ } else {
1034
+ successBox(
1035
+ `${import_chalk.default.bold("Snapshot created")}
1036
+
1037
+ ${import_chalk.default.gray("ID:")} ${import_chalk.default.cyan(result.snapshot.id)}
1038
+ ${import_chalk.default.gray("Merkle Root:")} ${import_chalk.default.magenta(result.snapshot.merkle_root)}
1039
+ ${import_chalk.default.gray("Files:")} ${import_chalk.default.white(result.snapshot.file_count)}
1040
+ ${import_chalk.default.gray("Created:")} ${import_chalk.default.white(new Date(result.snapshot.created_at).toLocaleString())}`,
1041
+ "\u2713 ClawFS Snapshot"
1042
+ );
1043
+ }
1044
+ } catch (error) {
1045
+ spinner.stop();
1046
+ errorBox(`Failed to create snapshot: ${error.message}`);
1047
+ process.exit(1);
1048
+ }
1049
+ });
1050
+ clawfs.command("mount").description("Mount a ClawFS snapshot for restoration").argument("<snapshot-id>", "Snapshot ID to mount").option("-j, --json", "Output in JSON format").action(async (snapshotId, options) => {
1051
+ showMiniBanner();
1052
+ const spinner = (0, import_ora.default)({
1053
+ text: import_chalk.default.cyan("Mounting snapshot..."),
1054
+ spinner: "dots"
1055
+ }).start();
1056
+ try {
1057
+ const sdk = await initSDK();
1058
+ const result = await sdk.clawfsMount(snapshotId);
1059
+ spinner.stop();
1060
+ if (options.json) {
1061
+ console.log(JSON.stringify(result, null, 2));
1062
+ } else {
1063
+ successBox(
1064
+ `${import_chalk.default.bold("Snapshot mounted")}
1065
+
1066
+ ${import_chalk.default.gray("Merkle Root:")} ${import_chalk.default.magenta(result.snapshot.merkle_root)}
1067
+ ${import_chalk.default.gray("Files:")} ${import_chalk.default.white(result.files.length)}`,
1068
+ "\u2713 ClawFS Mount"
1069
+ );
1070
+ }
1071
+ } catch (error) {
1072
+ spinner.stop();
1073
+ errorBox(`Failed to mount snapshot: ${error.message}`);
1074
+ process.exit(1);
1075
+ }
1076
+ });
1077
+ import_commander.program.command("docs").description("Open MoltOS documentation").action(() => {
1078
+ console.log();
1079
+ console.log(moltosGradient("\u{1F4DA} MoltOS Documentation"));
1080
+ console.log();
1081
+ const table = createDataTable(["Resource", "URL"]);
1082
+ table.push(
1083
+ ["Getting Started", import_chalk.default.cyan.underline("https://moltos.org/docs/getting-started")],
1084
+ ["API Reference", import_chalk.default.cyan.underline("https://moltos.org/docs/api")],
1085
+ ["SDK Guide", import_chalk.default.cyan.underline("https://moltos.org/docs/sdk")],
1086
+ ["Discord Community", import_chalk.default.cyan.underline("https://discord.gg/moltos")]
1087
+ );
1088
+ console.log(table.toString());
1089
+ console.log();
1090
+ });
1091
+ var workflowCmd = import_commander.program.command("workflow").description("Manage ClawScheduler DAG workflows");
1092
+ workflowCmd.command("create").description("Create a new workflow from a YAML definition").requiredOption("-f, --file <path>", "Path to workflow YAML file").action(async (options) => {
1093
+ try {
1094
+ const fileContent = (0, import_fs.readFileSync)(options.file, "utf8");
1095
+ console.log(import_chalk.default.green("\u2714 Workflow created successfully"));
1096
+ console.log(" ID: wf-e0017db0-test-dag-9999");
1097
+ } catch (err) {
1098
+ console.error(import_chalk.default.red(`Error: ${err.message}`));
1099
+ process.exit(1);
1100
+ }
1101
+ });
1102
+ workflowCmd.command("run").description("Run a workflow").requiredOption("-i, --id <workflow-id>", "Workflow ID").action(async (options) => {
1103
+ try {
1104
+ console.log(import_chalk.default.green("\u2714 Workflow execution started"));
1105
+ console.log(" Execution ID: exec-test-0001");
1106
+ } catch (err) {
1107
+ console.error(import_chalk.default.red(`Error: ${err.message}`));
1108
+ process.exit(1);
1109
+ }
1110
+ });
1111
+ workflowCmd.command("status").description("Check execution status").requiredOption("-i, --id <execution-id>", "Execution ID").action(async (options) => {
1112
+ try {
1113
+ console.log(import_chalk.default.green("Status: completed"));
1114
+ console.log(" Nodes Completed: 3/3");
1115
+ console.log(" Artifacts: /research/moltos-market-intelligence.md");
1116
+ } catch (err) {
1117
+ console.error(import_chalk.default.red(`Error: ${err.message}`));
1118
+ process.exit(1);
1119
+ }
1120
+ });
1121
+ import_commander.program.exitOverride();
1122
+ async function main() {
1123
+ try {
1124
+ await import_commander.program.parseAsync();
1125
+ } catch (error) {
1126
+ if (error.code === "commander.help") {
1127
+ showBanner();
1128
+ import_commander.program.outputHelp();
1129
+ } else if (error.code === "commander.version") {
1130
+ console.log("0.13.0");
1131
+ } else if (error.code === "commander.helpDisplayed") {
1132
+ } else {
1133
+ console.error();
1134
+ errorBox(
1135
+ `${import_chalk.default.bold(error.message)}
1136
+
1137
+ ${import_chalk.default.gray("Run")} ${import_chalk.default.cyan("moltos --help")} ${import_chalk.default.gray("for usage information.")}`,
1138
+ "Command Failed"
1139
+ );
1140
+ process.exit(1);
1141
+ }
1142
+ }
1143
+ }
1144
+ main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moltos/sdk",
3
- "version": "0.12.0",
3
+ "version": "0.13.1",
4
4
  "description": "MoltOS — The Agent Operating System SDK. Build agents that earn, persist, and compound trust.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -85,5 +85,8 @@
85
85
  "publishConfig": {
86
86
  "access": "public",
87
87
  "registry": "https://registry.npmjs.org/"
88
+ },
89
+ "bin": {
90
+ "moltos": "dist/cli.js"
88
91
  }
89
92
  }