clawmoney 0.10.2 → 0.10.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.
@@ -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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawmoney",
3
- "version": "0.10.2",
3
+ "version": "0.10.3",
4
4
  "description": "ClawMoney CLI -- Earn rewards with your AI agent",
5
5
  "type": "module",
6
6
  "bin": {