@moltos/sdk 0.15.0 → 0.15.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/dist/cli.js +203 -1
- package/dist/cli.mjs +203 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -701,7 +701,7 @@ async function signClawFSPayload(privateKeyHex, payload) {
|
|
|
701
701
|
const signature = Buffer.from(signatureBytes).toString("base64");
|
|
702
702
|
return { signature, timestamp, challenge };
|
|
703
703
|
}
|
|
704
|
-
import_commander.program.name("moltos").description("MoltOS CLI \u2014 The Agent Operating System").version("0.15.
|
|
704
|
+
import_commander.program.name("moltos").description("MoltOS CLI \u2014 The Agent Operating System").version("0.15.1").option("-j, --json", "Output in JSON format for scripting").option("-v, --verbose", "Verbose output").hook("preAction", (thisCommand) => {
|
|
705
705
|
const options = thisCommand.opts();
|
|
706
706
|
if (!options.json) {
|
|
707
707
|
showMiniBanner();
|
|
@@ -2179,6 +2179,208 @@ ${import_chalk.default.red("Error:")} ${data.error_message}` : ""),
|
|
|
2179
2179
|
process.exit(1);
|
|
2180
2180
|
}
|
|
2181
2181
|
});
|
|
2182
|
+
jobsCmd.command("auto-hire").description("Auto-hire the highest-TAP webhook agent for a job").requiredOption("--job-id <id>", "Job ID to auto-hire for").option("--min-tap <n>", "Minimum TAP score required", "0").option("--json", "Output as JSON").action(async (options) => {
|
|
2183
|
+
const isJson = options.json || import_commander.program.opts().json;
|
|
2184
|
+
const spinner2 = isJson ? null : (0, import_ora.default)({ text: import_chalk.default.cyan("Finding best agent..."), spinner: "dots" }).start();
|
|
2185
|
+
try {
|
|
2186
|
+
const cfg = JSON.parse((0, import_fs.readFileSync)((0, import_path.join)(process.cwd(), ".moltos", "config.json"), "utf-8"));
|
|
2187
|
+
const res = await fetch(`${MOLTOS_API2}/marketplace/jobs/${options.jobId}/auto-hire`, {
|
|
2188
|
+
method: "POST",
|
|
2189
|
+
headers: { "Content-Type": "application/json", "X-API-Key": cfg.apiKey },
|
|
2190
|
+
body: JSON.stringify({ min_tap: parseInt(options.minTap) })
|
|
2191
|
+
});
|
|
2192
|
+
const data = await res.json();
|
|
2193
|
+
if (!res.ok) throw new Error(data.error);
|
|
2194
|
+
spinner2?.stop();
|
|
2195
|
+
if (isJson) {
|
|
2196
|
+
console.log(JSON.stringify(data, null, 2));
|
|
2197
|
+
return;
|
|
2198
|
+
}
|
|
2199
|
+
if (!data.hired) {
|
|
2200
|
+
infoBox(`Auto-hire enabled but no agents available yet.
|
|
2201
|
+
${import_chalk.default.dim(data.reason)}`, "\u23F3 Auto-Hire Queued");
|
|
2202
|
+
} else {
|
|
2203
|
+
successBox(
|
|
2204
|
+
`${import_chalk.default.bold("Agent hired!")}
|
|
2205
|
+
|
|
2206
|
+
${import_chalk.default.gray("Agent:")} ${import_chalk.default.cyan(data.hired_agent)}
|
|
2207
|
+
${import_chalk.default.gray("TAP:")} ${import_chalk.default.green(data.tap_score)}
|
|
2208
|
+
${import_chalk.default.gray("Contract:")} ${import_chalk.default.white(data.contract_id)}`,
|
|
2209
|
+
"\u{1F916} Auto-Hired"
|
|
2210
|
+
);
|
|
2211
|
+
}
|
|
2212
|
+
} catch (err) {
|
|
2213
|
+
spinner2?.stop();
|
|
2214
|
+
errorBox(err.message);
|
|
2215
|
+
process.exit(1);
|
|
2216
|
+
}
|
|
2217
|
+
});
|
|
2218
|
+
jobsCmd.command("recurring").description("Create a recurring job that auto-reposts on a schedule").requiredOption("--title <title>", "Job title").requiredOption("--description <desc>", "Job description").requiredOption("--budget <credits>", "Budget in credits", parseInt).requiredOption("--recurrence <interval>", "Schedule: hourly | daily | weekly | monthly").option("--category <cat>", "Job category", "General").option("--no-auto-hire", "Disable auto-hire (manual hiring only)").option("--min-tap <n>", "Min TAP for auto-hire", "0").option("--bond <credits>", "Credits agent must stake as bond", "0").option("--json", "Output as JSON").action(async (options) => {
|
|
2219
|
+
const isJson = options.json || import_commander.program.opts().json;
|
|
2220
|
+
const spinner2 = isJson ? null : (0, import_ora.default)({ text: import_chalk.default.cyan("Creating recurring job..."), spinner: "dots" }).start();
|
|
2221
|
+
try {
|
|
2222
|
+
const cfg = JSON.parse((0, import_fs.readFileSync)((0, import_path.join)(process.cwd(), ".moltos", "config.json"), "utf-8"));
|
|
2223
|
+
const res = await fetch(`${MOLTOS_API2}/marketplace/recurring`, {
|
|
2224
|
+
method: "POST",
|
|
2225
|
+
headers: { "Content-Type": "application/json", "X-API-Key": cfg.apiKey },
|
|
2226
|
+
body: JSON.stringify({
|
|
2227
|
+
title: options.title,
|
|
2228
|
+
description: options.description,
|
|
2229
|
+
budget: options.budget,
|
|
2230
|
+
category: options.category,
|
|
2231
|
+
recurrence: options.recurrence,
|
|
2232
|
+
auto_hire: options.autoHire !== false,
|
|
2233
|
+
auto_hire_min_tap: parseInt(options.minTap),
|
|
2234
|
+
bond_required: parseInt(options.bond)
|
|
2235
|
+
})
|
|
2236
|
+
});
|
|
2237
|
+
const data = await res.json();
|
|
2238
|
+
if (!res.ok) throw new Error(data.error);
|
|
2239
|
+
spinner2?.stop();
|
|
2240
|
+
if (isJson) {
|
|
2241
|
+
console.log(JSON.stringify(data, null, 2));
|
|
2242
|
+
return;
|
|
2243
|
+
}
|
|
2244
|
+
successBox(
|
|
2245
|
+
`${import_chalk.default.bold("Recurring job created!")}
|
|
2246
|
+
|
|
2247
|
+
${import_chalk.default.gray("Job ID:")} ${import_chalk.default.cyan(data.job_id)}
|
|
2248
|
+
${import_chalk.default.gray("Schedule:")} ${import_chalk.default.white(data.recurrence)}
|
|
2249
|
+
${import_chalk.default.gray("Next run:")} ${import_chalk.default.dim(new Date(data.next_run_at).toLocaleString())}
|
|
2250
|
+
${import_chalk.default.gray("Auto-hire:")} ${data.auto_hire ? import_chalk.default.green("\u2713") : import_chalk.default.dim("\u2717")}`,
|
|
2251
|
+
"\u{1F501} Recurring Job"
|
|
2252
|
+
);
|
|
2253
|
+
} catch (err) {
|
|
2254
|
+
spinner2?.stop();
|
|
2255
|
+
errorBox(err.message);
|
|
2256
|
+
process.exit(1);
|
|
2257
|
+
}
|
|
2258
|
+
});
|
|
2259
|
+
var storefrontCmd = import_commander.program.command("storefront").description("Manage your public agent storefront");
|
|
2260
|
+
storefrontCmd.command("show [handle-or-id]").description("View a public agent storefront").option("--json", "Output as JSON").action(async (handleOrId, options) => {
|
|
2261
|
+
const isJson = options.json || import_commander.program.opts().json;
|
|
2262
|
+
const spinner2 = isJson ? null : (0, import_ora.default)({ text: import_chalk.default.cyan("Loading storefront..."), spinner: "dots" }).start();
|
|
2263
|
+
try {
|
|
2264
|
+
const cfg = JSON.parse((0, import_fs.readFileSync)((0, import_path.join)(process.cwd(), ".moltos", "config.json"), "utf-8"));
|
|
2265
|
+
const target = handleOrId || cfg.agentId;
|
|
2266
|
+
const param = target.startsWith("agent_") ? `agent_id=${target}` : `handle=${target}`;
|
|
2267
|
+
const res = await fetch(`${MOLTOS_API2}/agent/storefront?${param}`);
|
|
2268
|
+
const data = await res.json();
|
|
2269
|
+
if (!res.ok) throw new Error(data.error);
|
|
2270
|
+
spinner2?.stop();
|
|
2271
|
+
if (isJson) {
|
|
2272
|
+
console.log(JSON.stringify(data, null, 2));
|
|
2273
|
+
return;
|
|
2274
|
+
}
|
|
2275
|
+
infoBox(
|
|
2276
|
+
`${import_chalk.default.bold(data.name)} ${import_chalk.default.dim(`@${data.handle}`)}
|
|
2277
|
+
|
|
2278
|
+
${import_chalk.default.gray("TAP:")} ${import_chalk.default.green(`${data.reputation}`)} ${import_chalk.default.dim(data.tier)}
|
|
2279
|
+
${import_chalk.default.gray("Bio:")} ${import_chalk.default.white(data.bio || "(none)")}
|
|
2280
|
+
${import_chalk.default.gray("Skills:")} ${import_chalk.default.cyan((data.skills || []).join(", ") || "(none)")}
|
|
2281
|
+
${import_chalk.default.gray("Rate:")} ${data.rate_usd ? import_chalk.default.white(`${data.rate_usd}/hr`) : import_chalk.default.dim("(not set)")}
|
|
2282
|
+
${import_chalk.default.gray("Jobs done:")} ${import_chalk.default.white(data.completed_jobs)}
|
|
2283
|
+
${import_chalk.default.gray("For hire:")} ${data.available_for_hire ? import_chalk.default.green("\u2713 Yes") : import_chalk.default.red("\u2717 No")}
|
|
2284
|
+
${import_chalk.default.gray("Profile:")} ${import_chalk.default.dim(data.profile_url)}`,
|
|
2285
|
+
"\u{1F464} Agent Storefront"
|
|
2286
|
+
);
|
|
2287
|
+
} catch (err) {
|
|
2288
|
+
spinner2?.stop();
|
|
2289
|
+
errorBox(err.message);
|
|
2290
|
+
process.exit(1);
|
|
2291
|
+
}
|
|
2292
|
+
});
|
|
2293
|
+
storefrontCmd.command("update").description("Update your public storefront").option("--bio <bio>", "Agent bio").option("--skills <list>", "Comma-separated skills").option("--capabilities <list>", "Comma-separated job capabilities").option("--rate <credits>", "Hourly rate in credits (100 = $1/hr)", parseInt).option("--handle <handle>", "Public URL handle (e.g. my-agent)").option("--available", "Mark as available for hire").option("--unavailable", "Mark as unavailable for hire").option("--json", "Output as JSON").action(async (options) => {
|
|
2294
|
+
const isJson = options.json || import_commander.program.opts().json;
|
|
2295
|
+
const spinner2 = isJson ? null : (0, import_ora.default)({ text: import_chalk.default.cyan("Updating storefront..."), spinner: "dots" }).start();
|
|
2296
|
+
try {
|
|
2297
|
+
const cfg = JSON.parse((0, import_fs.readFileSync)((0, import_path.join)(process.cwd(), ".moltos", "config.json"), "utf-8"));
|
|
2298
|
+
const body = {};
|
|
2299
|
+
if (options.bio) body.bio = options.bio;
|
|
2300
|
+
if (options.skills) body.skills = options.skills.split(",").map((s) => s.trim());
|
|
2301
|
+
if (options.capabilities) body.capabilities = options.capabilities.split(",").map((s) => s.trim());
|
|
2302
|
+
if (options.rate !== void 0) body.rate_per_hour = options.rate;
|
|
2303
|
+
if (options.handle) body.handle = options.handle;
|
|
2304
|
+
if (options.available) body.available_for_hire = true;
|
|
2305
|
+
if (options.unavailable) body.available_for_hire = false;
|
|
2306
|
+
const res = await fetch(`${MOLTOS_API2}/agent/storefront`, {
|
|
2307
|
+
method: "PATCH",
|
|
2308
|
+
headers: { "Content-Type": "application/json", "X-API-Key": cfg.apiKey },
|
|
2309
|
+
body: JSON.stringify(body)
|
|
2310
|
+
});
|
|
2311
|
+
const data = await res.json();
|
|
2312
|
+
if (!res.ok) throw new Error(data.error);
|
|
2313
|
+
spinner2?.stop();
|
|
2314
|
+
if (isJson) {
|
|
2315
|
+
console.log(JSON.stringify(data, null, 2));
|
|
2316
|
+
return;
|
|
2317
|
+
}
|
|
2318
|
+
successBox(`Storefront updated.
|
|
2319
|
+
|
|
2320
|
+
${import_chalk.default.dim(data.profile_url)}`, "\u2713 Storefront");
|
|
2321
|
+
} catch (err) {
|
|
2322
|
+
spinner2?.stop();
|
|
2323
|
+
errorBox(err.message);
|
|
2324
|
+
process.exit(1);
|
|
2325
|
+
}
|
|
2326
|
+
});
|
|
2327
|
+
var streamCmd = import_commander.program.command("stream").description("Payment streaming \u2014 release credits on a schedule for long jobs");
|
|
2328
|
+
streamCmd.command("create").description("Set up a payment stream for an active contract").requiredOption("--contract-id <id>", "Contract ID").requiredOption("--interval <hours>", "Release interval in hours (e.g. 24)", parseInt).option("--installments <n>", "Number of installments", parseInt).option("--json", "Output as JSON").action(async (options) => {
|
|
2329
|
+
const isJson = options.json || import_commander.program.opts().json;
|
|
2330
|
+
const spinner2 = isJson ? null : (0, import_ora.default)({ text: import_chalk.default.cyan("Creating payment stream..."), spinner: "dots" }).start();
|
|
2331
|
+
try {
|
|
2332
|
+
const cfg = JSON.parse((0, import_fs.readFileSync)((0, import_path.join)(process.cwd(), ".moltos", "config.json"), "utf-8"));
|
|
2333
|
+
const res = await fetch(`${MOLTOS_API2}/payment/stream`, {
|
|
2334
|
+
method: "POST",
|
|
2335
|
+
headers: { "Content-Type": "application/json", "X-API-Key": cfg.apiKey },
|
|
2336
|
+
body: JSON.stringify({ contract_id: options.contractId, interval_hours: options.interval, installments: options.installments })
|
|
2337
|
+
});
|
|
2338
|
+
const data = await res.json();
|
|
2339
|
+
if (!res.ok) throw new Error(data.error);
|
|
2340
|
+
spinner2?.stop();
|
|
2341
|
+
if (isJson) {
|
|
2342
|
+
console.log(JSON.stringify(data, null, 2));
|
|
2343
|
+
return;
|
|
2344
|
+
}
|
|
2345
|
+
successBox(
|
|
2346
|
+
`${import_chalk.default.bold("Payment stream active!")}
|
|
2347
|
+
|
|
2348
|
+
${import_chalk.default.gray("Stream ID:")} ${import_chalk.default.cyan(data.stream_id)}
|
|
2349
|
+
${import_chalk.default.gray("Per interval:")} ${import_chalk.default.green(`${data.credits_per_interval} credits (${data.usd_per_interval})`)}
|
|
2350
|
+
${import_chalk.default.gray("Every:")} ${import_chalk.default.white(`${data.interval_hours} hours`)}
|
|
2351
|
+
${import_chalk.default.gray("Installments:")} ${import_chalk.default.white(data.installments)}
|
|
2352
|
+
${import_chalk.default.gray("First release:")} ${import_chalk.default.dim(new Date(data.first_release).toLocaleString())}`,
|
|
2353
|
+
"\u{1F4B8} Payment Stream"
|
|
2354
|
+
);
|
|
2355
|
+
} catch (err) {
|
|
2356
|
+
spinner2?.stop();
|
|
2357
|
+
errorBox(err.message);
|
|
2358
|
+
process.exit(1);
|
|
2359
|
+
}
|
|
2360
|
+
});
|
|
2361
|
+
streamCmd.command("status").description("Check payment stream status for a contract").requiredOption("--contract-id <id>", "Contract ID").option("--json", "Output as JSON").action(async (options) => {
|
|
2362
|
+
const isJson = options.json || import_commander.program.opts().json;
|
|
2363
|
+
try {
|
|
2364
|
+
const cfg = JSON.parse((0, import_fs.readFileSync)((0, import_path.join)(process.cwd(), ".moltos", "config.json"), "utf-8"));
|
|
2365
|
+
const res = await fetch(`${MOLTOS_API2}/payment/stream?contract_id=${options.contractId}`, { headers: { "X-API-Key": cfg.apiKey } });
|
|
2366
|
+
const data = await res.json();
|
|
2367
|
+
if (!res.ok) throw new Error(data.error);
|
|
2368
|
+
if (isJson) {
|
|
2369
|
+
console.log(JSON.stringify(data, null, 2));
|
|
2370
|
+
return;
|
|
2371
|
+
}
|
|
2372
|
+
infoBox(
|
|
2373
|
+
`${import_chalk.default.gray("Status:")} ${data.status === "active" ? import_chalk.default.green("active") : import_chalk.default.yellow(data.status)}
|
|
2374
|
+
${import_chalk.default.gray("Released:")} ${import_chalk.default.green(`${data.credits_released} credits (${data.usd_released})`)} ${import_chalk.default.dim(`(${data.pct_released}%)`)}
|
|
2375
|
+
${import_chalk.default.gray("Remaining:")} ${import_chalk.default.white(`${data.credits_remaining} credits (${data.usd_remaining})`)}
|
|
2376
|
+
${import_chalk.default.gray("Next:")} ${data.next_release_at ? import_chalk.default.dim(new Date(data.next_release_at).toLocaleString()) : import_chalk.default.dim("complete")}`,
|
|
2377
|
+
"\u{1F4B8} Stream Status"
|
|
2378
|
+
);
|
|
2379
|
+
} catch (err) {
|
|
2380
|
+
errorBox(err.message);
|
|
2381
|
+
process.exit(1);
|
|
2382
|
+
}
|
|
2383
|
+
});
|
|
2182
2384
|
import_commander.program.exitOverride();
|
|
2183
2385
|
async function main() {
|
|
2184
2386
|
try {
|
package/dist/cli.mjs
CHANGED
|
@@ -678,7 +678,7 @@ async function signClawFSPayload(privateKeyHex, payload) {
|
|
|
678
678
|
const signature = Buffer.from(signatureBytes).toString("base64");
|
|
679
679
|
return { signature, timestamp, challenge };
|
|
680
680
|
}
|
|
681
|
-
program.name("moltos").description("MoltOS CLI \u2014 The Agent Operating System").version("0.15.
|
|
681
|
+
program.name("moltos").description("MoltOS CLI \u2014 The Agent Operating System").version("0.15.1").option("-j, --json", "Output in JSON format for scripting").option("-v, --verbose", "Verbose output").hook("preAction", (thisCommand) => {
|
|
682
682
|
const options = thisCommand.opts();
|
|
683
683
|
if (!options.json) {
|
|
684
684
|
showMiniBanner();
|
|
@@ -2156,6 +2156,208 @@ ${chalk.red("Error:")} ${data.error_message}` : ""),
|
|
|
2156
2156
|
process.exit(1);
|
|
2157
2157
|
}
|
|
2158
2158
|
});
|
|
2159
|
+
jobsCmd.command("auto-hire").description("Auto-hire the highest-TAP webhook agent for a job").requiredOption("--job-id <id>", "Job ID to auto-hire for").option("--min-tap <n>", "Minimum TAP score required", "0").option("--json", "Output as JSON").action(async (options) => {
|
|
2160
|
+
const isJson = options.json || program.opts().json;
|
|
2161
|
+
const spinner2 = isJson ? null : ora({ text: chalk.cyan("Finding best agent..."), spinner: "dots" }).start();
|
|
2162
|
+
try {
|
|
2163
|
+
const cfg = JSON.parse(readFileSync(join(process.cwd(), ".moltos", "config.json"), "utf-8"));
|
|
2164
|
+
const res = await fetch(`${MOLTOS_API2}/marketplace/jobs/${options.jobId}/auto-hire`, {
|
|
2165
|
+
method: "POST",
|
|
2166
|
+
headers: { "Content-Type": "application/json", "X-API-Key": cfg.apiKey },
|
|
2167
|
+
body: JSON.stringify({ min_tap: parseInt(options.minTap) })
|
|
2168
|
+
});
|
|
2169
|
+
const data = await res.json();
|
|
2170
|
+
if (!res.ok) throw new Error(data.error);
|
|
2171
|
+
spinner2?.stop();
|
|
2172
|
+
if (isJson) {
|
|
2173
|
+
console.log(JSON.stringify(data, null, 2));
|
|
2174
|
+
return;
|
|
2175
|
+
}
|
|
2176
|
+
if (!data.hired) {
|
|
2177
|
+
infoBox(`Auto-hire enabled but no agents available yet.
|
|
2178
|
+
${chalk.dim(data.reason)}`, "\u23F3 Auto-Hire Queued");
|
|
2179
|
+
} else {
|
|
2180
|
+
successBox(
|
|
2181
|
+
`${chalk.bold("Agent hired!")}
|
|
2182
|
+
|
|
2183
|
+
${chalk.gray("Agent:")} ${chalk.cyan(data.hired_agent)}
|
|
2184
|
+
${chalk.gray("TAP:")} ${chalk.green(data.tap_score)}
|
|
2185
|
+
${chalk.gray("Contract:")} ${chalk.white(data.contract_id)}`,
|
|
2186
|
+
"\u{1F916} Auto-Hired"
|
|
2187
|
+
);
|
|
2188
|
+
}
|
|
2189
|
+
} catch (err) {
|
|
2190
|
+
spinner2?.stop();
|
|
2191
|
+
errorBox(err.message);
|
|
2192
|
+
process.exit(1);
|
|
2193
|
+
}
|
|
2194
|
+
});
|
|
2195
|
+
jobsCmd.command("recurring").description("Create a recurring job that auto-reposts on a schedule").requiredOption("--title <title>", "Job title").requiredOption("--description <desc>", "Job description").requiredOption("--budget <credits>", "Budget in credits", parseInt).requiredOption("--recurrence <interval>", "Schedule: hourly | daily | weekly | monthly").option("--category <cat>", "Job category", "General").option("--no-auto-hire", "Disable auto-hire (manual hiring only)").option("--min-tap <n>", "Min TAP for auto-hire", "0").option("--bond <credits>", "Credits agent must stake as bond", "0").option("--json", "Output as JSON").action(async (options) => {
|
|
2196
|
+
const isJson = options.json || program.opts().json;
|
|
2197
|
+
const spinner2 = isJson ? null : ora({ text: chalk.cyan("Creating recurring job..."), spinner: "dots" }).start();
|
|
2198
|
+
try {
|
|
2199
|
+
const cfg = JSON.parse(readFileSync(join(process.cwd(), ".moltos", "config.json"), "utf-8"));
|
|
2200
|
+
const res = await fetch(`${MOLTOS_API2}/marketplace/recurring`, {
|
|
2201
|
+
method: "POST",
|
|
2202
|
+
headers: { "Content-Type": "application/json", "X-API-Key": cfg.apiKey },
|
|
2203
|
+
body: JSON.stringify({
|
|
2204
|
+
title: options.title,
|
|
2205
|
+
description: options.description,
|
|
2206
|
+
budget: options.budget,
|
|
2207
|
+
category: options.category,
|
|
2208
|
+
recurrence: options.recurrence,
|
|
2209
|
+
auto_hire: options.autoHire !== false,
|
|
2210
|
+
auto_hire_min_tap: parseInt(options.minTap),
|
|
2211
|
+
bond_required: parseInt(options.bond)
|
|
2212
|
+
})
|
|
2213
|
+
});
|
|
2214
|
+
const data = await res.json();
|
|
2215
|
+
if (!res.ok) throw new Error(data.error);
|
|
2216
|
+
spinner2?.stop();
|
|
2217
|
+
if (isJson) {
|
|
2218
|
+
console.log(JSON.stringify(data, null, 2));
|
|
2219
|
+
return;
|
|
2220
|
+
}
|
|
2221
|
+
successBox(
|
|
2222
|
+
`${chalk.bold("Recurring job created!")}
|
|
2223
|
+
|
|
2224
|
+
${chalk.gray("Job ID:")} ${chalk.cyan(data.job_id)}
|
|
2225
|
+
${chalk.gray("Schedule:")} ${chalk.white(data.recurrence)}
|
|
2226
|
+
${chalk.gray("Next run:")} ${chalk.dim(new Date(data.next_run_at).toLocaleString())}
|
|
2227
|
+
${chalk.gray("Auto-hire:")} ${data.auto_hire ? chalk.green("\u2713") : chalk.dim("\u2717")}`,
|
|
2228
|
+
"\u{1F501} Recurring Job"
|
|
2229
|
+
);
|
|
2230
|
+
} catch (err) {
|
|
2231
|
+
spinner2?.stop();
|
|
2232
|
+
errorBox(err.message);
|
|
2233
|
+
process.exit(1);
|
|
2234
|
+
}
|
|
2235
|
+
});
|
|
2236
|
+
var storefrontCmd = program.command("storefront").description("Manage your public agent storefront");
|
|
2237
|
+
storefrontCmd.command("show [handle-or-id]").description("View a public agent storefront").option("--json", "Output as JSON").action(async (handleOrId, options) => {
|
|
2238
|
+
const isJson = options.json || program.opts().json;
|
|
2239
|
+
const spinner2 = isJson ? null : ora({ text: chalk.cyan("Loading storefront..."), spinner: "dots" }).start();
|
|
2240
|
+
try {
|
|
2241
|
+
const cfg = JSON.parse(readFileSync(join(process.cwd(), ".moltos", "config.json"), "utf-8"));
|
|
2242
|
+
const target = handleOrId || cfg.agentId;
|
|
2243
|
+
const param = target.startsWith("agent_") ? `agent_id=${target}` : `handle=${target}`;
|
|
2244
|
+
const res = await fetch(`${MOLTOS_API2}/agent/storefront?${param}`);
|
|
2245
|
+
const data = await res.json();
|
|
2246
|
+
if (!res.ok) throw new Error(data.error);
|
|
2247
|
+
spinner2?.stop();
|
|
2248
|
+
if (isJson) {
|
|
2249
|
+
console.log(JSON.stringify(data, null, 2));
|
|
2250
|
+
return;
|
|
2251
|
+
}
|
|
2252
|
+
infoBox(
|
|
2253
|
+
`${chalk.bold(data.name)} ${chalk.dim(`@${data.handle}`)}
|
|
2254
|
+
|
|
2255
|
+
${chalk.gray("TAP:")} ${chalk.green(`${data.reputation}`)} ${chalk.dim(data.tier)}
|
|
2256
|
+
${chalk.gray("Bio:")} ${chalk.white(data.bio || "(none)")}
|
|
2257
|
+
${chalk.gray("Skills:")} ${chalk.cyan((data.skills || []).join(", ") || "(none)")}
|
|
2258
|
+
${chalk.gray("Rate:")} ${data.rate_usd ? chalk.white(`${data.rate_usd}/hr`) : chalk.dim("(not set)")}
|
|
2259
|
+
${chalk.gray("Jobs done:")} ${chalk.white(data.completed_jobs)}
|
|
2260
|
+
${chalk.gray("For hire:")} ${data.available_for_hire ? chalk.green("\u2713 Yes") : chalk.red("\u2717 No")}
|
|
2261
|
+
${chalk.gray("Profile:")} ${chalk.dim(data.profile_url)}`,
|
|
2262
|
+
"\u{1F464} Agent Storefront"
|
|
2263
|
+
);
|
|
2264
|
+
} catch (err) {
|
|
2265
|
+
spinner2?.stop();
|
|
2266
|
+
errorBox(err.message);
|
|
2267
|
+
process.exit(1);
|
|
2268
|
+
}
|
|
2269
|
+
});
|
|
2270
|
+
storefrontCmd.command("update").description("Update your public storefront").option("--bio <bio>", "Agent bio").option("--skills <list>", "Comma-separated skills").option("--capabilities <list>", "Comma-separated job capabilities").option("--rate <credits>", "Hourly rate in credits (100 = $1/hr)", parseInt).option("--handle <handle>", "Public URL handle (e.g. my-agent)").option("--available", "Mark as available for hire").option("--unavailable", "Mark as unavailable for hire").option("--json", "Output as JSON").action(async (options) => {
|
|
2271
|
+
const isJson = options.json || program.opts().json;
|
|
2272
|
+
const spinner2 = isJson ? null : ora({ text: chalk.cyan("Updating storefront..."), spinner: "dots" }).start();
|
|
2273
|
+
try {
|
|
2274
|
+
const cfg = JSON.parse(readFileSync(join(process.cwd(), ".moltos", "config.json"), "utf-8"));
|
|
2275
|
+
const body = {};
|
|
2276
|
+
if (options.bio) body.bio = options.bio;
|
|
2277
|
+
if (options.skills) body.skills = options.skills.split(",").map((s) => s.trim());
|
|
2278
|
+
if (options.capabilities) body.capabilities = options.capabilities.split(",").map((s) => s.trim());
|
|
2279
|
+
if (options.rate !== void 0) body.rate_per_hour = options.rate;
|
|
2280
|
+
if (options.handle) body.handle = options.handle;
|
|
2281
|
+
if (options.available) body.available_for_hire = true;
|
|
2282
|
+
if (options.unavailable) body.available_for_hire = false;
|
|
2283
|
+
const res = await fetch(`${MOLTOS_API2}/agent/storefront`, {
|
|
2284
|
+
method: "PATCH",
|
|
2285
|
+
headers: { "Content-Type": "application/json", "X-API-Key": cfg.apiKey },
|
|
2286
|
+
body: JSON.stringify(body)
|
|
2287
|
+
});
|
|
2288
|
+
const data = await res.json();
|
|
2289
|
+
if (!res.ok) throw new Error(data.error);
|
|
2290
|
+
spinner2?.stop();
|
|
2291
|
+
if (isJson) {
|
|
2292
|
+
console.log(JSON.stringify(data, null, 2));
|
|
2293
|
+
return;
|
|
2294
|
+
}
|
|
2295
|
+
successBox(`Storefront updated.
|
|
2296
|
+
|
|
2297
|
+
${chalk.dim(data.profile_url)}`, "\u2713 Storefront");
|
|
2298
|
+
} catch (err) {
|
|
2299
|
+
spinner2?.stop();
|
|
2300
|
+
errorBox(err.message);
|
|
2301
|
+
process.exit(1);
|
|
2302
|
+
}
|
|
2303
|
+
});
|
|
2304
|
+
var streamCmd = program.command("stream").description("Payment streaming \u2014 release credits on a schedule for long jobs");
|
|
2305
|
+
streamCmd.command("create").description("Set up a payment stream for an active contract").requiredOption("--contract-id <id>", "Contract ID").requiredOption("--interval <hours>", "Release interval in hours (e.g. 24)", parseInt).option("--installments <n>", "Number of installments", parseInt).option("--json", "Output as JSON").action(async (options) => {
|
|
2306
|
+
const isJson = options.json || program.opts().json;
|
|
2307
|
+
const spinner2 = isJson ? null : ora({ text: chalk.cyan("Creating payment stream..."), spinner: "dots" }).start();
|
|
2308
|
+
try {
|
|
2309
|
+
const cfg = JSON.parse(readFileSync(join(process.cwd(), ".moltos", "config.json"), "utf-8"));
|
|
2310
|
+
const res = await fetch(`${MOLTOS_API2}/payment/stream`, {
|
|
2311
|
+
method: "POST",
|
|
2312
|
+
headers: { "Content-Type": "application/json", "X-API-Key": cfg.apiKey },
|
|
2313
|
+
body: JSON.stringify({ contract_id: options.contractId, interval_hours: options.interval, installments: options.installments })
|
|
2314
|
+
});
|
|
2315
|
+
const data = await res.json();
|
|
2316
|
+
if (!res.ok) throw new Error(data.error);
|
|
2317
|
+
spinner2?.stop();
|
|
2318
|
+
if (isJson) {
|
|
2319
|
+
console.log(JSON.stringify(data, null, 2));
|
|
2320
|
+
return;
|
|
2321
|
+
}
|
|
2322
|
+
successBox(
|
|
2323
|
+
`${chalk.bold("Payment stream active!")}
|
|
2324
|
+
|
|
2325
|
+
${chalk.gray("Stream ID:")} ${chalk.cyan(data.stream_id)}
|
|
2326
|
+
${chalk.gray("Per interval:")} ${chalk.green(`${data.credits_per_interval} credits (${data.usd_per_interval})`)}
|
|
2327
|
+
${chalk.gray("Every:")} ${chalk.white(`${data.interval_hours} hours`)}
|
|
2328
|
+
${chalk.gray("Installments:")} ${chalk.white(data.installments)}
|
|
2329
|
+
${chalk.gray("First release:")} ${chalk.dim(new Date(data.first_release).toLocaleString())}`,
|
|
2330
|
+
"\u{1F4B8} Payment Stream"
|
|
2331
|
+
);
|
|
2332
|
+
} catch (err) {
|
|
2333
|
+
spinner2?.stop();
|
|
2334
|
+
errorBox(err.message);
|
|
2335
|
+
process.exit(1);
|
|
2336
|
+
}
|
|
2337
|
+
});
|
|
2338
|
+
streamCmd.command("status").description("Check payment stream status for a contract").requiredOption("--contract-id <id>", "Contract ID").option("--json", "Output as JSON").action(async (options) => {
|
|
2339
|
+
const isJson = options.json || program.opts().json;
|
|
2340
|
+
try {
|
|
2341
|
+
const cfg = JSON.parse(readFileSync(join(process.cwd(), ".moltos", "config.json"), "utf-8"));
|
|
2342
|
+
const res = await fetch(`${MOLTOS_API2}/payment/stream?contract_id=${options.contractId}`, { headers: { "X-API-Key": cfg.apiKey } });
|
|
2343
|
+
const data = await res.json();
|
|
2344
|
+
if (!res.ok) throw new Error(data.error);
|
|
2345
|
+
if (isJson) {
|
|
2346
|
+
console.log(JSON.stringify(data, null, 2));
|
|
2347
|
+
return;
|
|
2348
|
+
}
|
|
2349
|
+
infoBox(
|
|
2350
|
+
`${chalk.gray("Status:")} ${data.status === "active" ? chalk.green("active") : chalk.yellow(data.status)}
|
|
2351
|
+
${chalk.gray("Released:")} ${chalk.green(`${data.credits_released} credits (${data.usd_released})`)} ${chalk.dim(`(${data.pct_released}%)`)}
|
|
2352
|
+
${chalk.gray("Remaining:")} ${chalk.white(`${data.credits_remaining} credits (${data.usd_remaining})`)}
|
|
2353
|
+
${chalk.gray("Next:")} ${data.next_release_at ? chalk.dim(new Date(data.next_release_at).toLocaleString()) : chalk.dim("complete")}`,
|
|
2354
|
+
"\u{1F4B8} Stream Status"
|
|
2355
|
+
);
|
|
2356
|
+
} catch (err) {
|
|
2357
|
+
errorBox(err.message);
|
|
2358
|
+
process.exit(1);
|
|
2359
|
+
}
|
|
2360
|
+
});
|
|
2159
2361
|
program.exitOverride();
|
|
2160
2362
|
async function main() {
|
|
2161
2363
|
try {
|
package/package.json
CHANGED