clawmoney 0.15.32 → 0.15.34

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.
@@ -346,7 +346,36 @@ export async function relaySetupCommand() {
346
346
  log.warn(`${f.cli}/${f.model}: ${chalk.dim(f.error.slice(0, 120))}`);
347
347
  }
348
348
  }
349
- // ── Step 7: auto-start the daemon ──
349
+ // ── Step 7: prune — implement "pick-what-you-run" semantics ──
350
+ //
351
+ // setup is meant to be declarative: the cli_types the user just picked
352
+ // are the complete set of what the daemon should serve. Earlier test
353
+ // runs that registered different subscriptions (antigravity, gemini,
354
+ // etc.) would otherwise linger in the DB and get preflighted every
355
+ // daemon start, confusing the user who just picked claude+codex.
356
+ //
357
+ // We only prune AFTER registration succeeds, so a failed batch doesn't
358
+ // wipe the user's existing state. And we only send the selected
359
+ // cli_types as keep_cli_types — the backend handles the "delete what's
360
+ // not in the list" part.
361
+ try {
362
+ const pruneResp = await apiPost("/api/v1/relay/providers/prune", { keep_cli_types: Array.from(new Set(selectedClis)) }, config.api_key);
363
+ if (pruneResp.ok &&
364
+ pruneResp.data?.deleted &&
365
+ pruneResp.data.deleted.length > 0) {
366
+ log.success(`Cleaned up ${pruneResp.data.deleted.length} provider(s) from earlier runs ` +
367
+ chalk.dim("(" +
368
+ Array.from(new Set(pruneResp.data.deleted.map((d) => d.cli_type))).join(", ") +
369
+ ")"));
370
+ }
371
+ }
372
+ catch (err) {
373
+ // Non-fatal: worst case is the daemon preflights extra cli_types,
374
+ // which is annoying but doesn't break anything.
375
+ log.warn(`Could not prune old providers: ${err.message} — ` +
376
+ `run \`clawmoney relay status\` and clean manually if needed`);
377
+ }
378
+ // ── Step 8: auto-start the daemon ──
350
379
  //
351
380
  // The daemon now runs in multi-cli auto mode by default: it fetches
352
381
  // every provider this agent has registered, preflights each distinct
@@ -370,8 +399,8 @@ export async function relaySetupCommand() {
370
399
  // instead of 6.
371
400
  log.message(chalk.dim("Next:") +
372
401
  "\n" +
373
- ` ${chalk.cyan("clawmoney relay status")} daemon health + providers\n` +
374
- ` ${chalk.cyan("clawmoney relay credits")} earnings + balance\n` +
402
+ ` ${chalk.cyan("clawmoney relay status")} daemon + provider list\n` +
403
+ ` ${chalk.cyan("clawmoney wallet balance")} on-chain + relay earnings\n` +
375
404
  ` ${chalk.cyan("clawmoney relay stop")} stop daemon`);
376
405
  const cliLabel = uniqueClis.length === 1
377
406
  ? `${uniqueClis[0]} daemon running`
@@ -18,5 +18,4 @@ export declare function relayLogsCommand(options: {
18
18
  }): Promise<void>;
19
19
  export declare function relayStatusCommand(): Promise<void>;
20
20
  export declare function relayModelsCommand(): Promise<void>;
21
- export declare function relayCreditsCommand(): Promise<void>;
22
21
  export {};
@@ -344,28 +344,3 @@ export async function relayModelsCommand() {
344
344
  throw err;
345
345
  }
346
346
  }
347
- export async function relayCreditsCommand() {
348
- const config = requireConfig();
349
- const spinner = ora("Fetching relay credits...").start();
350
- try {
351
- const resp = await apiGet("/api/v1/relay/credits", config.api_key);
352
- if (!resp.ok) {
353
- const detail = resp.data?.detail ?? resp.status;
354
- spinner.fail(chalk.red(`Failed to fetch credits: ${detail}`));
355
- process.exit(1);
356
- }
357
- const data = resp.data;
358
- spinner.succeed("Relay Credits");
359
- console.log("");
360
- console.log(` ${chalk.bold("Balance:")} $${(data.balance_usd ?? 0).toFixed(2)}`);
361
- console.log(` ${chalk.bold("Total Spent:")} $${(data.total_spent_usd ?? 0).toFixed(2)}`);
362
- console.log(` ${chalk.bold("Total Requests:")} ${data.total_requests ?? 0}`);
363
- if (data.last_used_at) {
364
- console.log(` ${chalk.bold("Last Used:")} ${data.last_used_at}`);
365
- }
366
- }
367
- catch (err) {
368
- spinner.fail(chalk.red("Failed to fetch credits"));
369
- throw err;
370
- }
371
- }
@@ -1,6 +1,8 @@
1
1
  import chalk from 'chalk';
2
2
  import ora from 'ora';
3
3
  import { awalExec } from '../utils/awal.js';
4
+ import { apiGet } from '../utils/api.js';
5
+ import { loadConfig } from '../utils/config.js';
4
6
  export async function walletStatusCommand() {
5
7
  const spinner = ora('Getting wallet status...').start();
6
8
  try {
@@ -20,25 +22,51 @@ export async function walletStatusCommand() {
20
22
  }
21
23
  export async function walletBalanceCommand() {
22
24
  const spinner = ora('Getting wallet balance...').start();
25
+ // Kick off both calls in parallel. Relay earnings are loaded from
26
+ // the clawmoney backend per-agent; the on-chain balance is awal's
27
+ // native `balance` RPC. We don't block on-chain display if relay
28
+ // fetching fails — the on-chain balance is the authoritative "real
29
+ // money" view.
30
+ const config = loadConfig();
31
+ const relayPromise = config?.api_key
32
+ ? apiGet("/api/v1/relay/providers/me", config.api_key)
33
+ .then((resp) => (resp.ok && Array.isArray(resp.data) ? resp.data : null))
34
+ .catch(() => null)
35
+ : Promise.resolve(null);
36
+ let awalResult;
23
37
  try {
24
- const result = await awalExec(['balance']);
25
- spinner.succeed('Wallet Balance');
26
- console.log('');
27
- const data = result.data;
28
- if (typeof data === 'object' && data !== null) {
29
- for (const [key, value] of Object.entries(data)) {
30
- console.log(` ${chalk.dim(key + ':')} ${chalk.green(String(value))}`);
31
- }
32
- }
33
- else {
34
- console.log(` ${result.raw}`);
35
- }
36
- console.log('');
38
+ awalResult = await awalExec(['balance']);
37
39
  }
38
40
  catch (err) {
39
41
  spinner.fail('Failed to get wallet balance');
40
42
  console.error(chalk.red(err.message));
43
+ return;
41
44
  }
45
+ const relayRows = await relayPromise;
46
+ spinner.succeed('Wallet');
47
+ console.log('');
48
+ console.log(chalk.bold(' On-chain (awal)'));
49
+ const data = awalResult.data;
50
+ if (typeof data === 'object' && data !== null) {
51
+ for (const [key, value] of Object.entries(data)) {
52
+ console.log(` ${chalk.dim(key + ':').padEnd(22)} ${chalk.green(String(value))}`);
53
+ }
54
+ }
55
+ else {
56
+ console.log(` ${awalResult.raw}`);
57
+ }
58
+ if (relayRows && relayRows.length > 0) {
59
+ const earned = relayRows.reduce((s, p) => s + (p.total_earned_usd ?? 0), 0);
60
+ const withdrawn = relayRows.reduce((s, p) => s + (p.total_withdrawn_usd ?? 0), 0);
61
+ const pending = Math.max(0, earned - withdrawn);
62
+ const requests = relayRows.reduce((s, p) => s + (p.total_requests ?? 0), 0);
63
+ console.log('');
64
+ console.log(chalk.bold(' Relay earnings'));
65
+ console.log(` ${chalk.dim('Earned:').padEnd(22)} ${chalk.green('$' + earned.toFixed(2))}`);
66
+ console.log(` ${chalk.dim('Pending payout:').padEnd(22)} ${chalk.green('$' + pending.toFixed(2))}`);
67
+ console.log(chalk.dim(` (${relayRows.length} provider${relayRows.length === 1 ? "" : "s"} · ${requests} request${requests === 1 ? "" : "s"} served)`));
68
+ }
69
+ console.log('');
42
70
  }
43
71
  export async function walletAddressCommand() {
44
72
  const spinner = ora('Getting wallet address...').start();
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ import { walletStatusCommand, walletBalanceCommand, walletAddressCommand, wallet
8
8
  import { tweetCommand } from './commands/tweet.js';
9
9
  import { gigCreateCommand, gigBrowseCommand, gigDetailCommand, gigAcceptCommand, gigDeliverCommand, gigApproveCommand, gigDisputeCommand, } from './commands/gig.js';
10
10
  import { hubStartCommand, hubStopCommand, hubStatusCommand, hubSearchCommand, hubCallCommand, hubRegisterCommand, hubSkillsCommand, hubOrderCommand, hubHistoryCommand, } from './commands/hub.js';
11
- import { relayRegisterCommand, relayStartCommand, relayStopCommand, relayStatusCommand, relayModelsCommand, relayCreditsCommand, relayLogsCommand, } from './commands/relay.js';
11
+ import { relayRegisterCommand, relayStartCommand, relayStopCommand, relayStatusCommand, relayModelsCommand, relayLogsCommand, } from './commands/relay.js';
12
12
  import { antigravityLoginCommand, antigravityStatusCommand, } from './commands/antigravity.js';
13
13
  import { createRequire } from 'node:module';
14
14
  const require = createRequire(import.meta.url);
@@ -34,7 +34,7 @@ program
34
34
  // account
35
35
  program
36
36
  .command('account')
37
- .description('Show current agent info (wallet, email, slug, credits)')
37
+ .description('Show current agent info (wallet, email, slug)')
38
38
  .action(async () => {
39
39
  try {
40
40
  const { requireConfig } = await import('./utils/config.js');
@@ -56,10 +56,6 @@ program
56
56
  console.log(` ${chalk.bold('Email:')} ${a.email ?? '-'}`);
57
57
  console.log(` ${chalk.bold('Wallet:')} ${a.wallet_address ?? 'not set'}`);
58
58
  console.log(` ${chalk.bold('Status:')} ${a.status ?? '-'}`);
59
- const credResp = await apiGet('/api/v1/relay/credits', config.api_key);
60
- if (credResp.ok && credResp.data) {
61
- console.log(` ${chalk.bold('Credits:')} $${Number(credResp.data.balance_usd ?? 0).toFixed(2)}`);
62
- }
63
59
  // Query Base mainnet USDC balance directly via JSON-RPC (no awal
64
60
  // dependency — works even if awal wallet bridge is down). Base USDC
65
61
  // is 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913, balanceOf(address)
@@ -553,18 +549,6 @@ relay
553
549
  process.exit(1);
554
550
  }
555
551
  });
556
- relay
557
- .command('credits')
558
- .description('Check relay credit balance')
559
- .action(async () => {
560
- try {
561
- await relayCreditsCommand();
562
- }
563
- catch (err) {
564
- console.error(err.message);
565
- process.exit(1);
566
- }
567
- });
568
552
  // antigravity (Google Antigravity IDE OAuth — separate quota pool + Claude access)
569
553
  const antigravity = program
570
554
  .command('antigravity')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawmoney",
3
- "version": "0.15.32",
3
+ "version": "0.15.34",
4
4
  "description": "ClawMoney CLI -- Earn rewards with your AI agent",
5
5
  "type": "module",
6
6
  "bin": {