clawmoney 0.10.2 → 0.10.4

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.
@@ -14,10 +14,10 @@ export async function hubStartCommand(options) {
14
14
  // Check if already running
15
15
  const existingPid = readPid();
16
16
  if (existingPid && isPidAlive(existingPid)) {
17
- console.log(chalk.yellow(`Hub Provider is already running (PID ${existingPid}). Use "clawmoney hub stop" first.`));
17
+ console.log(chalk.yellow(`Market Provider is already running (PID ${existingPid}). Use "clawmoney market stop" first.`));
18
18
  return;
19
19
  }
20
- const spinner = ora("Starting Hub Provider...").start();
20
+ const spinner = ora("Starting Market Provider...").start();
21
21
  try {
22
22
  // Resolve daemon script path relative to this file's directory
23
23
  // Works for both compiled (dist/commands/hub.js) and dev (src/commands/hub.ts)
@@ -44,19 +44,19 @@ export async function hubStartCommand(options) {
44
44
  await new Promise((resolve) => setTimeout(resolve, 1000));
45
45
  const pid = readPid();
46
46
  if (pid && isPidAlive(pid)) {
47
- spinner.succeed(chalk.green(`Hub Provider started (PID ${pid})`));
47
+ spinner.succeed(chalk.green(`Market Provider started (PID ${pid})`));
48
48
  console.log(chalk.dim(` Log file: ${LOG_FILE}`));
49
49
  console.log(chalk.dim(` CLI: ${options.cli || config.provider?.cli_command || "openclaw"}`));
50
50
  console.log(chalk.dim(` Auto-accept: ${options.autoAccept || config.provider?.auto_accept ? "on" : "off"}`));
51
51
  console.log(chalk.dim(` API key: ${config.api_key.slice(0, 8)}...`));
52
52
  }
53
53
  else {
54
- spinner.fail(chalk.red("Failed to start Hub Provider. Check logs at: " + LOG_FILE));
54
+ spinner.fail(chalk.red("Failed to start Market Provider. Check logs at: " + LOG_FILE));
55
55
  process.exit(1);
56
56
  }
57
57
  }
58
58
  catch (err) {
59
- spinner.fail(chalk.red("Failed to start Hub Provider"));
59
+ spinner.fail(chalk.red("Failed to start Market Provider"));
60
60
  throw err;
61
61
  }
62
62
  }
@@ -64,17 +64,17 @@ export async function hubStartCommand(options) {
64
64
  export async function hubStopCommand() {
65
65
  const pid = readPid();
66
66
  if (!pid) {
67
- console.log(chalk.dim("Hub Provider is not running (no PID file)."));
67
+ console.log(chalk.dim("Market Provider is not running (no PID file)."));
68
68
  return;
69
69
  }
70
70
  if (!isPidAlive(pid)) {
71
- console.log(chalk.dim(`Hub Provider PID ${pid} is not alive. Cleaning up PID file.`));
71
+ console.log(chalk.dim(`Market Provider PID ${pid} is not alive. Cleaning up PID file.`));
72
72
  removePid();
73
73
  return;
74
74
  }
75
75
  try {
76
76
  process.kill(pid, "SIGTERM");
77
- console.log(chalk.green(`Hub Provider stopped (PID ${pid}).`));
77
+ console.log(chalk.green(`Market Provider stopped (PID ${pid}).`));
78
78
  }
79
79
  catch (err) {
80
80
  console.error(chalk.red(`Failed to stop process ${pid}:`), err.message);
@@ -87,20 +87,20 @@ export async function hubStopCommand() {
87
87
  export async function hubStatusCommand() {
88
88
  const pid = readPid();
89
89
  if (!pid) {
90
- console.log(chalk.dim("Hub Provider is not running."));
90
+ console.log(chalk.dim("Market Provider is not running."));
91
91
  return;
92
92
  }
93
93
  if (isPidAlive(pid)) {
94
- console.log(chalk.green(`Hub Provider is running (PID ${pid}).`));
94
+ console.log(chalk.green(`Market Provider is running (PID ${pid}).`));
95
95
  console.log(chalk.dim(` Log file: ${LOG_FILE}`));
96
96
  }
97
97
  else {
98
- console.log(chalk.yellow(`Hub Provider PID ${pid} is not alive (stale PID file).`));
98
+ console.log(chalk.yellow(`Market Provider PID ${pid} is not alive (stale PID file).`));
99
99
  removePid();
100
100
  }
101
101
  }
102
102
  export async function hubSearchCommand(options) {
103
- const spinner = ora("Searching Hub...").start();
103
+ const spinner = ora("Searching Market...").start();
104
104
  try {
105
105
  const params = new URLSearchParams();
106
106
  if (options.query)
@@ -286,7 +286,7 @@ export async function hubCallCommand(options) {
286
286
  if (result._timeout) {
287
287
  spinner.warn(chalk.yellow("Still processing..."));
288
288
  console.log(` ${chalk.bold("Order:")} ${orderId}`);
289
- console.log(chalk.dim(` Check later: npx clawmoney hub order ${orderId}`));
289
+ console.log(chalk.dim(` Check later: npx clawmoney market order ${orderId}`));
290
290
  }
291
291
  else {
292
292
  spinner.succeed(chalk.green("Call completed (x402 paid)!"));
@@ -324,7 +324,7 @@ export async function hubCallCommand(options) {
324
324
  if (result._timeout) {
325
325
  spinner.warn(chalk.yellow("Still processing..."));
326
326
  console.log(` ${chalk.bold("Order:")} ${orderId}`);
327
- console.log(chalk.dim(` Check later: npx clawmoney hub order ${orderId}`));
327
+ console.log(chalk.dim(` Check later: npx clawmoney market order ${orderId}`));
328
328
  }
329
329
  else {
330
330
  spinner.succeed(chalk.green("Call completed!"));
@@ -392,7 +392,7 @@ export async function hubSkillsCommand() {
392
392
  spinner.succeed(`My Skills (${skills.length})`);
393
393
  console.log("");
394
394
  if (skills.length === 0) {
395
- console.log(chalk.dim(' No skills registered. Use "clawmoney hub register" to add one.'));
395
+ console.log(chalk.dim(' No skills registered. Use "clawmoney market register" to add one.'));
396
396
  return;
397
397
  }
398
398
  // Table header
@@ -417,7 +417,7 @@ export async function hubHistoryCommand(options) {
417
417
  const config = requireConfig();
418
418
  const limit = options.limit ?? 10;
419
419
  const showType = options.type ?? "all";
420
- console.log(chalk.bold("\n Hub Activity History\n"));
420
+ console.log(chalk.bold("\n Market Activity History\n"));
421
421
  // Escrow tasks I submitted to (assigned)
422
422
  if (showType === "all" || showType === "escrow") {
423
423
  try {
@@ -209,7 +209,11 @@ export class Executor {
209
209
  if (task.category?.startsWith("coding/")) {
210
210
  lines.push("", "If the task references a GitHub repo, create a GitHub Issue with your findings using `gh issue create`.", "Include the Issue URL in your JSON output as 'issue_url'.");
211
211
  }
212
- lines.push("", "Return the result as JSON with a 'result' field containing your work.");
212
+ // For image generation tasks, instruct to save files
213
+ if (task.category?.startsWith("generation/image")) {
214
+ lines.push("", "IMPORTANT: Generate a real image file (PNG/JPG). Save it to a local path.", "Include the file path in your JSON output as 'image_path'.", "Do NOT generate SVG, HTML, or code to fake an image.");
215
+ }
216
+ lines.push("", "Return the result as JSON with a 'result' field containing your work.", "If you generate any files (images, videos, etc.), include their absolute file paths in the output.");
213
217
  const prompt = lines.filter(Boolean).join("\n");
214
218
  const command = this.config.provider.cli_command;
215
219
  logger.info(`Executing multi task via ${command} (timeout=300s)`);
@@ -218,10 +222,11 @@ export class Executor {
218
222
  logger.error(`Escrow CLI failed (code=${exitCode}): ${stderr.slice(0, 500)}`);
219
223
  return;
220
224
  }
221
- // Extract text result and optional URL
225
+ // Extract text result, optional URL, and file paths
222
226
  const parsed = parseJsonOutput(stdout);
223
227
  let content;
224
228
  let url = null;
229
+ const localFiles = [];
225
230
  if (command === "openclaw" && parsed) {
226
231
  const ocResult = parseOpenClawResponse(parsed);
227
232
  content = typeof ocResult.result.text === "string"
@@ -231,6 +236,7 @@ export class Executor {
231
236
  : JSON.stringify(ocResult.result, null, 2);
232
237
  // Extract issue_url or pr_url from result
233
238
  url = (ocResult.result.issue_url ?? ocResult.result.pr_url ?? null);
239
+ localFiles.push(...ocResult.files);
234
240
  }
235
241
  else {
236
242
  content = parsed
@@ -238,6 +244,37 @@ export class Executor {
238
244
  : stdout.trim().slice(0, 10000);
239
245
  if (parsed) {
240
246
  url = (parsed.issue_url ?? parsed.pr_url ?? null);
247
+ // Extract file paths from parsed JSON
248
+ for (const key of ["image_path", "video_path", "audio_path", "file_path", "primary_file"]) {
249
+ const val = parsed[key];
250
+ if (typeof val === "string" && val.startsWith("/"))
251
+ localFiles.push(val);
252
+ }
253
+ const files = parsed.files;
254
+ if (Array.isArray(files)) {
255
+ localFiles.push(...files.filter((f) => typeof f === "string" && f.startsWith("/")));
256
+ }
257
+ }
258
+ // Also scan raw stdout for file paths (claude may output paths as plain text)
259
+ const pathMatches = stdout.match(/\/\S+\.(png|jpg|jpeg|webp|gif|mp4|webm|mov|mp3|wav|pdf)/gim);
260
+ if (pathMatches) {
261
+ for (const p of pathMatches) {
262
+ if (!localFiles.includes(p))
263
+ localFiles.push(p);
264
+ }
265
+ }
266
+ }
267
+ // Upload local files to R2 CDN
268
+ for (const filePath of localFiles) {
269
+ const cdnUrl = await uploadFile(filePath, this.config);
270
+ if (cdnUrl) {
271
+ logger.info(`Escrow ${task.id.slice(0, 8)}: uploaded ${filePath} -> ${cdnUrl}`);
272
+ // Use the first uploaded file as the submission URL
273
+ if (!url) {
274
+ url = cdnUrl;
275
+ }
276
+ // Replace local path in content with CDN URL
277
+ content = content.replace(filePath, cdnUrl);
241
278
  }
242
279
  }
243
280
  // Submit to marketplace
@@ -105,7 +105,7 @@ export function runProvider(cliCommand, autoAccept) {
105
105
  // Check for existing process
106
106
  const existingPid = readPid();
107
107
  if (existingPid && isPidAlive(existingPid)) {
108
- logger.error(`Hub Provider is already running (PID ${existingPid}). Use "hub stop" first.`);
108
+ logger.error(`Market Provider is already running (PID ${existingPid}). Use "market stop" first.`);
109
109
  process.exit(1);
110
110
  }
111
111
  const config = loadProviderConfig(cliCommand, autoAccept);
@@ -153,7 +153,7 @@ export function runProvider(cliCommand, autoAccept) {
153
153
  poller.stop();
154
154
  stopDedup();
155
155
  removePid();
156
- logger.info("Hub Provider stopped.");
156
+ logger.info("Market Provider stopped.");
157
157
  process.exit(0);
158
158
  }
159
159
  process.on("SIGTERM", () => shutdown("SIGTERM"));
@@ -162,6 +162,6 @@ export function runProvider(cliCommand, autoAccept) {
162
162
  writePid();
163
163
  wsClient.start();
164
164
  poller.start();
165
- logger.info("Hub Provider running. Listening for service calls...");
165
+ logger.info("Market Provider running. Listening for service calls...");
166
166
  logger.info(`Config: cli=${config.provider.cli_command}, max_concurrent=${config.provider.max_concurrent}`);
167
167
  }
package/dist/index.js CHANGED
@@ -142,13 +142,13 @@ program
142
142
  process.exit(1);
143
143
  }
144
144
  });
145
- // hub
146
- const hub = program
147
- .command('hub')
148
- .description('Agent Hub: provide services, register skills');
149
- hub
145
+ // market
146
+ const market = program
147
+ .command('market')
148
+ .description('Agent Market: provide services, register skills');
149
+ market
150
150
  .command('start')
151
- .description('Start Hub Provider (background process)')
151
+ .description('Start Market Provider (background process)')
152
152
  .option('--cli <command>', 'CLI command for task execution (default: from config or openclaw)')
153
153
  .option('--auto-accept', 'Auto-accept escrow tasks from the marketplace')
154
154
  .action(async (options) => {
@@ -160,9 +160,9 @@ hub
160
160
  process.exit(1);
161
161
  }
162
162
  });
163
- hub
163
+ market
164
164
  .command('stop')
165
- .description('Stop Hub Provider')
165
+ .description('Stop Market Provider')
166
166
  .action(async () => {
167
167
  try {
168
168
  await hubStopCommand();
@@ -172,9 +172,9 @@ hub
172
172
  process.exit(1);
173
173
  }
174
174
  });
175
- hub
175
+ market
176
176
  .command('status')
177
- .description('Check Hub Provider status')
177
+ .description('Check Market Provider status')
178
178
  .action(async () => {
179
179
  try {
180
180
  await hubStatusCommand();
@@ -184,9 +184,9 @@ hub
184
184
  process.exit(1);
185
185
  }
186
186
  });
187
- hub
187
+ market
188
188
  .command('register')
189
- .description('Register a skill on the Hub')
189
+ .description('Register a skill on the Market')
190
190
  .requiredOption('-n, --name <name>', 'Skill name')
191
191
  .requiredOption('-c, --category <category>', 'Category (e.g., generation/image)')
192
192
  .requiredOption('-d, --description <desc>', 'Description')
@@ -200,7 +200,7 @@ hub
200
200
  process.exit(1);
201
201
  }
202
202
  });
203
- hub
203
+ market
204
204
  .command('skills')
205
205
  .description('List my registered skills')
206
206
  .action(async () => {
@@ -212,9 +212,9 @@ hub
212
212
  process.exit(1);
213
213
  }
214
214
  });
215
- hub
215
+ market
216
216
  .command('order <orderId>')
217
- .description('Check the status of a Hub order')
217
+ .description('Check the status of a Market order')
218
218
  .action(async (orderId) => {
219
219
  try {
220
220
  await hubOrderCommand(orderId);
@@ -224,9 +224,9 @@ hub
224
224
  process.exit(1);
225
225
  }
226
226
  });
227
- hub
227
+ market
228
228
  .command('history')
229
- .description('View Hub activity: escrow tasks, orders, and provider log')
229
+ .description('View Market activity: escrow tasks, orders, and provider log')
230
230
  .option('-t, --type <type>', 'Filter: all, escrow, orders, log', 'all')
231
231
  .option('-l, --limit <n>', 'Number of items to show', '10')
232
232
  .action(async (options) => {
@@ -238,9 +238,9 @@ hub
238
238
  process.exit(1);
239
239
  }
240
240
  });
241
- hub
241
+ market
242
242
  .command('search')
243
- .description('Search for agent services on the Hub')
243
+ .description('Search for agent services on the Market')
244
244
  .option('-q, --query <query>', 'Keyword search')
245
245
  .option('-c, --category <category>', 'Category filter (e.g., generation/image)')
246
246
  .option('-s, --sort <sort>', 'Sort by: rating, price, response_time', 'rating')
@@ -255,7 +255,7 @@ hub
255
255
  process.exit(1);
256
256
  }
257
257
  });
258
- hub
258
+ market
259
259
  .command('call')
260
260
  .description('Call another agent\'s service')
261
261
  .requiredOption('-a, --agent <agent>', 'Target agent slug or ID')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawmoney",
3
- "version": "0.10.2",
3
+ "version": "0.10.4",
4
4
  "description": "ClawMoney CLI -- Earn rewards with your AI agent",
5
5
  "type": "module",
6
6
  "bin": {