clawmoney 0.8.2 → 0.8.3

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.
@@ -3,6 +3,21 @@ export declare function hubStartCommand(options: {
3
3
  }): Promise<void>;
4
4
  export declare function hubStopCommand(): Promise<void>;
5
5
  export declare function hubStatusCommand(): Promise<void>;
6
+ interface SearchOptions {
7
+ query?: string;
8
+ category?: string;
9
+ sort?: string;
10
+ limit?: string;
11
+ maxPrice?: string;
12
+ }
13
+ export declare function hubSearchCommand(options: SearchOptions): Promise<void>;
14
+ interface CallOptions {
15
+ agent: string;
16
+ skill: string;
17
+ input?: string;
18
+ timeout?: string;
19
+ }
20
+ export declare function hubCallCommand(options: CallOptions): Promise<void>;
6
21
  interface RegisterOptions {
7
22
  name: string;
8
23
  category: string;
@@ -94,6 +94,91 @@ export async function hubStatusCommand() {
94
94
  removePid();
95
95
  }
96
96
  }
97
+ export async function hubSearchCommand(options) {
98
+ const spinner = ora("Searching Hub...").start();
99
+ try {
100
+ const params = new URLSearchParams();
101
+ if (options.query)
102
+ params.set("q", options.query);
103
+ if (options.category)
104
+ params.set("category", options.category);
105
+ if (options.sort)
106
+ params.set("sort", options.sort);
107
+ if (options.limit)
108
+ params.set("limit", options.limit);
109
+ if (options.maxPrice)
110
+ params.set("max_price", options.maxPrice);
111
+ params.set("online_only", "true");
112
+ const resp = await apiGet(`/api/v1/hub/skills/search?${params}`);
113
+ if (!resp.ok) {
114
+ spinner.fail(chalk.red(`Search failed (${resp.status})`));
115
+ process.exit(1);
116
+ }
117
+ const skills = resp.data.data ?? [];
118
+ const count = resp.data.count ?? skills.length;
119
+ spinner.succeed(`Found ${count} service(s)`);
120
+ console.log("");
121
+ if (skills.length === 0) {
122
+ console.log(chalk.dim(" No services found. Try broader search terms."));
123
+ return;
124
+ }
125
+ console.log(chalk.bold(` ${"Agent".padEnd(18)} ${"Skill".padEnd(18)} ${"Category".padEnd(18)} ${"Price".padEnd(8)} ${"Rating".padEnd(8)} ${"Calls".padEnd(7)}`));
126
+ console.log(chalk.dim(" " + "-".repeat(79)));
127
+ for (const s of skills) {
128
+ const agent = (s.agent_name ?? s.agent_slug ?? "-").slice(0, 17);
129
+ const name = (s.skill_name ?? "-").slice(0, 17);
130
+ const category = (s.category ?? "-").slice(0, 17);
131
+ const price = s.price !== undefined ? `$${s.price.toFixed(3)}` : "-";
132
+ const rating = s.avg_rating != null ? s.avg_rating.toFixed(1) : "-";
133
+ const calls = String(s.total_calls ?? 0);
134
+ const online = s.agent_is_online ? chalk.green("●") : chalk.dim("○");
135
+ console.log(` ${online} ${chalk.cyan(agent.padEnd(17))} ${name.padEnd(18)} ${category.padEnd(18)} ${chalk.green(price.padEnd(8))} ${rating.padEnd(8)} ${calls.padEnd(7)}`);
136
+ }
137
+ }
138
+ catch (err) {
139
+ spinner.fail(chalk.red("Search failed"));
140
+ throw err;
141
+ }
142
+ }
143
+ export async function hubCallCommand(options) {
144
+ const config = requireConfig();
145
+ let inputData = {};
146
+ if (options.input) {
147
+ try {
148
+ inputData = JSON.parse(options.input);
149
+ }
150
+ catch {
151
+ console.error(chalk.red("Invalid JSON for --input. Example: '{\"prompt\":\"hello\"}'"));
152
+ process.exit(1);
153
+ }
154
+ }
155
+ const timeout = options.timeout ? parseInt(options.timeout, 10) : 60;
156
+ const spinner = ora(`Calling ${options.agent}/${options.skill}...`).start();
157
+ try {
158
+ const resp = await apiPost(`/api/v1/hub/gateway/invoke?agent_id=${encodeURIComponent(options.agent)}&skill=${encodeURIComponent(options.skill)}&timeout=${timeout}&payment_method=ledger`, inputData, config.api_key);
159
+ if (!resp.ok) {
160
+ const raw = resp.data && typeof resp.data === "object" && "detail" in resp.data
161
+ ? resp.data.detail
162
+ : resp.data;
163
+ const detail = typeof raw === "string" ? raw : JSON.stringify(raw);
164
+ spinner.fail(chalk.red(`Call failed (${resp.status}): ${detail}`));
165
+ process.exit(1);
166
+ }
167
+ const result = resp.data;
168
+ spinner.succeed(chalk.green("Call completed!"));
169
+ console.log("");
170
+ console.log(` ${chalk.bold("Order:")} ${result.id ?? "-"}`);
171
+ console.log(` ${chalk.bold("Duration:")} ${typeof result.duration === "number" ? result.duration.toFixed(1) + "s" : "-"}`);
172
+ console.log(` ${chalk.bold("Cost:")} $${typeof result.price === "number" ? result.price.toFixed(3) : "-"}`);
173
+ console.log("");
174
+ console.log(chalk.bold(" Output:"));
175
+ console.log(chalk.cyan(" " + JSON.stringify(result.output_data ?? result.output ?? {}, null, 2).replace(/\n/g, "\n ")));
176
+ }
177
+ catch (err) {
178
+ spinner.fail(chalk.red("Call failed"));
179
+ throw err;
180
+ }
181
+ }
97
182
  export async function hubRegisterCommand(options) {
98
183
  const config = requireConfig();
99
184
  const price = parseFloat(options.price);
package/dist/index.js CHANGED
@@ -5,12 +5,12 @@ import { browseCommand } from './commands/browse.js';
5
5
  import { promoteSubmitCommand, promoteVerifyCommand } from './commands/promote.js';
6
6
  import { walletStatusCommand, walletBalanceCommand, walletAddressCommand, walletSendCommand, } from './commands/wallet.js';
7
7
  import { tweetCommand } from './commands/tweet.js';
8
- import { hubStartCommand, hubStopCommand, hubStatusCommand, hubRegisterCommand, hubSkillsCommand, } from './commands/hub.js';
8
+ import { hubStartCommand, hubStopCommand, hubStatusCommand, hubSearchCommand, hubCallCommand, hubRegisterCommand, hubSkillsCommand, } from './commands/hub.js';
9
9
  const program = new Command();
10
10
  program
11
11
  .name('clawmoney')
12
12
  .description('ClawMoney CLI -- Earn rewards with your AI agent')
13
- .version('0.1.0');
13
+ .version('0.8.2');
14
14
  // setup
15
15
  program
16
16
  .command('setup')
@@ -207,4 +207,37 @@ hub
207
207
  process.exit(1);
208
208
  }
209
209
  });
210
+ hub
211
+ .command('search')
212
+ .description('Search for agent services on the Hub')
213
+ .option('-q, --query <query>', 'Keyword search')
214
+ .option('-c, --category <category>', 'Category filter (e.g., generation/image)')
215
+ .option('-s, --sort <sort>', 'Sort by: rating, price, response_time', 'rating')
216
+ .option('-l, --limit <limit>', 'Number of results', '10')
217
+ .option('--max-price <price>', 'Maximum price filter')
218
+ .action(async (options) => {
219
+ try {
220
+ await hubSearchCommand(options);
221
+ }
222
+ catch (err) {
223
+ console.error(err.message);
224
+ process.exit(1);
225
+ }
226
+ });
227
+ hub
228
+ .command('call')
229
+ .description('Call another agent\'s service')
230
+ .requiredOption('-a, --agent <agent>', 'Target agent slug or ID')
231
+ .requiredOption('-s, --skill <skill>', 'Skill name to invoke')
232
+ .option('-i, --input <json>', 'Input parameters as JSON')
233
+ .option('-t, --timeout <seconds>', 'Timeout in seconds', '60')
234
+ .action(async (options) => {
235
+ try {
236
+ await hubCallCommand(options);
237
+ }
238
+ catch (err) {
239
+ console.error(err.message);
240
+ process.exit(1);
241
+ }
242
+ });
210
243
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawmoney",
3
- "version": "0.8.2",
3
+ "version": "0.8.3",
4
4
  "description": "ClawMoney CLI -- Earn rewards with your AI agent",
5
5
  "type": "module",
6
6
  "bin": {