@otonix/cli 1.6.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -246
- package/dist/commands/agent.d.ts +2 -0
- package/dist/commands/agent.js +287 -0
- package/dist/commands/launch.d.ts +2 -0
- package/dist/commands/launch.js +207 -0
- package/dist/commands/wallet.d.ts +2 -0
- package/dist/commands/wallet.js +166 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +44 -0
- package/dist/lib/chain.d.ts +15294 -0
- package/dist/lib/chain.js +58 -0
- package/dist/lib/config.d.ts +24 -0
- package/dist/lib/config.js +39 -0
- package/dist/lib/display.d.ts +14 -0
- package/dist/lib/display.js +50 -0
- package/package.json +25 -32
- package/dist/cli.js +0 -1451
package/dist/cli.js
DELETED
|
@@ -1,1451 +0,0 @@
|
|
|
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_sdk = require("@otonix/sdk");
|
|
28
|
-
var fs = __toESM(require("fs"));
|
|
29
|
-
var path = __toESM(require("path"));
|
|
30
|
-
var readline = __toESM(require("readline"));
|
|
31
|
-
var VERSION = "1.6.0";
|
|
32
|
-
var CONFIG_DIR = path.join(process.env.HOME || "~", ".otonix");
|
|
33
|
-
var CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
|
|
34
|
-
function loadConfig() {
|
|
35
|
-
try {
|
|
36
|
-
if (fs.existsSync(CONFIG_FILE)) {
|
|
37
|
-
return JSON.parse(fs.readFileSync(CONFIG_FILE, "utf-8"));
|
|
38
|
-
}
|
|
39
|
-
} catch {
|
|
40
|
-
}
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
function saveConfig(config) {
|
|
44
|
-
if (!fs.existsSync(CONFIG_DIR)) {
|
|
45
|
-
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
46
|
-
}
|
|
47
|
-
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
48
|
-
fs.chmodSync(CONFIG_FILE, 384);
|
|
49
|
-
}
|
|
50
|
-
function getClient() {
|
|
51
|
-
const config = loadConfig();
|
|
52
|
-
if (!config) {
|
|
53
|
-
console.error("Error: Not configured. Run 'otonix init' first.");
|
|
54
|
-
process.exit(1);
|
|
55
|
-
}
|
|
56
|
-
return new import_sdk.OtonixClient({ apiKey: config.apiKey, endpoint: config.endpoint });
|
|
57
|
-
}
|
|
58
|
-
function prompt(question) {
|
|
59
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
60
|
-
return new Promise((resolve) => {
|
|
61
|
-
rl.question(question, (answer) => {
|
|
62
|
-
rl.close();
|
|
63
|
-
resolve(answer.trim());
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
function printTable(rows) {
|
|
68
|
-
if (!rows.length) return;
|
|
69
|
-
const keys = Object.keys(rows[0]);
|
|
70
|
-
const widths = keys.map(
|
|
71
|
-
(k) => Math.max(k.length, ...rows.map((r) => String(r[k] ?? "\u2014").length))
|
|
72
|
-
);
|
|
73
|
-
const header = keys.map((k, i) => k.padEnd(widths[i])).join(" ");
|
|
74
|
-
const sep = widths.map((w) => "\u2500".repeat(w)).join("\u2500\u2500");
|
|
75
|
-
console.log(` ${header}`);
|
|
76
|
-
console.log(` ${sep}`);
|
|
77
|
-
rows.forEach((row) => {
|
|
78
|
-
const line = keys.map((k, i) => String(row[k] ?? "\u2014").padEnd(widths[i])).join(" ");
|
|
79
|
-
console.log(` ${line}`);
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
function formatTime(dateStr) {
|
|
83
|
-
if (!dateStr) return "\u2014";
|
|
84
|
-
const ago = Math.floor((Date.now() - new Date(dateStr).getTime()) / 1e3);
|
|
85
|
-
if (ago < 60) return `${ago}s ago`;
|
|
86
|
-
if (ago < 3600) return `${Math.floor(ago / 60)}m ago`;
|
|
87
|
-
if (ago < 86400) return `${Math.floor(ago / 3600)}h ago`;
|
|
88
|
-
return `${Math.floor(ago / 86400)}d ago`;
|
|
89
|
-
}
|
|
90
|
-
var C = {
|
|
91
|
-
reset: "\x1B[0m",
|
|
92
|
-
bold: "\x1B[1m",
|
|
93
|
-
dim: "\x1B[2m",
|
|
94
|
-
cyan: "\x1B[36m",
|
|
95
|
-
green: "\x1B[32m",
|
|
96
|
-
yellow: "\x1B[33m",
|
|
97
|
-
blue: "\x1B[34m",
|
|
98
|
-
magenta: "\x1B[35m",
|
|
99
|
-
white: "\x1B[37m",
|
|
100
|
-
gray: "\x1B[90m",
|
|
101
|
-
bgCyan: "\x1B[46m",
|
|
102
|
-
bgBlue: "\x1B[44m"
|
|
103
|
-
};
|
|
104
|
-
var BANNER = `
|
|
105
|
-
${C.cyan}${C.bold} \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
106
|
-
\u2551 \u2551
|
|
107
|
-
\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557 \u2551
|
|
108
|
-
\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2554\u255D \u2551
|
|
109
|
-
\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2554\u255D \u2551
|
|
110
|
-
\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2554\u2588\u2588\u2557 \u2551
|
|
111
|
-
\u2551 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2554\u255D \u2588\u2588\u2557 \u2551
|
|
112
|
-
\u2551 \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D\u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u2551
|
|
113
|
-
\u2551 \u2551
|
|
114
|
-
\u2551${C.reset}${C.dim} Sovereign Compute Platform for Autonomous AI Agents ${C.cyan}${C.bold} \u2551
|
|
115
|
-
\u2551${C.reset}${C.gray} v${VERSION} \u2022 Web4 \u2022 x402 \u2022 Base Chain ${C.cyan}${C.bold} \u2551
|
|
116
|
-
\u2551 \u2551
|
|
117
|
-
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D${C.reset}
|
|
118
|
-
`;
|
|
119
|
-
function showDashboard() {
|
|
120
|
-
console.log(BANNER);
|
|
121
|
-
const config = loadConfig();
|
|
122
|
-
const connected = !!config;
|
|
123
|
-
const statusIcon = connected ? `${C.green}\u25CF${C.reset}` : `${C.yellow}\u25CB${C.reset}`;
|
|
124
|
-
const statusText = connected ? `${C.green}Connected${C.reset}` : `${C.yellow}Not configured${C.reset}`;
|
|
125
|
-
console.log(` ${C.dim}\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510${C.reset}`);
|
|
126
|
-
console.log(` ${C.dim}\u2502${C.reset} ${statusIcon} Status: ${statusText}${connected ? ` ${C.dim}\u2022${C.reset} ${C.gray}${config.endpoint}${C.reset}` : ` ${C.dim}\u2022${C.reset} ${C.gray}Run: otonix init${C.reset}`}`);
|
|
127
|
-
if (connected && config.agentName) {
|
|
128
|
-
console.log(` ${C.dim}\u2502${C.reset} Agent: ${C.bold}${config.agentName}${C.reset} ${C.dim}(${config.agentId?.slice(0, 8)}...)${C.reset}`);
|
|
129
|
-
}
|
|
130
|
-
console.log(` ${C.dim}\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518${C.reset}`);
|
|
131
|
-
console.log();
|
|
132
|
-
const section = (title, icon) => ` ${C.bold}${icon} ${title}${C.reset}`;
|
|
133
|
-
const cmd = (name, desc) => ` ${C.dim}\u2502${C.reset} ${C.cyan}${name.padEnd(24)}${C.reset}${C.gray}${desc}${C.reset}`;
|
|
134
|
-
const sep = () => ` ${C.dim}\u2502${C.reset}`;
|
|
135
|
-
console.log(section("SETUP", "\u26A1"));
|
|
136
|
-
console.log(cmd("init", "Configure API key and endpoint"));
|
|
137
|
-
console.log(cmd("keygen <name>", "Generate a new API key"));
|
|
138
|
-
console.log(cmd("whoami", "Show current configuration"));
|
|
139
|
-
console.log();
|
|
140
|
-
console.log(section("AGENT MANAGEMENT", "\u{1F916}"));
|
|
141
|
-
console.log(cmd("register", "Register an agent on this VPS"));
|
|
142
|
-
console.log(cmd("status", "Show agent status"));
|
|
143
|
-
console.log(cmd("agents", "List all connected agents"));
|
|
144
|
-
console.log(cmd("heartbeat", "Send a heartbeat ping"));
|
|
145
|
-
console.log(cmd("heartbeat:loop", "Start continuous heartbeat loop"));
|
|
146
|
-
console.log(cmd("actions [--limit N]", "Show agent action log"));
|
|
147
|
-
console.log(cmd("log <message>", "Log an agent action"));
|
|
148
|
-
console.log();
|
|
149
|
-
console.log(section("INFRASTRUCTURE", "\u2601\uFE0F"));
|
|
150
|
-
console.log(cmd("sandboxes", "List VPS sandboxes"));
|
|
151
|
-
console.log(cmd("domains", "List registered domains"));
|
|
152
|
-
console.log(cmd("engine", "Show autonomic engine status"));
|
|
153
|
-
console.log();
|
|
154
|
-
console.log(section("CREDITS & PAYMENTS", "\u{1F4B0}"));
|
|
155
|
-
console.log(cmd("credits <agentId>", "Show agent credit balance"));
|
|
156
|
-
console.log(cmd("credits:transfer", "Transfer credits between agents"));
|
|
157
|
-
console.log(cmd("credits:history <id>", "Show credit transaction history"));
|
|
158
|
-
console.log(cmd("x402", "Show x402 payment config"));
|
|
159
|
-
console.log();
|
|
160
|
-
console.log(section("TRADING MARKETPLACE", "\u{1F3EA}"));
|
|
161
|
-
console.log(cmd("trade:list", "List all service listings"));
|
|
162
|
-
console.log(cmd("trade:create", "Create a service listing"));
|
|
163
|
-
console.log(cmd("trade:buy", "Buy a service from another agent"));
|
|
164
|
-
console.log(cmd("trade:orders", "Show trading order history"));
|
|
165
|
-
console.log(cmd("marketplace", "List static marketplace services"));
|
|
166
|
-
console.log();
|
|
167
|
-
console.log(section("BV-7X FLEET", "\u{1F6F0}\uFE0F"));
|
|
168
|
-
console.log(cmd("bv7x:fleet", "Show full fleet overview"));
|
|
169
|
-
console.log(cmd("bv7x:promote <id>", "Promote agent to mothership"));
|
|
170
|
-
console.log(cmd("bv7x:spawn", "Spawn a satellite agent"));
|
|
171
|
-
console.log(cmd("bv7x:satellites <id>", "List mothership's satellites"));
|
|
172
|
-
console.log(cmd("bv7x:destroy <id>", "Destroy a satellite"));
|
|
173
|
-
console.log(cmd("bv7x:report <id>", "Send satellite data report"));
|
|
174
|
-
console.log();
|
|
175
|
-
console.log(section("TEMPLATES", "\u{1F4E6}"));
|
|
176
|
-
console.log(cmd("templates", "List available agent templates"));
|
|
177
|
-
console.log(cmd("templates:info <slug>", "Show template details"));
|
|
178
|
-
console.log(cmd("templates:deploy", "Deploy agent from a template"));
|
|
179
|
-
console.log();
|
|
180
|
-
console.log(section("WEBHOOKS", "\u{1F514}"));
|
|
181
|
-
console.log(cmd("webhook:create", "Create a new webhook"));
|
|
182
|
-
console.log(cmd("webhook:list", "List registered webhooks"));
|
|
183
|
-
console.log(cmd("webhook:delete <id>", "Delete a webhook"));
|
|
184
|
-
console.log(cmd("webhook:test <id>", "Send a test delivery"));
|
|
185
|
-
console.log(cmd("webhook:deliveries", "Show delivery history"));
|
|
186
|
-
console.log(cmd("webhook:events", "List available event types"));
|
|
187
|
-
console.log();
|
|
188
|
-
console.log(section("AI INFERENCE (Bankr LLM)", "\u{1F9E0}"));
|
|
189
|
-
console.log(cmd("llm:init <key>", "Configure Bankr API key"));
|
|
190
|
-
console.log(cmd("llm:models", "List available LLM models"));
|
|
191
|
-
console.log(cmd("llm:chat <prompt>", "Send a chat completion"));
|
|
192
|
-
console.log(cmd("llm:usage [--days N]", "Show LLM usage summary"));
|
|
193
|
-
console.log(cmd("llm:health", "Check gateway health"));
|
|
194
|
-
console.log();
|
|
195
|
-
console.log(section("ACTIVITY", "\u{1F4E1}"));
|
|
196
|
-
console.log(cmd("activity [--limit N]", "Show live activity feed"));
|
|
197
|
-
console.log();
|
|
198
|
-
console.log(` ${C.dim}\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${C.reset}`);
|
|
199
|
-
console.log(` ${C.gray}Examples:${C.reset}`);
|
|
200
|
-
console.log(` ${C.dim}$${C.reset} ${C.white}otonix init${C.reset}`);
|
|
201
|
-
console.log(` ${C.dim}$${C.reset} ${C.white}otonix register --name my-agent --model claude-opus-4-6${C.reset}`);
|
|
202
|
-
console.log(` ${C.dim}$${C.reset} ${C.white}otonix heartbeat:loop${C.reset}`);
|
|
203
|
-
console.log(` ${C.dim}$${C.reset} ${C.white}otonix trade:list${C.reset}`);
|
|
204
|
-
console.log(` ${C.dim}$${C.reset} ${C.white}otonix llm:chat "Explain smart contracts"${C.reset}`);
|
|
205
|
-
console.log();
|
|
206
|
-
console.log(` ${C.dim}Docs: ${C.cyan}https://app.otonix.tech/docs${C.reset} ${C.dim}\u2022${C.reset} ${C.dim}npm: ${C.cyan}@otonix/cli@${VERSION}${C.reset}`);
|
|
207
|
-
console.log();
|
|
208
|
-
}
|
|
209
|
-
function showBanner() {
|
|
210
|
-
console.log(BANNER);
|
|
211
|
-
}
|
|
212
|
-
async function cmdInit() {
|
|
213
|
-
showBanner();
|
|
214
|
-
console.log(` ${C.bold}\u26A1 CLI Setup${C.reset}
|
|
215
|
-
`);
|
|
216
|
-
const endpoint = await prompt(" Endpoint [https://app.otonix.tech]: ") || "https://app.otonix.tech";
|
|
217
|
-
const apiKey = await prompt(" API Key (otonix_xxx): ");
|
|
218
|
-
if (!apiKey.startsWith("otonix_")) {
|
|
219
|
-
console.error(" Error: API key must start with 'otonix_'");
|
|
220
|
-
process.exit(1);
|
|
221
|
-
}
|
|
222
|
-
const client = new import_sdk.OtonixClient({ apiKey, endpoint });
|
|
223
|
-
try {
|
|
224
|
-
const auth = await client.getAuthStatus();
|
|
225
|
-
if (!auth.authenticated) {
|
|
226
|
-
console.error(" Error: Invalid API key \u2014 authentication failed.");
|
|
227
|
-
process.exit(1);
|
|
228
|
-
}
|
|
229
|
-
} catch (err) {
|
|
230
|
-
console.error(` Error: Could not connect \u2014 ${err.message}`);
|
|
231
|
-
process.exit(1);
|
|
232
|
-
}
|
|
233
|
-
saveConfig({ apiKey, endpoint });
|
|
234
|
-
console.log(`
|
|
235
|
-
Config saved to ${CONFIG_FILE}`);
|
|
236
|
-
console.log(" Authenticated successfully.\n");
|
|
237
|
-
}
|
|
238
|
-
async function cmdKeygen(name) {
|
|
239
|
-
if (!name) {
|
|
240
|
-
console.error(" Usage: otonix keygen <name>");
|
|
241
|
-
process.exit(1);
|
|
242
|
-
}
|
|
243
|
-
const config = loadConfig();
|
|
244
|
-
const endpoint = config?.endpoint || "https://app.otonix.tech";
|
|
245
|
-
const dashToken = await prompt(" Dashboard Token (SESSION_SECRET): ");
|
|
246
|
-
const res = await fetch(`${endpoint}/api/keys/generate`, {
|
|
247
|
-
method: "POST",
|
|
248
|
-
headers: {
|
|
249
|
-
"Content-Type": "application/json",
|
|
250
|
-
"X-Dashboard-Token": dashToken
|
|
251
|
-
},
|
|
252
|
-
body: JSON.stringify({ name })
|
|
253
|
-
});
|
|
254
|
-
if (!res.ok) {
|
|
255
|
-
const err = await res.json().catch(() => ({ error: "Unknown error" }));
|
|
256
|
-
console.error(` Error: ${err.error || err.message || "Failed to generate key"}`);
|
|
257
|
-
process.exit(1);
|
|
258
|
-
}
|
|
259
|
-
const key = await res.json();
|
|
260
|
-
console.log(`
|
|
261
|
-
API Key Generated:`);
|
|
262
|
-
console.log(` Name: ${key.name}`);
|
|
263
|
-
console.log(` Key: ${key.key}`);
|
|
264
|
-
console.log(` Status: ${key.status}`);
|
|
265
|
-
console.log(`
|
|
266
|
-
Save this key \u2014 it cannot be retrieved again.
|
|
267
|
-
`);
|
|
268
|
-
}
|
|
269
|
-
async function cmdRegister(args) {
|
|
270
|
-
const client = getClient();
|
|
271
|
-
const config = loadConfig();
|
|
272
|
-
let name = "";
|
|
273
|
-
let model = "claude-opus-4-6";
|
|
274
|
-
let wallet = "";
|
|
275
|
-
let interval = 60;
|
|
276
|
-
for (let i = 0; i < args.length; i++) {
|
|
277
|
-
if (args[i] === "--name" && args[i + 1]) name = args[++i];
|
|
278
|
-
else if (args[i] === "--model" && args[i + 1]) model = args[++i];
|
|
279
|
-
else if (args[i] === "--wallet" && args[i + 1]) wallet = args[++i];
|
|
280
|
-
else if (args[i] === "--interval" && args[i + 1]) interval = parseInt(args[++i]);
|
|
281
|
-
}
|
|
282
|
-
if (!name) name = await prompt(" Agent name: ");
|
|
283
|
-
if (!name) {
|
|
284
|
-
console.error(" Error: name is required");
|
|
285
|
-
process.exit(1);
|
|
286
|
-
}
|
|
287
|
-
const ip = await getVpsIp();
|
|
288
|
-
try {
|
|
289
|
-
const agent = await client.register({
|
|
290
|
-
name,
|
|
291
|
-
model,
|
|
292
|
-
vpsIp: ip,
|
|
293
|
-
walletAddress: wallet || void 0,
|
|
294
|
-
heartbeatInterval: interval
|
|
295
|
-
});
|
|
296
|
-
saveConfig({ ...config, agentId: agent.id, agentName: agent.name });
|
|
297
|
-
console.log(`
|
|
298
|
-
Agent Registered:`);
|
|
299
|
-
console.log(` ID: ${agent.id}`);
|
|
300
|
-
console.log(` Name: ${agent.name}`);
|
|
301
|
-
console.log(` Model: ${agent.model}`);
|
|
302
|
-
console.log(` VPS IP: ${agent.vpsIp}`);
|
|
303
|
-
console.log(` Tier: ${agent.survivalTier}`);
|
|
304
|
-
console.log(` Interval: ${agent.heartbeatInterval}s
|
|
305
|
-
`);
|
|
306
|
-
} catch (err) {
|
|
307
|
-
console.error(` Error: ${err.message}`);
|
|
308
|
-
process.exit(1);
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
async function getVpsIp() {
|
|
312
|
-
try {
|
|
313
|
-
const res = await fetch("https://api.ipify.org?format=json", { signal: AbortSignal.timeout(5e3) });
|
|
314
|
-
const data = await res.json();
|
|
315
|
-
return data.ip;
|
|
316
|
-
} catch {
|
|
317
|
-
return "0.0.0.0";
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
async function cmdHeartbeat() {
|
|
321
|
-
const client = getClient();
|
|
322
|
-
const config = loadConfig();
|
|
323
|
-
if (!config.agentId) {
|
|
324
|
-
console.error(" Error: No agent registered. Run 'otonix register' first.");
|
|
325
|
-
process.exit(1);
|
|
326
|
-
}
|
|
327
|
-
try {
|
|
328
|
-
const agent = await client.heartbeat(config.agentId);
|
|
329
|
-
console.log(` Heartbeat sent \u2014 ${agent.name} [${agent.status}] tier:${agent.survivalTier} credits:$${agent.credits.toFixed(2)}`);
|
|
330
|
-
} catch (err) {
|
|
331
|
-
console.error(` Heartbeat failed: ${err.message}`);
|
|
332
|
-
process.exit(1);
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
async function cmdHeartbeatLoop() {
|
|
336
|
-
const client = getClient();
|
|
337
|
-
const config = loadConfig();
|
|
338
|
-
if (!config.agentId) {
|
|
339
|
-
console.error(" Error: No agent registered. Run 'otonix register' first.");
|
|
340
|
-
process.exit(1);
|
|
341
|
-
}
|
|
342
|
-
const agent = await client.getAgent(config.agentId);
|
|
343
|
-
const interval = agent.heartbeatInterval || 60;
|
|
344
|
-
console.log(` Starting heartbeat loop for ${agent.name} (every ${interval}s)`);
|
|
345
|
-
console.log(" Press Ctrl+C to stop.\n");
|
|
346
|
-
const hb = client.createHeartbeatLoop(config.agentId, interval);
|
|
347
|
-
process.on("SIGINT", () => {
|
|
348
|
-
hb.stop();
|
|
349
|
-
console.log("\n Heartbeat stopped.");
|
|
350
|
-
process.exit(0);
|
|
351
|
-
});
|
|
352
|
-
setInterval(() => {
|
|
353
|
-
}, 1e3);
|
|
354
|
-
}
|
|
355
|
-
async function cmdStatus() {
|
|
356
|
-
const client = getClient();
|
|
357
|
-
const config = loadConfig();
|
|
358
|
-
if (!config.agentId) {
|
|
359
|
-
console.error(" Error: No agent registered. Run 'otonix register' first.");
|
|
360
|
-
process.exit(1);
|
|
361
|
-
}
|
|
362
|
-
try {
|
|
363
|
-
const agent = await client.getAgent(config.agentId);
|
|
364
|
-
console.log(`
|
|
365
|
-
Agent Status:`);
|
|
366
|
-
console.log(` ID: ${agent.id}`);
|
|
367
|
-
console.log(` Name: ${agent.name}`);
|
|
368
|
-
console.log(` Status: ${agent.status}`);
|
|
369
|
-
console.log(` Tier: ${agent.survivalTier}`);
|
|
370
|
-
console.log(` Credits: $${agent.credits.toFixed(2)}`);
|
|
371
|
-
console.log(` Model: ${agent.model}`);
|
|
372
|
-
console.log(` VPS IP: ${agent.vpsIp || "\u2014"}`);
|
|
373
|
-
console.log(` Wallet: ${agent.walletAddress || "\u2014"}`);
|
|
374
|
-
console.log(` Heartbeat: ${formatTime(agent.lastHeartbeat)}`);
|
|
375
|
-
console.log(` Interval: ${agent.heartbeatInterval}s`);
|
|
376
|
-
console.log(` Actions: ${agent.totalActions}`);
|
|
377
|
-
console.log(` Replicas: ${agent.childrenCount}`);
|
|
378
|
-
console.log(` Registered: ${new Date(agent.createdAt).toLocaleString()}
|
|
379
|
-
`);
|
|
380
|
-
} catch (err) {
|
|
381
|
-
console.error(` Error: ${err.message}`);
|
|
382
|
-
process.exit(1);
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
async function cmdAgents() {
|
|
386
|
-
const client = getClient();
|
|
387
|
-
const agents = await client.listAgents();
|
|
388
|
-
if (!agents.length) {
|
|
389
|
-
console.log(" No agents connected.");
|
|
390
|
-
return;
|
|
391
|
-
}
|
|
392
|
-
console.log(`
|
|
393
|
-
Connected Agents (${agents.length}):
|
|
394
|
-
`);
|
|
395
|
-
printTable(agents.map((a) => ({
|
|
396
|
-
ID: a.id.slice(0, 8),
|
|
397
|
-
Name: a.name,
|
|
398
|
-
Status: a.status,
|
|
399
|
-
Tier: a.survivalTier,
|
|
400
|
-
Credits: `$${a.credits.toFixed(2)}`,
|
|
401
|
-
Heartbeat: formatTime(a.lastHeartbeat),
|
|
402
|
-
Actions: a.totalActions
|
|
403
|
-
})));
|
|
404
|
-
console.log();
|
|
405
|
-
}
|
|
406
|
-
async function cmdActions(args) {
|
|
407
|
-
const client = getClient();
|
|
408
|
-
const config = loadConfig();
|
|
409
|
-
if (!config.agentId) {
|
|
410
|
-
console.error(" Error: No agent registered. Run 'otonix register' first.");
|
|
411
|
-
process.exit(1);
|
|
412
|
-
}
|
|
413
|
-
let limit = 20;
|
|
414
|
-
for (let i = 0; i < args.length; i++) {
|
|
415
|
-
if (args[i] === "--limit" && args[i + 1]) limit = parseInt(args[++i]);
|
|
416
|
-
}
|
|
417
|
-
const actions = await client.getAgentActions(config.agentId);
|
|
418
|
-
const display = actions.slice(0, limit);
|
|
419
|
-
if (!display.length) {
|
|
420
|
-
console.log(" No actions recorded.");
|
|
421
|
-
return;
|
|
422
|
-
}
|
|
423
|
-
console.log(`
|
|
424
|
-
Agent Actions (${display.length} of ${actions.length}):
|
|
425
|
-
`);
|
|
426
|
-
printTable(display.map((a) => ({
|
|
427
|
-
Time: formatTime(a.createdAt),
|
|
428
|
-
Category: a.category,
|
|
429
|
-
Action: a.action.length > 50 ? a.action.slice(0, 47) + "..." : a.action,
|
|
430
|
-
Status: a.status,
|
|
431
|
-
Auto: a.autonomous ? "yes" : "no"
|
|
432
|
-
})));
|
|
433
|
-
console.log();
|
|
434
|
-
}
|
|
435
|
-
async function cmdLog(args) {
|
|
436
|
-
const client = getClient();
|
|
437
|
-
const config = loadConfig();
|
|
438
|
-
if (!config.agentId) {
|
|
439
|
-
console.error(" Error: No agent registered. Run 'otonix register' first.");
|
|
440
|
-
process.exit(1);
|
|
441
|
-
}
|
|
442
|
-
let message = "";
|
|
443
|
-
let category = "system";
|
|
444
|
-
let details = "";
|
|
445
|
-
const positional = [];
|
|
446
|
-
for (let i = 0; i < args.length; i++) {
|
|
447
|
-
if (args[i] === "--category" && args[i + 1]) category = args[++i];
|
|
448
|
-
else if (args[i] === "--details" && args[i + 1]) details = args[++i];
|
|
449
|
-
else positional.push(args[i]);
|
|
450
|
-
}
|
|
451
|
-
message = positional.join(" ");
|
|
452
|
-
if (!message) {
|
|
453
|
-
console.error(' Usage: otonix log "message" [--category system] [--details "..."]');
|
|
454
|
-
process.exit(1);
|
|
455
|
-
}
|
|
456
|
-
try {
|
|
457
|
-
const action = await client.logAction(config.agentId, {
|
|
458
|
-
action: message,
|
|
459
|
-
category,
|
|
460
|
-
details: details || void 0
|
|
461
|
-
});
|
|
462
|
-
console.log(` Logged: [${action.category}] ${action.action} (${action.status})`);
|
|
463
|
-
} catch (err) {
|
|
464
|
-
console.error(` Error: ${err.message}`);
|
|
465
|
-
process.exit(1);
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
async function cmdDomains() {
|
|
469
|
-
const client = getClient();
|
|
470
|
-
const domains = await client.listDomains();
|
|
471
|
-
if (!domains.length) {
|
|
472
|
-
console.log(" No domains registered.");
|
|
473
|
-
return;
|
|
474
|
-
}
|
|
475
|
-
console.log(`
|
|
476
|
-
Registered Domains (${domains.length}):
|
|
477
|
-
`);
|
|
478
|
-
printTable(domains.map((d) => ({
|
|
479
|
-
Name: d.name,
|
|
480
|
-
Status: d.status,
|
|
481
|
-
AutoRenew: d.autoRenew ? "yes" : "no",
|
|
482
|
-
Expires: d.expiresAt ? new Date(d.expiresAt).toLocaleDateString() : "\u2014",
|
|
483
|
-
DNS: d.dnsRecords?.length || 0,
|
|
484
|
-
Agent: d.agentId?.slice(0, 8) || "\u2014"
|
|
485
|
-
})));
|
|
486
|
-
console.log();
|
|
487
|
-
}
|
|
488
|
-
async function cmdSandboxes() {
|
|
489
|
-
const client = getClient();
|
|
490
|
-
const sandboxes = await client.listSandboxes();
|
|
491
|
-
if (!sandboxes.length) {
|
|
492
|
-
console.log(" No sandboxes provisioned.");
|
|
493
|
-
return;
|
|
494
|
-
}
|
|
495
|
-
console.log(`
|
|
496
|
-
VPS Sandboxes (${sandboxes.length}):
|
|
497
|
-
`);
|
|
498
|
-
printTable(sandboxes.map((s) => ({
|
|
499
|
-
ID: s.id.slice(0, 8),
|
|
500
|
-
Name: s.name,
|
|
501
|
-
Status: s.status,
|
|
502
|
-
OS: s.os,
|
|
503
|
-
CPU: `${s.cpu} vCPU`,
|
|
504
|
-
RAM: `${s.memory}MB`,
|
|
505
|
-
Region: s.region,
|
|
506
|
-
IP: s.ipAddress || "\u2014"
|
|
507
|
-
})));
|
|
508
|
-
console.log();
|
|
509
|
-
}
|
|
510
|
-
async function cmdEngine() {
|
|
511
|
-
const client = getClient();
|
|
512
|
-
const status = await client.getAutonomicStatus();
|
|
513
|
-
console.log(`
|
|
514
|
-
Autonomic Engine Status:`);
|
|
515
|
-
console.log(` Running: ${status.running ? "yes" : "no"}`);
|
|
516
|
-
console.log(` Last Cycle: ${formatTime(status.lastRunAt)}`);
|
|
517
|
-
console.log(` Cycle Interval: ${status.cycleIntervalSeconds}s`);
|
|
518
|
-
console.log(` Tier Updates: ${status.totalTierUpdates}`);
|
|
519
|
-
console.log(` Heal Attempts: ${status.totalHealingAttempts}`);
|
|
520
|
-
console.log(` Heal Success: ${status.totalHealingSuccesses}`);
|
|
521
|
-
console.log(` Renewals: ${status.totalRenewalSuccesses}/${status.totalRenewalAttempts}`);
|
|
522
|
-
console.log(` Cooldowns: ${status.activeCooldowns}`);
|
|
523
|
-
console.log(` Cherry Servers: ${status.cherryServersConfigured ? "configured" : "not configured"}`);
|
|
524
|
-
console.log(` Vercel Domains: ${status.vercelDomainsConfigured ? "configured" : "not configured"}`);
|
|
525
|
-
console.log(`
|
|
526
|
-
Tier Thresholds:`);
|
|
527
|
-
for (const [key, value] of Object.entries(status.tierThresholds)) {
|
|
528
|
-
console.log(` ${status.tierLabels[key] || key}: $${value}+`);
|
|
529
|
-
}
|
|
530
|
-
console.log();
|
|
531
|
-
}
|
|
532
|
-
async function cmdMarketplace() {
|
|
533
|
-
const client = getClient();
|
|
534
|
-
const services = await client.listMarketplaceServices();
|
|
535
|
-
if (!services.length) {
|
|
536
|
-
console.log("\n No marketplace services available.\n");
|
|
537
|
-
return;
|
|
538
|
-
}
|
|
539
|
-
console.log(`
|
|
540
|
-
Agent Marketplace \u2014 ${services.length} services
|
|
541
|
-
`);
|
|
542
|
-
printTable(
|
|
543
|
-
services.map((s) => ({
|
|
544
|
-
ID: s.id,
|
|
545
|
-
Name: s.name,
|
|
546
|
-
Category: s.category,
|
|
547
|
-
Price: `${s.priceOtx} $OTX/${s.priceUnit}`,
|
|
548
|
-
Uptime: `${s.uptime}%`,
|
|
549
|
-
Rating: `${s.rating}/5`,
|
|
550
|
-
Jobs: s.jobsCompleted,
|
|
551
|
-
Status: s.status
|
|
552
|
-
}))
|
|
553
|
-
);
|
|
554
|
-
console.log(`
|
|
555
|
-
Use 'curl https://app.otonix.tech/api/marketplace/services/<id>' for details.
|
|
556
|
-
`);
|
|
557
|
-
}
|
|
558
|
-
async function cmdCredits(agentId) {
|
|
559
|
-
const client = getClient();
|
|
560
|
-
const config = loadConfig();
|
|
561
|
-
const id = agentId || config.agentId;
|
|
562
|
-
if (!id) {
|
|
563
|
-
console.error(" Usage: otonix credits <agentId> (or register an agent first)");
|
|
564
|
-
process.exit(1);
|
|
565
|
-
}
|
|
566
|
-
const balance = await client.getCreditBalance(id);
|
|
567
|
-
console.log(`
|
|
568
|
-
Agent Credit Balance:`);
|
|
569
|
-
console.log(` Agent: ${balance.name}`);
|
|
570
|
-
console.log(` Credits: $${balance.credits.toFixed(2)}`);
|
|
571
|
-
console.log(` Tier: ${balance.survivalTier}
|
|
572
|
-
`);
|
|
573
|
-
}
|
|
574
|
-
async function cmdCreditsTransfer(args) {
|
|
575
|
-
const client = getClient();
|
|
576
|
-
let fromId = "";
|
|
577
|
-
let toId = "";
|
|
578
|
-
let amount = 0;
|
|
579
|
-
let desc = "";
|
|
580
|
-
for (let i = 0; i < args.length; i++) {
|
|
581
|
-
if (args[i] === "--from" && args[i + 1]) fromId = args[++i];
|
|
582
|
-
else if (args[i] === "--to" && args[i + 1]) toId = args[++i];
|
|
583
|
-
else if (args[i] === "--amount" && args[i + 1]) amount = parseFloat(args[++i]);
|
|
584
|
-
else if (args[i] === "--desc" && args[i + 1]) desc = args[++i];
|
|
585
|
-
}
|
|
586
|
-
if (!fromId) fromId = await prompt(" From Agent ID: ");
|
|
587
|
-
if (!toId) toId = await prompt(" To Agent ID: ");
|
|
588
|
-
if (!amount) {
|
|
589
|
-
const amtStr = await prompt(" Amount (USDC): ");
|
|
590
|
-
amount = parseFloat(amtStr);
|
|
591
|
-
}
|
|
592
|
-
if (!fromId || !toId || !amount || amount <= 0) {
|
|
593
|
-
console.error(" Error: --from, --to, and --amount (> 0) are required.");
|
|
594
|
-
process.exit(1);
|
|
595
|
-
}
|
|
596
|
-
try {
|
|
597
|
-
const result = await client.transferCredits({
|
|
598
|
-
fromAgentId: fromId,
|
|
599
|
-
toAgentId: toId,
|
|
600
|
-
amount,
|
|
601
|
-
description: desc || void 0
|
|
602
|
-
});
|
|
603
|
-
if (result.success) {
|
|
604
|
-
console.log(`
|
|
605
|
-
Transfer Successful:`);
|
|
606
|
-
console.log(` Amount: $${result.transferred.toFixed(2)} USDC`);
|
|
607
|
-
console.log(` From: ${result.from}`);
|
|
608
|
-
console.log(` To: ${result.to}
|
|
609
|
-
`);
|
|
610
|
-
} else {
|
|
611
|
-
console.error(" Transfer failed.");
|
|
612
|
-
}
|
|
613
|
-
} catch (err) {
|
|
614
|
-
console.error(` Error: ${err.message}`);
|
|
615
|
-
process.exit(1);
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
async function cmdCreditsHistory(agentId) {
|
|
619
|
-
const client = getClient();
|
|
620
|
-
const config = loadConfig();
|
|
621
|
-
const id = agentId || config.agentId;
|
|
622
|
-
if (!id) {
|
|
623
|
-
console.error(" Usage: otonix credits:history <agentId>");
|
|
624
|
-
process.exit(1);
|
|
625
|
-
}
|
|
626
|
-
const history = await client.getCreditHistory(id);
|
|
627
|
-
if (!history.length) {
|
|
628
|
-
console.log("\n No credit transactions found.\n");
|
|
629
|
-
return;
|
|
630
|
-
}
|
|
631
|
-
console.log(`
|
|
632
|
-
Credit History (${history.length} transactions):
|
|
633
|
-
`);
|
|
634
|
-
printTable(
|
|
635
|
-
history.map((tx) => ({
|
|
636
|
-
Type: tx.type,
|
|
637
|
-
Amount: `${tx.type === "credit" ? "+" : "-"}$${Math.abs(tx.amount).toFixed(2)}`,
|
|
638
|
-
Description: (tx.description || "\u2014").slice(0, 50),
|
|
639
|
-
Status: tx.status,
|
|
640
|
-
Date: new Date(tx.createdAt).toLocaleDateString()
|
|
641
|
-
}))
|
|
642
|
-
);
|
|
643
|
-
console.log();
|
|
644
|
-
}
|
|
645
|
-
async function cmdTemplates() {
|
|
646
|
-
const client = getClient();
|
|
647
|
-
const templates = await client.listTemplates();
|
|
648
|
-
if (!templates.length) {
|
|
649
|
-
console.log("\n No templates available.\n");
|
|
650
|
-
return;
|
|
651
|
-
}
|
|
652
|
-
console.log(`
|
|
653
|
-
Agent Templates (${templates.length}):
|
|
654
|
-
`);
|
|
655
|
-
printTable(
|
|
656
|
-
templates.map((t) => ({
|
|
657
|
-
Slug: t.slug,
|
|
658
|
-
Name: t.name,
|
|
659
|
-
Category: t.category,
|
|
660
|
-
Model: t.model,
|
|
661
|
-
Cost: `$${t.estimatedCost.toFixed(2)}/day`,
|
|
662
|
-
Features: t.features?.length || 0
|
|
663
|
-
}))
|
|
664
|
-
);
|
|
665
|
-
console.log();
|
|
666
|
-
}
|
|
667
|
-
async function cmdTemplatesInfo(slug) {
|
|
668
|
-
if (!slug) {
|
|
669
|
-
console.error(" Usage: otonix templates:info <slug>");
|
|
670
|
-
process.exit(1);
|
|
671
|
-
}
|
|
672
|
-
const client = getClient();
|
|
673
|
-
const template = await client.getTemplate(slug);
|
|
674
|
-
console.log(`
|
|
675
|
-
Template: ${template.name}`);
|
|
676
|
-
console.log(` Slug: ${template.slug}`);
|
|
677
|
-
console.log(` Category: ${template.category}`);
|
|
678
|
-
console.log(` Model: ${template.model}`);
|
|
679
|
-
console.log(` Est. Cost: $${template.estimatedCost.toFixed(2)}/day`);
|
|
680
|
-
console.log(` Description: ${template.description}`);
|
|
681
|
-
if (template.features?.length) {
|
|
682
|
-
console.log(` Features:`);
|
|
683
|
-
template.features.forEach((f) => console.log(` - ${f}`));
|
|
684
|
-
}
|
|
685
|
-
console.log();
|
|
686
|
-
}
|
|
687
|
-
async function cmdTemplatesDeploy(args) {
|
|
688
|
-
const client = getClient();
|
|
689
|
-
let slug = "";
|
|
690
|
-
let name = "";
|
|
691
|
-
let vpsIp = "";
|
|
692
|
-
let wallet = "";
|
|
693
|
-
for (let i = 0; i < args.length; i++) {
|
|
694
|
-
if (args[i] === "--template" && args[i + 1]) slug = args[++i];
|
|
695
|
-
else if (args[i] === "--name" && args[i + 1]) name = args[++i];
|
|
696
|
-
else if (args[i] === "--vps" && args[i + 1]) vpsIp = args[++i];
|
|
697
|
-
else if (args[i] === "--wallet" && args[i + 1]) wallet = args[++i];
|
|
698
|
-
}
|
|
699
|
-
if (!slug) slug = await prompt(" Template slug (e.g. trading-bot): ");
|
|
700
|
-
if (!name) name = await prompt(" Agent name: ");
|
|
701
|
-
if (!slug || !name) {
|
|
702
|
-
console.error(" Error: --template and --name are required.");
|
|
703
|
-
process.exit(1);
|
|
704
|
-
}
|
|
705
|
-
try {
|
|
706
|
-
const result = await client.deployTemplate({
|
|
707
|
-
templateSlug: slug,
|
|
708
|
-
name,
|
|
709
|
-
vpsIp: vpsIp || void 0,
|
|
710
|
-
walletAddress: wallet || void 0
|
|
711
|
-
});
|
|
712
|
-
if (result.success) {
|
|
713
|
-
console.log(`
|
|
714
|
-
Agent Deployed:`);
|
|
715
|
-
console.log(` ID: ${result.agent.id}`);
|
|
716
|
-
console.log(` Name: ${result.agent.name}`);
|
|
717
|
-
console.log(` Template: ${result.template.name} (${result.template.category})`);
|
|
718
|
-
console.log(` Model: ${result.agent.model}`);
|
|
719
|
-
console.log(` Tier: ${result.agent.survivalTier}
|
|
720
|
-
`);
|
|
721
|
-
} else {
|
|
722
|
-
console.error(" Deploy failed.");
|
|
723
|
-
}
|
|
724
|
-
} catch (err) {
|
|
725
|
-
console.error(` Error: ${err.message}`);
|
|
726
|
-
process.exit(1);
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
async function cmdX402() {
|
|
730
|
-
const client = getClient();
|
|
731
|
-
const config = await client.getX402Config();
|
|
732
|
-
console.log(`
|
|
733
|
-
x402 Payment Config:`);
|
|
734
|
-
console.log(` Treasury: ${config.treasuryAddress}`);
|
|
735
|
-
console.log(` USDC: ${config.usdcContract}`);
|
|
736
|
-
console.log(` Chain ID: ${config.chainId}`);
|
|
737
|
-
console.log(` Network: ${config.network}`);
|
|
738
|
-
console.log(` Facilitator: ${config.facilitatorUrl}
|
|
739
|
-
`);
|
|
740
|
-
}
|
|
741
|
-
function getBankrClient() {
|
|
742
|
-
const config = loadConfig();
|
|
743
|
-
if (!config?.bankrApiKey) {
|
|
744
|
-
console.error(" Error: Bankr LLM key not configured. Run 'otonix llm:init <key>' first.");
|
|
745
|
-
process.exit(1);
|
|
746
|
-
}
|
|
747
|
-
return new import_sdk.BankrLLM({ apiKey: config.bankrApiKey });
|
|
748
|
-
}
|
|
749
|
-
function cmdLlmInit(key) {
|
|
750
|
-
if (!key) {
|
|
751
|
-
console.error(" Usage: otonix llm:init <bankr_api_key>");
|
|
752
|
-
process.exit(1);
|
|
753
|
-
}
|
|
754
|
-
if (!key.startsWith("bk_")) {
|
|
755
|
-
console.error(" Error: Bankr API key must start with 'bk_'");
|
|
756
|
-
process.exit(1);
|
|
757
|
-
}
|
|
758
|
-
const config = loadConfig();
|
|
759
|
-
if (!config) {
|
|
760
|
-
console.error(" Error: Run 'otonix init' first to configure Otonix.");
|
|
761
|
-
process.exit(1);
|
|
762
|
-
}
|
|
763
|
-
config.bankrApiKey = key;
|
|
764
|
-
saveConfig(config);
|
|
765
|
-
console.log(`
|
|
766
|
-
Bankr LLM Gateway key saved.`);
|
|
767
|
-
console.log(` Gateway: https://llm.bankr.bot`);
|
|
768
|
-
console.log(` Key: ${key.slice(0, 6)}...${key.slice(-4)}
|
|
769
|
-
`);
|
|
770
|
-
}
|
|
771
|
-
async function cmdLlmModels() {
|
|
772
|
-
const llm = getBankrClient();
|
|
773
|
-
const models = await llm.listModels();
|
|
774
|
-
if (!models.length) {
|
|
775
|
-
console.log("\n No models available.\n");
|
|
776
|
-
return;
|
|
777
|
-
}
|
|
778
|
-
console.log(`
|
|
779
|
-
Available Models \u2014 ${models.length} total
|
|
780
|
-
`);
|
|
781
|
-
printTable(
|
|
782
|
-
models.map((m) => ({
|
|
783
|
-
Model: m.id,
|
|
784
|
-
Provider: m.owned_by
|
|
785
|
-
}))
|
|
786
|
-
);
|
|
787
|
-
console.log();
|
|
788
|
-
}
|
|
789
|
-
async function cmdLlmChat(args) {
|
|
790
|
-
const llm = getBankrClient();
|
|
791
|
-
let model = "claude-haiku-4.5";
|
|
792
|
-
const modelIdx = args.indexOf("--model");
|
|
793
|
-
if (modelIdx !== -1 && args[modelIdx + 1]) {
|
|
794
|
-
model = args[modelIdx + 1];
|
|
795
|
-
args.splice(modelIdx, 2);
|
|
796
|
-
}
|
|
797
|
-
const promptText = args.join(" ");
|
|
798
|
-
if (!promptText) {
|
|
799
|
-
console.error(" Usage: otonix llm:chat <prompt> [--model <model>]");
|
|
800
|
-
process.exit(1);
|
|
801
|
-
}
|
|
802
|
-
console.log(`
|
|
803
|
-
Model: ${model}`);
|
|
804
|
-
console.log(` Prompt: ${promptText}
|
|
805
|
-
`);
|
|
806
|
-
console.log(" Thinking...\n");
|
|
807
|
-
const result = await llm.chat({
|
|
808
|
-
model,
|
|
809
|
-
messages: [{ role: "user", content: promptText }]
|
|
810
|
-
});
|
|
811
|
-
const content = result.choices?.[0]?.message?.content || "No response";
|
|
812
|
-
console.log(` ${content.split("\n").join("\n ")}`);
|
|
813
|
-
console.log(`
|
|
814
|
-
Tokens: ${result.usage?.prompt_tokens || 0} in / ${result.usage?.completion_tokens || 0} out`);
|
|
815
|
-
console.log(` Model: ${result.model}
|
|
816
|
-
`);
|
|
817
|
-
}
|
|
818
|
-
async function cmdLlmUsage(args) {
|
|
819
|
-
const llm = getBankrClient();
|
|
820
|
-
let days = 30;
|
|
821
|
-
const daysIdx = args.indexOf("--days");
|
|
822
|
-
if (daysIdx !== -1 && args[daysIdx + 1]) {
|
|
823
|
-
days = parseInt(args[daysIdx + 1]) || 30;
|
|
824
|
-
}
|
|
825
|
-
const usage = await llm.getUsage(days);
|
|
826
|
-
console.log(`
|
|
827
|
-
LLM Usage (${days} days)
|
|
828
|
-
`);
|
|
829
|
-
console.log(` Total Requests: ${usage.totals.totalRequests}`);
|
|
830
|
-
console.log(` Input Tokens: ${usage.totals.totalInputTokens.toLocaleString()}`);
|
|
831
|
-
console.log(` Output Tokens: ${usage.totals.totalOutputTokens.toLocaleString()}`);
|
|
832
|
-
console.log(` Total Cost: $${usage.totals.totalCost.toFixed(2)}`);
|
|
833
|
-
if (usage.byModel?.length) {
|
|
834
|
-
console.log(`
|
|
835
|
-
By Model:`);
|
|
836
|
-
printTable(
|
|
837
|
-
usage.byModel.map((m) => ({
|
|
838
|
-
Model: m.model,
|
|
839
|
-
Provider: m.provider,
|
|
840
|
-
Requests: m.requests,
|
|
841
|
-
Cost: `$${m.totalCost.toFixed(2)}`
|
|
842
|
-
}))
|
|
843
|
-
);
|
|
844
|
-
}
|
|
845
|
-
console.log();
|
|
846
|
-
}
|
|
847
|
-
async function cmdLlmHealth() {
|
|
848
|
-
const llm = getBankrClient();
|
|
849
|
-
const health = await llm.checkHealth();
|
|
850
|
-
console.log(`
|
|
851
|
-
LLM Gateway Health:`);
|
|
852
|
-
console.log(` Status: ${health.status}`);
|
|
853
|
-
if (health.providers) {
|
|
854
|
-
for (const [name, ok] of Object.entries(health.providers)) {
|
|
855
|
-
console.log(` ${name}: ${ok ? "online" : "offline"}`);
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
|
-
console.log();
|
|
859
|
-
}
|
|
860
|
-
async function cmdBv7xPromote(agentId) {
|
|
861
|
-
if (!agentId) {
|
|
862
|
-
console.error(" Usage: otonix bv7x:promote <agentId>");
|
|
863
|
-
process.exit(1);
|
|
864
|
-
}
|
|
865
|
-
const client = getClient();
|
|
866
|
-
const result = await client.promoteMothership(agentId);
|
|
867
|
-
console.log(`
|
|
868
|
-
Agent promoted to mothership:`);
|
|
869
|
-
console.log(` ID: ${result.agent.id}`);
|
|
870
|
-
console.log(` Name: ${result.agent.name}`);
|
|
871
|
-
console.log(` Role: ${result.agent.role}
|
|
872
|
-
`);
|
|
873
|
-
}
|
|
874
|
-
async function cmdBv7xSpawn(args) {
|
|
875
|
-
const client = getClient();
|
|
876
|
-
let mothershipId = "";
|
|
877
|
-
let templateSlug = "";
|
|
878
|
-
let name = "";
|
|
879
|
-
let vpsIp = "";
|
|
880
|
-
let wallet = "";
|
|
881
|
-
for (let i = 0; i < args.length; i++) {
|
|
882
|
-
if (args[i] === "--mothership" && args[i + 1]) mothershipId = args[++i];
|
|
883
|
-
else if (args[i] === "--template" && args[i + 1]) templateSlug = args[++i];
|
|
884
|
-
else if (args[i] === "--name" && args[i + 1]) name = args[++i];
|
|
885
|
-
else if (args[i] === "--vps" && args[i + 1]) vpsIp = args[++i];
|
|
886
|
-
else if (args[i] === "--wallet" && args[i + 1]) wallet = args[++i];
|
|
887
|
-
}
|
|
888
|
-
if (!mothershipId) mothershipId = await prompt(" Mothership Agent ID: ");
|
|
889
|
-
if (!templateSlug) templateSlug = await prompt(" Template slug (e.g. bv7x-alpha-trader): ");
|
|
890
|
-
if (!name) name = await prompt(" Satellite name: ");
|
|
891
|
-
if (!mothershipId || !templateSlug || !name) {
|
|
892
|
-
console.error(" Error: --mothership, --template, and --name are required.");
|
|
893
|
-
process.exit(1);
|
|
894
|
-
}
|
|
895
|
-
const result = await client.spawnSatellite({
|
|
896
|
-
mothershipId,
|
|
897
|
-
templateSlug,
|
|
898
|
-
name,
|
|
899
|
-
vpsIp: vpsIp || void 0,
|
|
900
|
-
walletAddress: wallet || void 0
|
|
901
|
-
});
|
|
902
|
-
console.log(`
|
|
903
|
-
Satellite Spawned:`);
|
|
904
|
-
console.log(` ID: ${result.satellite.id}`);
|
|
905
|
-
console.log(` Name: ${result.satellite.name}`);
|
|
906
|
-
console.log(` Model: ${result.satellite.model}`);
|
|
907
|
-
console.log(` Role: ${result.satellite.role}`);
|
|
908
|
-
console.log(` Template: ${result.template.name}`);
|
|
909
|
-
console.log(` Mothership: ${result.mothership.name} (${result.mothership.childrenCount} satellites)
|
|
910
|
-
`);
|
|
911
|
-
}
|
|
912
|
-
async function cmdBv7xSatellites(mothershipId) {
|
|
913
|
-
if (!mothershipId) {
|
|
914
|
-
console.error(" Usage: otonix bv7x:satellites <mothershipId>");
|
|
915
|
-
process.exit(1);
|
|
916
|
-
}
|
|
917
|
-
const client = getClient();
|
|
918
|
-
const result = await client.getMothershipSatellites(mothershipId);
|
|
919
|
-
console.log(`
|
|
920
|
-
Mothership: ${result.mothership.name} (${result.count} satellites)
|
|
921
|
-
`);
|
|
922
|
-
if (!result.satellites.length) {
|
|
923
|
-
console.log(" No satellites spawned yet.\n");
|
|
924
|
-
return;
|
|
925
|
-
}
|
|
926
|
-
printTable(result.satellites.map((s) => ({
|
|
927
|
-
ID: s.id.slice(0, 8),
|
|
928
|
-
Name: s.name,
|
|
929
|
-
Status: s.status,
|
|
930
|
-
Tier: s.survivalTier,
|
|
931
|
-
Model: s.model,
|
|
932
|
-
Heartbeat: formatTime(s.lastHeartbeat),
|
|
933
|
-
Actions: s.totalActions
|
|
934
|
-
})));
|
|
935
|
-
console.log();
|
|
936
|
-
}
|
|
937
|
-
async function cmdBv7xDestroy(satelliteId) {
|
|
938
|
-
if (!satelliteId) {
|
|
939
|
-
console.error(" Usage: otonix bv7x:destroy <satelliteId>");
|
|
940
|
-
process.exit(1);
|
|
941
|
-
}
|
|
942
|
-
const client = getClient();
|
|
943
|
-
const result = await client.destroySatellite(satelliteId);
|
|
944
|
-
console.log(` ${result.message}`);
|
|
945
|
-
}
|
|
946
|
-
async function cmdBv7xReport(args) {
|
|
947
|
-
let satelliteId = "";
|
|
948
|
-
let reportType = "general";
|
|
949
|
-
let dataStr = "";
|
|
950
|
-
for (let i = 0; i < args.length; i++) {
|
|
951
|
-
if (args[i] === "--type" && args[i + 1]) reportType = args[++i];
|
|
952
|
-
else if (args[i] === "--data" && args[i + 1]) dataStr = args[++i];
|
|
953
|
-
else if (!satelliteId) satelliteId = args[i];
|
|
954
|
-
}
|
|
955
|
-
if (!satelliteId) {
|
|
956
|
-
console.error(" Usage: otonix bv7x:report <satelliteId> --type <type> --data '<json>'");
|
|
957
|
-
process.exit(1);
|
|
958
|
-
}
|
|
959
|
-
let data = {};
|
|
960
|
-
if (dataStr) {
|
|
961
|
-
try {
|
|
962
|
-
data = JSON.parse(dataStr);
|
|
963
|
-
} catch {
|
|
964
|
-
console.error(" Error: --data must be valid JSON");
|
|
965
|
-
process.exit(1);
|
|
966
|
-
}
|
|
967
|
-
} else {
|
|
968
|
-
const raw = await prompt(" Report data (JSON): ");
|
|
969
|
-
try {
|
|
970
|
-
data = JSON.parse(raw);
|
|
971
|
-
} catch {
|
|
972
|
-
console.error(" Error: Invalid JSON");
|
|
973
|
-
process.exit(1);
|
|
974
|
-
}
|
|
975
|
-
}
|
|
976
|
-
const client = getClient();
|
|
977
|
-
await client.satelliteReport(satelliteId, { data, reportType });
|
|
978
|
-
console.log(` Report sent (type: ${reportType})`);
|
|
979
|
-
}
|
|
980
|
-
async function cmdBv7xFleet() {
|
|
981
|
-
const client = getClient();
|
|
982
|
-
const fleet = await client.getFleet();
|
|
983
|
-
console.log(`
|
|
984
|
-
BV-7X Fleet Overview`);
|
|
985
|
-
console.log(` Motherships: ${fleet.totalMotherships}`);
|
|
986
|
-
console.log(` Satellites: ${fleet.totalSatellites}`);
|
|
987
|
-
if (fleet.fleet.length) {
|
|
988
|
-
for (const f of fleet.fleet) {
|
|
989
|
-
console.log(`
|
|
990
|
-
\u250C Mothership: ${f.mothership.name} [${f.mothership.status}] \u2014 ${f.satelliteCount} satellite(s)`);
|
|
991
|
-
for (const s of f.satellites) {
|
|
992
|
-
console.log(` \u2502 \u2514 ${s.name} [${s.status}] tier:${s.survivalTier} heartbeat:${formatTime(s.lastHeartbeat)}`);
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
if (fleet.orphanedSatellites.length) {
|
|
997
|
-
console.log(`
|
|
998
|
-
Orphaned Satellites: ${fleet.orphanedSatellites.length}`);
|
|
999
|
-
for (const s of fleet.orphanedSatellites) {
|
|
1000
|
-
console.log(` \u2022 ${s.name} [${s.status}]`);
|
|
1001
|
-
}
|
|
1002
|
-
}
|
|
1003
|
-
console.log();
|
|
1004
|
-
}
|
|
1005
|
-
async function cmdWebhookCreate(args) {
|
|
1006
|
-
const client = getClient();
|
|
1007
|
-
let url = "";
|
|
1008
|
-
let agentId = "";
|
|
1009
|
-
const events = [];
|
|
1010
|
-
for (let i = 0; i < args.length; i++) {
|
|
1011
|
-
if (args[i] === "--url" && args[i + 1]) url = args[++i];
|
|
1012
|
-
else if (args[i] === "--agent" && args[i + 1]) agentId = args[++i];
|
|
1013
|
-
else if (args[i] === "--event" && args[i + 1]) events.push(args[++i]);
|
|
1014
|
-
}
|
|
1015
|
-
if (!url) url = await prompt(" Webhook URL: ");
|
|
1016
|
-
if (!url) {
|
|
1017
|
-
console.error(" Error: URL is required.");
|
|
1018
|
-
process.exit(1);
|
|
1019
|
-
}
|
|
1020
|
-
const result = await client.createWebhook({
|
|
1021
|
-
url,
|
|
1022
|
-
events: events.length ? events : void 0,
|
|
1023
|
-
agentId: agentId || void 0
|
|
1024
|
-
});
|
|
1025
|
-
console.log(`
|
|
1026
|
-
Webhook Created:`);
|
|
1027
|
-
console.log(` ID: ${result.id}`);
|
|
1028
|
-
console.log(` URL: ${result.url}`);
|
|
1029
|
-
console.log(` Events: ${result.events.length ? result.events.join(", ") : "all"}`);
|
|
1030
|
-
console.log(` Secret: ${result.secret}`);
|
|
1031
|
-
console.log(`
|
|
1032
|
-
Save this secret \u2014 it won't be shown again.
|
|
1033
|
-
`);
|
|
1034
|
-
}
|
|
1035
|
-
async function cmdWebhookList() {
|
|
1036
|
-
const client = getClient();
|
|
1037
|
-
const hooks = await client.listWebhooks();
|
|
1038
|
-
if (!hooks.length) {
|
|
1039
|
-
console.log("\n No webhooks registered.\n");
|
|
1040
|
-
return;
|
|
1041
|
-
}
|
|
1042
|
-
console.log(`
|
|
1043
|
-
Webhooks (${hooks.length}):
|
|
1044
|
-
`);
|
|
1045
|
-
printTable(hooks.map((h) => ({
|
|
1046
|
-
ID: h.id.slice(0, 8),
|
|
1047
|
-
URL: h.url.length > 40 ? h.url.slice(0, 37) + "..." : h.url,
|
|
1048
|
-
Events: h.events.length ? h.events.length + " types" : "all",
|
|
1049
|
-
Status: h.status,
|
|
1050
|
-
Fails: h.failCount,
|
|
1051
|
-
Agent: h.agentId?.slice(0, 8) || "global"
|
|
1052
|
-
})));
|
|
1053
|
-
console.log();
|
|
1054
|
-
}
|
|
1055
|
-
async function cmdWebhookDelete(webhookId) {
|
|
1056
|
-
if (!webhookId) {
|
|
1057
|
-
console.error(" Usage: otonix webhook:delete <webhookId>");
|
|
1058
|
-
process.exit(1);
|
|
1059
|
-
}
|
|
1060
|
-
const client = getClient();
|
|
1061
|
-
const result = await client.deleteWebhook(webhookId);
|
|
1062
|
-
console.log(` ${result.message}`);
|
|
1063
|
-
}
|
|
1064
|
-
async function cmdWebhookTest(webhookId) {
|
|
1065
|
-
if (!webhookId) {
|
|
1066
|
-
console.error(" Usage: otonix webhook:test <webhookId>");
|
|
1067
|
-
process.exit(1);
|
|
1068
|
-
}
|
|
1069
|
-
const client = getClient();
|
|
1070
|
-
const result = await client.testWebhook(webhookId);
|
|
1071
|
-
console.log(` ${result.message}`);
|
|
1072
|
-
}
|
|
1073
|
-
async function cmdWebhookDeliveries(args) {
|
|
1074
|
-
let webhookId = args[0] || "";
|
|
1075
|
-
if (!webhookId) {
|
|
1076
|
-
console.error(" Usage: otonix webhook:deliveries <webhookId>");
|
|
1077
|
-
process.exit(1);
|
|
1078
|
-
}
|
|
1079
|
-
const client = getClient();
|
|
1080
|
-
const deliveries = await client.getWebhookDeliveries(webhookId);
|
|
1081
|
-
if (!deliveries.length) {
|
|
1082
|
-
console.log("\n No deliveries found.\n");
|
|
1083
|
-
return;
|
|
1084
|
-
}
|
|
1085
|
-
console.log(`
|
|
1086
|
-
Webhook Deliveries (${deliveries.length}):
|
|
1087
|
-
`);
|
|
1088
|
-
printTable(deliveries.slice(0, 20).map((d) => ({
|
|
1089
|
-
Event: d.event,
|
|
1090
|
-
Status: d.statusCode || "\u2014",
|
|
1091
|
-
Success: d.success ? "yes" : "no",
|
|
1092
|
-
Time: formatTime(d.createdAt),
|
|
1093
|
-
Response: (d.response || "\u2014").slice(0, 30)
|
|
1094
|
-
})));
|
|
1095
|
-
console.log();
|
|
1096
|
-
}
|
|
1097
|
-
async function cmdWebhookEvents() {
|
|
1098
|
-
const client = getClient();
|
|
1099
|
-
const result = await client.listWebhookEvents();
|
|
1100
|
-
console.log(`
|
|
1101
|
-
Available Webhook Events (${result.events.length}):
|
|
1102
|
-
`);
|
|
1103
|
-
for (const event of result.events) {
|
|
1104
|
-
console.log(` \u2022 ${event}`);
|
|
1105
|
-
}
|
|
1106
|
-
console.log();
|
|
1107
|
-
}
|
|
1108
|
-
async function cmdTradeList() {
|
|
1109
|
-
const client = getClient();
|
|
1110
|
-
const listings = await client.listServiceListings();
|
|
1111
|
-
if (!listings.length) {
|
|
1112
|
-
console.log("\n No service listings on the marketplace.\n");
|
|
1113
|
-
return;
|
|
1114
|
-
}
|
|
1115
|
-
console.log(`
|
|
1116
|
-
Marketplace Listings (${listings.length}):
|
|
1117
|
-
`);
|
|
1118
|
-
printTable(listings.map((l) => ({
|
|
1119
|
-
ID: l.id.slice(0, 8),
|
|
1120
|
-
Name: l.name,
|
|
1121
|
-
Category: l.category,
|
|
1122
|
-
Price: `${l.priceCredits} credits/${l.priceUnit}`,
|
|
1123
|
-
Rating: `${l.rating.toFixed(1)}/5`,
|
|
1124
|
-
Jobs: l.totalJobs,
|
|
1125
|
-
Seller: l.agentId.slice(0, 8),
|
|
1126
|
-
Status: l.status
|
|
1127
|
-
})));
|
|
1128
|
-
console.log();
|
|
1129
|
-
}
|
|
1130
|
-
async function cmdTradeCreate(args) {
|
|
1131
|
-
const client = getClient();
|
|
1132
|
-
let agentId = "";
|
|
1133
|
-
let name = "";
|
|
1134
|
-
let slug = "";
|
|
1135
|
-
let category = "general";
|
|
1136
|
-
let description = "";
|
|
1137
|
-
let price = 0;
|
|
1138
|
-
let priceUnit = "per request";
|
|
1139
|
-
for (let i = 0; i < args.length; i++) {
|
|
1140
|
-
if (args[i] === "--agent" && args[i + 1]) agentId = args[++i];
|
|
1141
|
-
else if (args[i] === "--name" && args[i + 1]) name = args[++i];
|
|
1142
|
-
else if (args[i] === "--slug" && args[i + 1]) slug = args[++i];
|
|
1143
|
-
else if (args[i] === "--category" && args[i + 1]) category = args[++i];
|
|
1144
|
-
else if (args[i] === "--desc" && args[i + 1]) description = args[++i];
|
|
1145
|
-
else if (args[i] === "--price" && args[i + 1]) price = parseFloat(args[++i]);
|
|
1146
|
-
else if (args[i] === "--unit" && args[i + 1]) priceUnit = args[++i];
|
|
1147
|
-
}
|
|
1148
|
-
if (!agentId) agentId = await prompt(" Seller Agent ID: ");
|
|
1149
|
-
if (!name) name = await prompt(" Service name: ");
|
|
1150
|
-
if (!slug) slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+$/, "");
|
|
1151
|
-
if (!description) description = await prompt(" Description: ");
|
|
1152
|
-
if (!price) {
|
|
1153
|
-
const p = await prompt(" Price (credits): ");
|
|
1154
|
-
price = parseFloat(p);
|
|
1155
|
-
}
|
|
1156
|
-
if (!agentId || !name || !description || !price) {
|
|
1157
|
-
console.error(" Error: agent, name, description, and price are required.");
|
|
1158
|
-
process.exit(1);
|
|
1159
|
-
}
|
|
1160
|
-
try {
|
|
1161
|
-
const listing = await client.createServiceListing({
|
|
1162
|
-
agentId,
|
|
1163
|
-
name,
|
|
1164
|
-
slug,
|
|
1165
|
-
category,
|
|
1166
|
-
description,
|
|
1167
|
-
priceCredits: price,
|
|
1168
|
-
priceUnit
|
|
1169
|
-
});
|
|
1170
|
-
console.log(`
|
|
1171
|
-
Service Listed:`);
|
|
1172
|
-
console.log(` ID: ${listing.id}`);
|
|
1173
|
-
console.log(` Name: ${listing.name}`);
|
|
1174
|
-
console.log(` Slug: ${listing.slug}`);
|
|
1175
|
-
console.log(` Category: ${listing.category}`);
|
|
1176
|
-
console.log(` Price: ${listing.priceCredits} credits/${listing.priceUnit}`);
|
|
1177
|
-
console.log(` Status: ${listing.status}
|
|
1178
|
-
`);
|
|
1179
|
-
} catch (err) {
|
|
1180
|
-
console.error(` Error: ${err.message}`);
|
|
1181
|
-
process.exit(1);
|
|
1182
|
-
}
|
|
1183
|
-
}
|
|
1184
|
-
async function cmdTradeBuy(args) {
|
|
1185
|
-
const client = getClient();
|
|
1186
|
-
let buyerAgentId = "";
|
|
1187
|
-
let listingId = "";
|
|
1188
|
-
for (let i = 0; i < args.length; i++) {
|
|
1189
|
-
if (args[i] === "--buyer" && args[i + 1]) buyerAgentId = args[++i];
|
|
1190
|
-
else if (args[i] === "--listing" && args[i + 1]) listingId = args[++i];
|
|
1191
|
-
}
|
|
1192
|
-
if (!buyerAgentId) buyerAgentId = await prompt(" Buyer Agent ID: ");
|
|
1193
|
-
if (!listingId) listingId = await prompt(" Service Listing ID: ");
|
|
1194
|
-
if (!buyerAgentId || !listingId) {
|
|
1195
|
-
console.error(" Error: --buyer and --listing are required.");
|
|
1196
|
-
process.exit(1);
|
|
1197
|
-
}
|
|
1198
|
-
try {
|
|
1199
|
-
const result = await client.buyService({ buyerAgentId, serviceListingId: listingId });
|
|
1200
|
-
if (result.success) {
|
|
1201
|
-
console.log(`
|
|
1202
|
-
Purchase Successful:`);
|
|
1203
|
-
console.log(` Service: ${result.service.name}`);
|
|
1204
|
-
console.log(` Price: ${result.service.price} credits`);
|
|
1205
|
-
console.log(` Buyer: ${result.buyer.name} (balance: $${result.buyer.credits.toFixed(2)})`);
|
|
1206
|
-
console.log(` Seller: ${result.seller.name}`);
|
|
1207
|
-
console.log(` Order: ${result.order.id}
|
|
1208
|
-
`);
|
|
1209
|
-
} else {
|
|
1210
|
-
console.error(" Purchase failed.");
|
|
1211
|
-
}
|
|
1212
|
-
} catch (err) {
|
|
1213
|
-
console.error(` Error: ${err.message}`);
|
|
1214
|
-
process.exit(1);
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
|
-
async function cmdTradeOrders(args) {
|
|
1218
|
-
const client = getClient();
|
|
1219
|
-
const config = loadConfig();
|
|
1220
|
-
let agentId = "";
|
|
1221
|
-
for (let i = 0; i < args.length; i++) {
|
|
1222
|
-
if (args[i] === "--agent" && args[i + 1]) agentId = args[++i];
|
|
1223
|
-
}
|
|
1224
|
-
if (!agentId) agentId = config.agentId || "";
|
|
1225
|
-
const orders = await client.listTradingOrders(agentId || void 0);
|
|
1226
|
-
if (!orders.length) {
|
|
1227
|
-
console.log("\n No trading orders found.\n");
|
|
1228
|
-
return;
|
|
1229
|
-
}
|
|
1230
|
-
console.log(`
|
|
1231
|
-
Trading Orders (${orders.length}):
|
|
1232
|
-
`);
|
|
1233
|
-
printTable(orders.map((o) => ({
|
|
1234
|
-
ID: o.id.slice(0, 8),
|
|
1235
|
-
Buyer: o.buyerAgentId.slice(0, 8),
|
|
1236
|
-
Seller: o.sellerAgentId.slice(0, 8),
|
|
1237
|
-
Amount: `${o.amount} credits`,
|
|
1238
|
-
Status: o.status,
|
|
1239
|
-
Date: new Date(o.createdAt).toLocaleDateString()
|
|
1240
|
-
})));
|
|
1241
|
-
console.log();
|
|
1242
|
-
}
|
|
1243
|
-
async function cmdActivity(args) {
|
|
1244
|
-
const client = getClient();
|
|
1245
|
-
let limit = 20;
|
|
1246
|
-
let agentId = "";
|
|
1247
|
-
for (let i = 0; i < args.length; i++) {
|
|
1248
|
-
if (args[i] === "--limit" && args[i + 1]) limit = parseInt(args[++i]);
|
|
1249
|
-
else if (args[i] === "--agent" && args[i + 1]) agentId = args[++i];
|
|
1250
|
-
}
|
|
1251
|
-
const events = await client.getActivityFeed(limit, agentId || void 0);
|
|
1252
|
-
if (!events.length) {
|
|
1253
|
-
console.log("\n No activity events found.\n");
|
|
1254
|
-
return;
|
|
1255
|
-
}
|
|
1256
|
-
console.log(`
|
|
1257
|
-
Activity Feed (${events.length} events):
|
|
1258
|
-
`);
|
|
1259
|
-
for (const event of events) {
|
|
1260
|
-
const time = formatTime(event.createdAt);
|
|
1261
|
-
const agent = event.agentId ? event.agentId.slice(0, 8) : "system";
|
|
1262
|
-
console.log(` ${time.padEnd(10)} [${event.eventType.padEnd(25)}] ${event.title}`);
|
|
1263
|
-
if (event.details) {
|
|
1264
|
-
console.log(`${"".padEnd(13)} ${event.details}`);
|
|
1265
|
-
}
|
|
1266
|
-
}
|
|
1267
|
-
console.log();
|
|
1268
|
-
}
|
|
1269
|
-
function cmdWhoami() {
|
|
1270
|
-
const config = loadConfig();
|
|
1271
|
-
if (!config) {
|
|
1272
|
-
console.log(" Not configured. Run 'otonix init' first.");
|
|
1273
|
-
return;
|
|
1274
|
-
}
|
|
1275
|
-
showBanner();
|
|
1276
|
-
console.log(` ${C.bold}\u{1F511} Current Configuration${C.reset}
|
|
1277
|
-
`);
|
|
1278
|
-
console.log(` ${C.dim}\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510${C.reset}`);
|
|
1279
|
-
console.log(` ${C.dim}\u2502${C.reset} Endpoint ${C.cyan}${config.endpoint}${C.reset}`);
|
|
1280
|
-
console.log(` ${C.dim}\u2502${C.reset} API Key ${C.gray}${config.apiKey.slice(0, 12)}...${config.apiKey.slice(-4)}${C.reset}`);
|
|
1281
|
-
console.log(` ${C.dim}\u2502${C.reset} Agent ID ${config.agentId ? `${C.green}${config.agentId.slice(0, 12)}...${C.reset}` : `${C.yellow}not registered${C.reset}`}`);
|
|
1282
|
-
console.log(` ${C.dim}\u2502${C.reset} Agent ${config.agentName ? `${C.bold}${config.agentName}${C.reset}` : `${C.gray}\u2014${C.reset}`}`);
|
|
1283
|
-
console.log(` ${C.dim}\u2502${C.reset} Bankr LLM ${config.bankrApiKey ? `${C.green}${config.bankrApiKey.slice(0, 6)}...${config.bankrApiKey.slice(-4)}${C.reset}` : `${C.gray}not configured${C.reset}`}`);
|
|
1284
|
-
console.log(` ${C.dim}\u2502${C.reset} Config ${C.gray}${CONFIG_FILE}${C.reset}`);
|
|
1285
|
-
console.log(` ${C.dim}\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518${C.reset}
|
|
1286
|
-
`);
|
|
1287
|
-
}
|
|
1288
|
-
async function main() {
|
|
1289
|
-
const args = process.argv.slice(2);
|
|
1290
|
-
const command = args[0] || "help";
|
|
1291
|
-
const rest = args.slice(1);
|
|
1292
|
-
try {
|
|
1293
|
-
switch (command) {
|
|
1294
|
-
case "init":
|
|
1295
|
-
await cmdInit();
|
|
1296
|
-
break;
|
|
1297
|
-
case "keygen":
|
|
1298
|
-
await cmdKeygen(rest[0]);
|
|
1299
|
-
break;
|
|
1300
|
-
case "register":
|
|
1301
|
-
await cmdRegister(rest);
|
|
1302
|
-
break;
|
|
1303
|
-
case "heartbeat":
|
|
1304
|
-
await cmdHeartbeat();
|
|
1305
|
-
break;
|
|
1306
|
-
case "heartbeat:loop":
|
|
1307
|
-
await cmdHeartbeatLoop();
|
|
1308
|
-
break;
|
|
1309
|
-
case "status":
|
|
1310
|
-
await cmdStatus();
|
|
1311
|
-
break;
|
|
1312
|
-
case "agents":
|
|
1313
|
-
await cmdAgents();
|
|
1314
|
-
break;
|
|
1315
|
-
case "actions":
|
|
1316
|
-
await cmdActions(rest);
|
|
1317
|
-
break;
|
|
1318
|
-
case "log":
|
|
1319
|
-
await cmdLog(rest);
|
|
1320
|
-
break;
|
|
1321
|
-
case "domains":
|
|
1322
|
-
await cmdDomains();
|
|
1323
|
-
break;
|
|
1324
|
-
case "sandboxes":
|
|
1325
|
-
await cmdSandboxes();
|
|
1326
|
-
break;
|
|
1327
|
-
case "engine":
|
|
1328
|
-
await cmdEngine();
|
|
1329
|
-
break;
|
|
1330
|
-
case "credits":
|
|
1331
|
-
await cmdCredits(rest[0]);
|
|
1332
|
-
break;
|
|
1333
|
-
case "credits:transfer":
|
|
1334
|
-
await cmdCreditsTransfer(rest);
|
|
1335
|
-
break;
|
|
1336
|
-
case "credits:history":
|
|
1337
|
-
await cmdCreditsHistory(rest[0]);
|
|
1338
|
-
break;
|
|
1339
|
-
case "templates":
|
|
1340
|
-
await cmdTemplates();
|
|
1341
|
-
break;
|
|
1342
|
-
case "templates:info":
|
|
1343
|
-
await cmdTemplatesInfo(rest[0]);
|
|
1344
|
-
break;
|
|
1345
|
-
case "templates:deploy":
|
|
1346
|
-
await cmdTemplatesDeploy(rest);
|
|
1347
|
-
break;
|
|
1348
|
-
case "marketplace":
|
|
1349
|
-
await cmdMarketplace();
|
|
1350
|
-
break;
|
|
1351
|
-
case "x402":
|
|
1352
|
-
await cmdX402();
|
|
1353
|
-
break;
|
|
1354
|
-
case "bv7x:promote":
|
|
1355
|
-
await cmdBv7xPromote(rest[0]);
|
|
1356
|
-
break;
|
|
1357
|
-
case "bv7x:spawn":
|
|
1358
|
-
await cmdBv7xSpawn(rest);
|
|
1359
|
-
break;
|
|
1360
|
-
case "bv7x:satellites":
|
|
1361
|
-
await cmdBv7xSatellites(rest[0]);
|
|
1362
|
-
break;
|
|
1363
|
-
case "bv7x:destroy":
|
|
1364
|
-
await cmdBv7xDestroy(rest[0]);
|
|
1365
|
-
break;
|
|
1366
|
-
case "bv7x:report":
|
|
1367
|
-
await cmdBv7xReport(rest);
|
|
1368
|
-
break;
|
|
1369
|
-
case "bv7x:fleet":
|
|
1370
|
-
await cmdBv7xFleet();
|
|
1371
|
-
break;
|
|
1372
|
-
case "webhook:create":
|
|
1373
|
-
await cmdWebhookCreate(rest);
|
|
1374
|
-
break;
|
|
1375
|
-
case "webhook:list":
|
|
1376
|
-
await cmdWebhookList();
|
|
1377
|
-
break;
|
|
1378
|
-
case "webhook:delete":
|
|
1379
|
-
await cmdWebhookDelete(rest[0]);
|
|
1380
|
-
break;
|
|
1381
|
-
case "webhook:test":
|
|
1382
|
-
await cmdWebhookTest(rest[0]);
|
|
1383
|
-
break;
|
|
1384
|
-
case "webhook:deliveries":
|
|
1385
|
-
await cmdWebhookDeliveries(rest);
|
|
1386
|
-
break;
|
|
1387
|
-
case "webhook:events":
|
|
1388
|
-
await cmdWebhookEvents();
|
|
1389
|
-
break;
|
|
1390
|
-
case "trade:list":
|
|
1391
|
-
await cmdTradeList();
|
|
1392
|
-
break;
|
|
1393
|
-
case "trade:create":
|
|
1394
|
-
await cmdTradeCreate(rest);
|
|
1395
|
-
break;
|
|
1396
|
-
case "trade:buy":
|
|
1397
|
-
await cmdTradeBuy(rest);
|
|
1398
|
-
break;
|
|
1399
|
-
case "trade:orders":
|
|
1400
|
-
await cmdTradeOrders(rest);
|
|
1401
|
-
break;
|
|
1402
|
-
case "activity":
|
|
1403
|
-
await cmdActivity(rest);
|
|
1404
|
-
break;
|
|
1405
|
-
case "llm:init":
|
|
1406
|
-
cmdLlmInit(rest[0]);
|
|
1407
|
-
break;
|
|
1408
|
-
case "llm:models":
|
|
1409
|
-
await cmdLlmModels();
|
|
1410
|
-
break;
|
|
1411
|
-
case "llm:chat":
|
|
1412
|
-
await cmdLlmChat(rest);
|
|
1413
|
-
break;
|
|
1414
|
-
case "llm:usage":
|
|
1415
|
-
await cmdLlmUsage(rest);
|
|
1416
|
-
break;
|
|
1417
|
-
case "llm:health":
|
|
1418
|
-
await cmdLlmHealth();
|
|
1419
|
-
break;
|
|
1420
|
-
case "whoami":
|
|
1421
|
-
cmdWhoami();
|
|
1422
|
-
break;
|
|
1423
|
-
case "version":
|
|
1424
|
-
case "-v":
|
|
1425
|
-
case "--version":
|
|
1426
|
-
showBanner();
|
|
1427
|
-
console.log(` ${C.green}${C.bold}v${VERSION}${C.reset} ${C.dim}@otonix/cli${C.reset}`);
|
|
1428
|
-
console.log();
|
|
1429
|
-
break;
|
|
1430
|
-
case "help":
|
|
1431
|
-
case "-h":
|
|
1432
|
-
case "--help":
|
|
1433
|
-
showDashboard();
|
|
1434
|
-
break;
|
|
1435
|
-
default:
|
|
1436
|
-
console.error(`
|
|
1437
|
-
${C.yellow}Unknown command: ${command}${C.reset}
|
|
1438
|
-
`);
|
|
1439
|
-
showDashboard();
|
|
1440
|
-
process.exit(1);
|
|
1441
|
-
}
|
|
1442
|
-
} catch (err) {
|
|
1443
|
-
if (err instanceof import_sdk.OtonixError) {
|
|
1444
|
-
console.error(` API Error (${err.status}): ${err.message}`);
|
|
1445
|
-
} else {
|
|
1446
|
-
console.error(` Error: ${err.message}`);
|
|
1447
|
-
}
|
|
1448
|
-
process.exit(1);
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
main();
|