clawmoney 0.15.28 → 0.15.30

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.
@@ -7,7 +7,7 @@ import chalk from "chalk";
7
7
  import { apiPost } from "../utils/api.js";
8
8
  import { loadConfig, requireConfig } from "../utils/config.js";
9
9
  import { setupCommand } from "./setup.js";
10
- import { API_PRICES, RELAY_DISCOUNT, PLATFORM_FEE } from "../relay/pricing.js";
10
+ import { API_PRICES, PLATFORM_FEE } from "../relay/pricing.js";
11
11
  // ── Per-cli_type model catalogs ──
12
12
  //
13
13
  // `RECOMMENDED_MODELS` is what gets registered when the user picks "all
@@ -119,12 +119,6 @@ function detectInstalledClis() {
119
119
  });
120
120
  return results;
121
121
  }
122
- // ── Helpers ──
123
- function formatBuyerPrice(input, output) {
124
- const buyerInput = (input * RELAY_DISCOUNT).toFixed(3);
125
- const buyerOutput = (output * RELAY_DISCOUNT).toFixed(3);
126
- return `$${buyerInput}/$${buyerOutput} per 1M (after ${Math.round((1 - RELAY_DISCOUNT) * 100)}% relay discount)`;
127
- }
128
122
  // ── Main command ──
129
123
  export async function relaySetupCommand() {
130
124
  // ── Step 0: ensure the agent is logged in ──
@@ -201,10 +195,7 @@ export async function relaySetupCommand() {
201
195
  log.warn(`${cli}: no recommended models found — skipping`);
202
196
  continue;
203
197
  }
204
- log.step(`${chalk.bold(cli)}: auto-registering ${recommended.length} recommended models`);
205
- for (const m of recommended) {
206
- log.message(chalk.dim(` · ${m}`));
207
- }
198
+ log.step(`${chalk.bold(cli)}: ${recommended.length} models ${chalk.dim("— " + recommended.join(", "))}`);
208
199
  for (const model of recommended) {
209
200
  const p = API_PRICES[model];
210
201
  registrations.push({
@@ -276,36 +267,30 @@ export async function relaySetupCommand() {
276
267
  process.exit(0);
277
268
  }
278
269
  const dailyLimit = dailyLimitChoice;
279
- // ── Step 5: confirmation summary ──
280
- // Translate the chosen daily-limit USD value back into the percentage
281
- // label the user picked, so what they see in the summary matches what
282
- // they answered in the prompt.
270
+ // ── Step 5: register everything under one spinner ──
271
+ //
272
+ // We deliberately skip the old per-model Summary block: pricing is on
273
+ // the website, and Step 3 already listed which models were queued per
274
+ // subscription. The remaining signal (quota share + earn %) goes into
275
+ // the spinner's final message so users see it exactly once.
276
+ //
277
+ // Also: one spinner for the whole batch, not N. Sequential per-model
278
+ // spinners produced 7+ rows of clack vertical whitespace for what's
279
+ // really a single bulk action.
280
+ //
281
+ // No "Register all N providers now?" confirm either — the user picked
282
+ // subscriptions + quota share above; Ctrl-C still aborts, and the
283
+ // backend is idempotent so mid-way aborts are safe to re-run.
283
284
  const limitLabel = {
284
- 15: "~25% (Light)",
285
- 30: "~50% (Balanced)",
286
- 45: "~75% (Heavy)",
287
- 60: "~100% (Full)",
285
+ 15: "~25%", 30: "~50%", 45: "~75%", 60: "~100%",
288
286
  };
289
- log.step(chalk.bold("Summary"));
290
- for (const r of registrations) {
291
- log.message(` ${chalk.cyan(r.cli + "/" + r.model).padEnd(50)} ${chalk.dim(formatBuyerPrice(r.input, r.output))}`);
292
- }
293
- log.message(chalk.dim(` ${registrations.length} provider(s) · ${limitLabel[dailyLimit] ?? `$${dailyLimit}/day cap`} per model`));
294
- log.message(chalk.dim(` You earn ~${Math.round((1 - PLATFORM_FEE) * 100)}% of what buyers pay (after platform fee)`));
295
- log.message(chalk.dim(` To customize: edit ~/.clawmoney/config.yaml after start`));
296
- // ── Step 6: register each (idempotent — "already registered" counts as success) ──
297
- //
298
- // No "Register all N providers now?" confirm — the user already
299
- // picked subscriptions + daily quota share. Seeing the summary and
300
- // immediately going into registration is the expected flow. Ctrl-C
301
- // still aborts, and registrations are idempotent so a mid-way abort
302
- // is recoverable by re-running.
287
+ const earnPct = Math.round((1 - PLATFORM_FEE) * 100);
303
288
  let succeeded = 0;
304
289
  let failed = 0;
305
290
  const failures = [];
291
+ const regSpin = spinner();
292
+ regSpin.start(`Registering ${registrations.length} providers...`);
306
293
  for (const r of registrations) {
307
- const regSpin = spinner();
308
- regSpin.start(`Registering ${r.cli}/${r.model}...`);
309
294
  try {
310
295
  const body = {
311
296
  cli_type: r.cli,
@@ -318,7 +303,6 @@ export async function relaySetupCommand() {
318
303
  };
319
304
  const resp = await apiPost("/api/v1/relay/providers", body, config.api_key);
320
305
  if (resp.ok) {
321
- regSpin.stop(`${chalk.green("✓")} ${r.cli}/${r.model}`);
322
306
  succeeded++;
323
307
  }
324
308
  else {
@@ -328,11 +312,9 @@ export async function relaySetupCommand() {
328
312
  const detail = typeof raw === "string" ? raw : JSON.stringify(raw);
329
313
  // Already-registered is a soft success — idempotent re-run.
330
314
  if (detail.includes("Already registered")) {
331
- regSpin.stop(`${chalk.yellow("~")} ${r.cli}/${r.model} ${chalk.dim("(already registered, no change)")}`);
332
315
  succeeded++;
333
316
  }
334
317
  else {
335
- regSpin.stop(`${chalk.red("✗")} ${r.cli}/${r.model} ${chalk.dim("(" + detail.slice(0, 80) + ")")}`);
336
318
  failed++;
337
319
  failures.push({ cli: r.cli, model: r.model, error: detail });
338
320
  }
@@ -340,21 +322,28 @@ export async function relaySetupCommand() {
340
322
  }
341
323
  catch (err) {
342
324
  const msg = err.message;
343
- regSpin.stop(`${chalk.red("✗")} ${r.cli}/${r.model} ${chalk.dim("(" + msg + ")")}`);
344
325
  failed++;
345
326
  failures.push({ cli: r.cli, model: r.model, error: msg });
346
327
  }
347
328
  }
348
- // ── Step 7: registration done, offer to auto-start ──
349
- log.step(chalk.bold("Registered"));
350
- log.message(`${chalk.green(succeeded.toString())} provider(s) registered`);
329
+ if (failed === 0) {
330
+ regSpin.stop(`${chalk.green(`✓ ${succeeded} providers registered`)} ` +
331
+ chalk.dim(`(${limitLabel[dailyLimit] ?? `$${dailyLimit}`} quota share · you earn ~${earnPct}%)`));
332
+ }
333
+ else {
334
+ regSpin.stop(`${chalk.yellow(`${succeeded} registered, ${failed} failed`)}`);
335
+ }
336
+ // ── Step 6: on failure, list which ones broke ──
337
+ //
338
+ // On success we say nothing — the spinner's final message is already
339
+ // the "registered" summary. On failure we dump a per-row detail line
340
+ // so the user can tell what to fix.
351
341
  if (failed > 0) {
352
- log.warn(`${failed} registrations failed`);
353
342
  for (const f of failures) {
354
- log.message(chalk.dim(` ${f.cli}/${f.model}: ${f.error.slice(0, 120)}`));
343
+ log.warn(`${f.cli}/${f.model}: ${chalk.dim(f.error.slice(0, 120))}`);
355
344
  }
356
345
  }
357
- // ── Step 8: auto-start the daemon ──
346
+ // ── Step 7: auto-start the daemon ──
358
347
  //
359
348
  // The daemon now runs in multi-cli auto mode by default: it fetches
360
349
  // every provider this agent has registered, preflights each distinct
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawmoney",
3
- "version": "0.15.28",
3
+ "version": "0.15.30",
4
4
  "description": "ClawMoney CLI -- Earn rewards with your AI agent",
5
5
  "type": "module",
6
6
  "bin": {