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.
- package/dist/commands/hub.js +16 -16
- package/dist/hub/executor.js +39 -2
- package/dist/hub/provider.js +3 -3
- package/dist/index.js +20 -20
- package/package.json +1 -1
package/dist/commands/hub.js
CHANGED
|
@@ -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(`
|
|
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
|
|
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(`
|
|
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
|
|
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
|
|
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("
|
|
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(`
|
|
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(`
|
|
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("
|
|
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(`
|
|
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(`
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 {
|
package/dist/hub/executor.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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/dist/hub/provider.js
CHANGED
|
@@ -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(`
|
|
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("
|
|
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("
|
|
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
|
-
//
|
|
146
|
-
const
|
|
147
|
-
.command('
|
|
148
|
-
.description('Agent
|
|
149
|
-
|
|
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
|
|
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
|
-
|
|
163
|
+
market
|
|
164
164
|
.command('stop')
|
|
165
|
-
.description('Stop
|
|
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
|
-
|
|
175
|
+
market
|
|
176
176
|
.command('status')
|
|
177
|
-
.description('Check
|
|
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
|
-
|
|
187
|
+
market
|
|
188
188
|
.command('register')
|
|
189
|
-
.description('Register a skill on the
|
|
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
|
-
|
|
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
|
-
|
|
215
|
+
market
|
|
216
216
|
.command('order <orderId>')
|
|
217
|
-
.description('Check the status of a
|
|
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
|
-
|
|
227
|
+
market
|
|
228
228
|
.command('history')
|
|
229
|
-
.description('View
|
|
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
|
-
|
|
241
|
+
market
|
|
242
242
|
.command('search')
|
|
243
|
-
.description('Search for agent services on the
|
|
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
|
-
|
|
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')
|