@thirdfy/agent-cli 0.1.36 → 0.1.37

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/CHANGELOG.md CHANGED
@@ -4,6 +4,21 @@ All notable changes to `@thirdfy/agent-cli` are documented here. The format is b
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.1.37] - 2026-05-17
8
+
9
+ ### Added
10
+
11
+ - Email OTP `thirdfy-agent login email` two-step onboarding (`send OTP` then `--code --accept-terms`) plus `help onboarding`, `doctor auth`, and `wallet list` so agents can learn and verify setup directly from the CLI.
12
+
13
+ ### Changed
14
+
15
+ - `whoami` now reports masked auth, agent, and wallet profile state instead of dumping raw local config secrets.
16
+
17
+ ### Fixed
18
+
19
+ - Onboarding help: neutral email-OTP wording, safer `maskSecret` for short tokens, and a non-interactive example that places `--ni` after `login email` so argv parsing does not swallow the `login` token.
20
+ - `doctor auth`: agent API key is diagnostic-only (optional until execution); missing key no longer fails the command while the detail calls it optional.
21
+
7
22
  ## [0.1.36] - 2026-05-16
8
23
 
9
24
  ### Added
package/README.md CHANGED
@@ -77,6 +77,13 @@ Execution-only workflows can run with only `AGENT_API_KEY` after onboarding is c
77
77
  ### Login / logout / config UX
78
78
 
79
79
  ```bash
80
+ # Email OTP first-run flow
81
+ thirdfy-agent login email you@example.com --json
82
+ thirdfy-agent login email you@example.com --code "<otp>" --accept-terms --key-name "My Agent" --json
83
+ thirdfy-agent whoami --json
84
+ thirdfy-agent wallet list --json
85
+ thirdfy-agent doctor auth --json
86
+
80
87
  # Store auth defaults once
81
88
  thirdfy-agent login --auth-token "$THIRDFY_AUTH_TOKEN" --agent-api-key "$AGENT_API_KEY" --json
82
89
 
@@ -95,6 +102,8 @@ thirdfy-agent logout --json
95
102
  thirdfy-agent logout --all --json
96
103
  ```
97
104
 
105
+ `login email` is a two-step headless-safe flow. Without `--code`, the CLI asks the Thirdfy API onboarding broker to send a Privy email OTP and exits with the exact next command. With `--code --accept-terms`, it stores a short-lived owner session in `~/.thirdfy/config.json`, records linked EVM/Solana wallets when Privy returns them, and stores a new agent API key when first-run bootstrap issues one. Use `--not-interactive` / `--ni` in automation so missing input fails fast instead of prompting.
106
+
98
107
  `logout --all` is provider-agnostic: it attempts owner-session revocation when a session token exists, then always clears local credentials.
99
108
 
100
109
  ### Wallet-sign onboarding path
@@ -157,6 +157,9 @@ async function main() {
157
157
  case 'config set':
158
158
  await commandConfigSet(context, subFlags);
159
159
  return;
160
+ case 'login email':
161
+ await commandLoginEmail(context, { ...subFlags, address: parsed.positionals[2] });
162
+ return;
160
163
  case 'login':
161
164
  await commandLogin(context, subFlags);
162
165
  return;
@@ -164,11 +167,21 @@ async function main() {
164
167
  await commandLogout(context, subFlags);
165
168
  return;
166
169
  case 'whoami':
167
- await commandProfileShow(context, subFlags);
170
+ await commandWhoami(context, subFlags);
168
171
  return;
169
172
  case 'doctor self':
170
173
  await commandDoctorSelf(context, subFlags);
171
174
  return;
175
+ case 'doctor auth':
176
+ await commandDoctorAuth(context, subFlags);
177
+ return;
178
+ case 'help onboarding':
179
+ case 'onboarding help':
180
+ await commandHelpOnboarding(context, subFlags);
181
+ return;
182
+ case 'wallet list':
183
+ await commandWalletList(context, subFlags);
184
+ return;
172
185
  default:
173
186
  break;
174
187
  }
@@ -361,6 +374,10 @@ function parseArgs(argv) {
361
374
  return { flags, positionals };
362
375
  }
363
376
 
377
+ function isNonInteractive(flags = {}) {
378
+ return Boolean(flags.notInteractive || flags.ni || process.env.THIRDFY_NOT_INTERACTIVE === '1');
379
+ }
380
+
364
381
  function toCamel(input) {
365
382
  return String(input || '')
366
383
  .trim()
@@ -2427,6 +2444,183 @@ async function commandProfileShow(ctx, _flags) {
2427
2444
  });
2428
2445
  }
2429
2446
 
2447
+ function maskSecret(value) {
2448
+ const raw = String(value || '').trim();
2449
+ if (!raw) return null;
2450
+ if (raw.length <= 12) return '***';
2451
+ if (raw.length <= 20) return `${raw.slice(0, 4)}***${raw.slice(-2)}`;
2452
+ return `${raw.slice(0, 6)}...${raw.slice(-4)}`;
2453
+ }
2454
+
2455
+ function buildOnboardingHelp(ctx) {
2456
+ return {
2457
+ title: 'Thirdfy Agent CLI onboarding',
2458
+ summary: 'Use email OTP, wallet-sign, or existing credentials to create owner auth, wallets, and agent execution credentials.',
2459
+ paths: [
2460
+ {
2461
+ id: 'email_otp',
2462
+ recommended: true,
2463
+ description: 'Email OTP first-run flow for humans and agents that can ask the user for a verification code.',
2464
+ commands: [
2465
+ 'thirdfy-agent login email user@example.com',
2466
+ 'thirdfy-agent login email user@example.com --code <otp> --accept-terms --key-name "My Agent"',
2467
+ 'thirdfy-agent whoami',
2468
+ 'thirdfy-agent managed wallet init --chain-id 8453',
2469
+ ],
2470
+ },
2471
+ {
2472
+ id: 'wallet_sign',
2473
+ description: 'Headless wallet proof for operators with an EVM signer.',
2474
+ commands: [
2475
+ 'thirdfy-agent agent auth challenge --agent-key 0xYOUR_AGENT_KEY --json',
2476
+ 'thirdfy-agent login --agent-key 0xYOUR_AGENT_KEY --challenge-id <id> --signature <hex> --json',
2477
+ ],
2478
+ },
2479
+ {
2480
+ id: 'existing_credentials',
2481
+ description: 'Use already-issued owner or agent credentials from a secure secret store.',
2482
+ commands: [
2483
+ 'thirdfy-agent login --owner-session-token "$THIRDFY_OWNER_SESSION_TOKEN"',
2484
+ 'thirdfy-agent login --auth-token "$THIRDFY_AUTH_TOKEN"',
2485
+ 'thirdfy-agent login --agent-api-key "$THIRDFY_AGENT_API_KEY"',
2486
+ ],
2487
+ },
2488
+ {
2489
+ id: 'mcp_bootstrap',
2490
+ description: 'After owner proof, issue an MCP bootstrap token for agents.',
2491
+ commands: [
2492
+ 'thirdfy-agent bootstrap complete --agent-key 0xYOUR_AGENT_KEY --owner-session-token "$THIRDFY_OWNER_SESSION_TOKEN" --lane thirdfy --json',
2493
+ ],
2494
+ },
2495
+ ],
2496
+ nonInteractive: {
2497
+ flag: '--not-interactive or --ni',
2498
+ example:
2499
+ 'thirdfy-agent login email user@example.com --code 123456 --accept-terms --ni (place --ni after the subcommand so it is not parsed as a flag value)',
2500
+ rule: 'Commands must fail fast instead of waiting for prompts when required input is missing.',
2501
+ },
2502
+ apiBase: ctx.apiBase,
2503
+ };
2504
+ }
2505
+
2506
+ async function commandHelpOnboarding(ctx, _flags) {
2507
+ printEnvelope({
2508
+ success: true,
2509
+ code: 'ONBOARDING_HELP_OK',
2510
+ message: 'Thirdfy onboarding help',
2511
+ data: buildOnboardingHelp(ctx),
2512
+ meta: { apiBase: ctx.apiBase },
2513
+ });
2514
+ }
2515
+
2516
+ async function commandWhoami(ctx, _flags) {
2517
+ const config = loadProfileConfig();
2518
+ const auth = config.auth && typeof config.auth === 'object' ? config.auth : {};
2519
+ const agent = config.agent && typeof config.agent === 'object' ? config.agent : {};
2520
+ const wallets = config.wallets && typeof config.wallets === 'object' ? config.wallets : {};
2521
+ printEnvelope({
2522
+ success: true,
2523
+ code: 'WHOAMI_OK',
2524
+ message: 'Thirdfy CLI identity loaded',
2525
+ data: {
2526
+ profile: ctx.profile || config.profile || 'personal',
2527
+ runMode: ctx.runMode || config.runMode || 'thirdfy',
2528
+ custodyMode: ctx.custodyMode || config.custodyMode || defaultCustodyModeForRunMode(ctx.runMode || config.runMode || 'thirdfy'),
2529
+ auth: {
2530
+ source: auth.source || null,
2531
+ hasAuthToken: Boolean(auth.authToken),
2532
+ hasOwnerSessionToken: Boolean(auth.ownerSessionToken),
2533
+ ownerSessionToken: maskSecret(auth.ownerSessionToken),
2534
+ ownerSessionExpiresAt: auth.ownerSessionExpiresAt || null,
2535
+ },
2536
+ agent: {
2537
+ hasAgentApiKey: Boolean(agent.apiKey),
2538
+ agentApiKey: maskSecret(agent.apiKey),
2539
+ agentKey: agent.agentKey || null,
2540
+ },
2541
+ wallets: {
2542
+ primaryEvmWallet: wallets.primaryEvmWallet || null,
2543
+ evm: Array.isArray(wallets.evm) ? wallets.evm : [],
2544
+ solana: Array.isArray(wallets.solana) ? wallets.solana : [],
2545
+ },
2546
+ configPath: getProfileConfigPath(),
2547
+ nextSteps: buildOnboardingHelp(ctx).paths[0].commands,
2548
+ },
2549
+ meta: { apiBase: ctx.apiBase },
2550
+ });
2551
+ }
2552
+
2553
+ async function commandWalletList(ctx, _flags) {
2554
+ const config = loadProfileConfig();
2555
+ const wallets = config.wallets && typeof config.wallets === 'object' ? config.wallets : {};
2556
+ printEnvelope({
2557
+ success: true,
2558
+ code: 'WALLET_LIST_OK',
2559
+ message: 'Linked wallets from local Thirdfy CLI profile',
2560
+ data: {
2561
+ primaryEvmWallet: wallets.primaryEvmWallet || null,
2562
+ evm: Array.isArray(wallets.evm) ? wallets.evm : [],
2563
+ solana: Array.isArray(wallets.solana) ? wallets.solana : [],
2564
+ hint: 'Run `thirdfy-agent login email <email>` to refresh linked wallets from Privy-backed onboarding.',
2565
+ },
2566
+ meta: { apiBase: ctx.apiBase },
2567
+ });
2568
+ }
2569
+
2570
+ async function commandDoctorAuth(ctx, _flags) {
2571
+ const config = loadProfileConfig();
2572
+ const auth = config.auth && typeof config.auth === 'object' ? config.auth : {};
2573
+ const agent = config.agent && typeof config.agent === 'object' ? config.agent : {};
2574
+ const ownerSessionTokenFromEnv = String(process.env.THIRDFY_OWNER_SESSION_TOKEN || '').trim();
2575
+ const authTokenFromEnv = String(process.env.THIRDFY_AUTH_TOKEN || '').trim();
2576
+ const agentApiKeyFromEnv = String(process.env.THIRDFY_AGENT_API_KEY || '').trim();
2577
+ const checks = [
2578
+ {
2579
+ name: 'owner-auth',
2580
+ ok: Boolean(auth.ownerSessionToken || auth.authToken || ownerSessionTokenFromEnv || authTokenFromEnv),
2581
+ detail: auth.ownerSessionToken
2582
+ ? 'owner session stored'
2583
+ : auth.authToken
2584
+ ? 'auth token stored'
2585
+ : ownerSessionTokenFromEnv
2586
+ ? 'owner session from THIRDFY_OWNER_SESSION_TOKEN'
2587
+ : authTokenFromEnv
2588
+ ? 'auth token from THIRDFY_AUTH_TOKEN'
2589
+ : 'missing owner auth; run `thirdfy-agent login email <email>`',
2590
+ },
2591
+ {
2592
+ name: 'agent-api-key',
2593
+ optional: true,
2594
+ ok: Boolean(agent.apiKey || agentApiKeyFromEnv),
2595
+ detail: agent.apiKey
2596
+ ? 'agent API key stored'
2597
+ : agentApiKeyFromEnv
2598
+ ? 'agent API key from THIRDFY_AGENT_API_KEY'
2599
+ : 'not stored yet (optional until execution); complete onboarding or bootstrap to add one',
2600
+ },
2601
+ {
2602
+ name: 'wallet-profile',
2603
+ ok: Boolean(config.wallets?.primaryEvmWallet || (Array.isArray(config.wallets?.evm) && config.wallets.evm.length)),
2604
+ detail: config.wallets?.primaryEvmWallet
2605
+ || (Array.isArray(config.wallets?.evm) && config.wallets.evm.length
2606
+ ? `${config.wallets.evm.length} linked EVM wallet${config.wallets.evm.length === 1 ? '' : 's'}`
2607
+ : 'missing wallet profile; run email onboarding or wallet-sign proof'),
2608
+ },
2609
+ ];
2610
+ const ok = checks.every((entry) => entry.optional || entry.ok);
2611
+ printEnvelope({
2612
+ success: ok,
2613
+ code: ok ? 'DOCTOR_AUTH_OK' : 'DOCTOR_AUTH_NEEDS_SETUP',
2614
+ message: ok ? 'Auth profile is ready' : 'Auth profile needs setup',
2615
+ data: {
2616
+ checks,
2617
+ help: buildOnboardingHelp(ctx),
2618
+ },
2619
+ meta: { apiBase: ctx.apiBase },
2620
+ });
2621
+ if (!ok) process.exit(1);
2622
+ }
2623
+
2430
2624
  async function commandConfigSet(ctx, flags) {
2431
2625
  const key = String(flags.key || '').trim();
2432
2626
  const value = flags.value;
@@ -2577,6 +2771,149 @@ async function commandLogin(ctx, flags) {
2577
2771
  });
2578
2772
  }
2579
2773
 
2774
+ async function commandLoginEmail(ctx, flags) {
2775
+ const current = loadProfileConfig();
2776
+ const email = String(flags.address || flags.email || '').trim().toLowerCase();
2777
+ if (!email) {
2778
+ throw createCliError(
2779
+ 'LOGIN_EMAIL_REQUIRED',
2780
+ isNonInteractive(flags)
2781
+ ? 'Missing email address for non-interactive login. Use: thirdfy-agent login email user@example.com [--code <otp> --accept-terms]'
2782
+ : 'Missing email address. Use: thirdfy-agent login email user@example.com'
2783
+ );
2784
+ }
2785
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
2786
+ throw createCliError('LOGIN_EMAIL_INVALID', 'Provide a valid email address for Thirdfy email login.');
2787
+ }
2788
+ const code = String(flags.code || flags.otp || '').trim();
2789
+ const keyName = String(flags.keyName || 'Thirdfy CLI').trim();
2790
+ if (!code) {
2791
+ const response = await apiPost(ctx, '/api/v1/agent/onboarding/cli/email/start', {
2792
+ email,
2793
+ keyName,
2794
+ requestedCapabilities: {
2795
+ walletApi: true,
2796
+ agentApi: true,
2797
+ evmWallet: true,
2798
+ solanaWallet: true,
2799
+ },
2800
+ });
2801
+ const data = response?.data || response || {};
2802
+ const next = {
2803
+ ...current,
2804
+ login: {
2805
+ ...(current.login && typeof current.login === 'object' ? current.login : {}),
2806
+ email: {
2807
+ lastEmail: email,
2808
+ lastAttemptId: data.loginAttemptId || null,
2809
+ sentAt: new Date().toISOString(),
2810
+ },
2811
+ },
2812
+ };
2813
+ persistProfileConfig(next);
2814
+ printEnvelope({
2815
+ success: true,
2816
+ code: 'LOGIN_EMAIL_CODE_SENT',
2817
+ message: response?.message || 'Verification code sent',
2818
+ data: {
2819
+ email,
2820
+ loginAttemptId: data.loginAttemptId || null,
2821
+ expiresAt: data.expiresAt || null,
2822
+ nextCommand: data.nextCommand || `thirdfy-agent login email ${email} --code <code> --accept-terms`,
2823
+ configPath: getProfileConfigPath(),
2824
+ },
2825
+ meta: { apiBase: ctx.apiBase },
2826
+ });
2827
+ return;
2828
+ }
2829
+
2830
+ if (!parseBooleanFlag(flags.acceptTerms, false)) {
2831
+ throw createCliError(
2832
+ 'LOGIN_EMAIL_TERMS_REQUIRED',
2833
+ 'Email login requires --accept-terms to complete first-run onboarding.'
2834
+ );
2835
+ }
2836
+
2837
+ const lastAttempt = current?.login?.email && typeof current.login.email === 'object' ? current.login.email : {};
2838
+ const response = await apiPost(ctx, '/api/v1/agent/onboarding/cli/email/complete', {
2839
+ email,
2840
+ code,
2841
+ loginAttemptId: String(flags.loginAttemptId || lastAttempt.lastAttemptId || '').trim() || undefined,
2842
+ acceptTerms: true,
2843
+ keyName,
2844
+ agentKey: String(flags.agentKey || '').trim() || undefined,
2845
+ runMode: normalizeRunMode(flags.runMode || current.runMode || process.env.THIRDFY_RUN_MODE || 'thirdfy'),
2846
+ custodyMode: normalizeCustodyMode(
2847
+ flags.custodyMode || current.custodyMode || process.env.THIRDFY_CUSTODY_MODE,
2848
+ normalizeRunMode(flags.runMode || current.runMode || process.env.THIRDFY_RUN_MODE || 'thirdfy')
2849
+ ),
2850
+ bootstrapAgent: !parseBooleanFlag(flags.noBootstrapAgent, false),
2851
+ rotateAgentKey: parseBooleanFlag(flags.rotateAgentKey, false),
2852
+ });
2853
+ const data = response?.data || response || {};
2854
+ const ownerSessionToken = String(data.ownerSessionToken || '').trim();
2855
+ const bootstrap = data.bootstrap && typeof data.bootstrap === 'object' ? data.bootstrap : {};
2856
+ const agentApiKey = String(bootstrap.agentApiKey || '').trim();
2857
+ const agentKey = String(bootstrap.agentKey || data.owner?.creatorWallet || '').trim();
2858
+ const wallets = data.wallets && typeof data.wallets === 'object' ? data.wallets : {};
2859
+ const primaryEvmWallet = String(wallets.primaryEvmWallet || data.owner?.creatorWallet || '').trim();
2860
+ const persistedWallets = {
2861
+ ...wallets,
2862
+ ...(primaryEvmWallet ? { primaryEvmWallet } : {}),
2863
+ };
2864
+ const runMode = normalizeRunMode(flags.runMode || current.runMode || process.env.THIRDFY_RUN_MODE || 'thirdfy');
2865
+ const custodyMode = normalizeCustodyMode(flags.custodyMode || current.custodyMode || process.env.THIRDFY_CUSTODY_MODE, runMode);
2866
+ if (!ownerSessionToken) {
2867
+ throw createCliError('LOGIN_EMAIL_OWNER_SESSION_MISSING', 'Email onboarding completed without an owner session token.');
2868
+ }
2869
+ const next = {
2870
+ ...current,
2871
+ runMode,
2872
+ custodyMode,
2873
+ auth: {
2874
+ ...(current.auth && typeof current.auth === 'object' ? current.auth : {}),
2875
+ lastLoginAt: new Date().toISOString(),
2876
+ source: 'email',
2877
+ ownerSessionToken,
2878
+ ownerSessionExpiresAt: data.ownerSessionExpiresAt || null,
2879
+ },
2880
+ wallets: persistedWallets,
2881
+ login: {
2882
+ ...(current.login && typeof current.login === 'object' ? current.login : {}),
2883
+ email: {
2884
+ lastEmail: email,
2885
+ completedAt: new Date().toISOString(),
2886
+ },
2887
+ },
2888
+ };
2889
+ delete next.auth.authToken;
2890
+ if (agentApiKey || agentKey) {
2891
+ next.agent = {
2892
+ ...(current.agent && typeof current.agent === 'object' ? current.agent : {}),
2893
+ ...(agentApiKey ? { apiKey: agentApiKey } : {}),
2894
+ ...(agentKey ? { agentKey } : {}),
2895
+ };
2896
+ }
2897
+ persistProfileConfig(next);
2898
+ printEnvelope({
2899
+ success: true,
2900
+ code: 'LOGIN_EMAIL_OK',
2901
+ message: response?.message || 'Email login completed',
2902
+ data: {
2903
+ email,
2904
+ hasOwnerSessionToken: Boolean(ownerSessionToken),
2905
+ hasAgentApiKey: Boolean(agentApiKey),
2906
+ agentKey: agentKey || null,
2907
+ evmWallets: Array.isArray(persistedWallets.evm) ? persistedWallets.evm : [],
2908
+ solanaWallets: Array.isArray(persistedWallets.solana) ? persistedWallets.solana : [],
2909
+ primaryEvmWallet: persistedWallets.primaryEvmWallet || null,
2910
+ configPath: getProfileConfigPath(),
2911
+ nextSteps: response?.nextSteps || [],
2912
+ },
2913
+ meta: { apiBase: ctx.apiBase },
2914
+ });
2915
+ }
2916
+
2580
2917
  async function commandLogout(ctx, flags) {
2581
2918
  const current = loadProfileConfig();
2582
2919
  const localOnly = flags.all ? false : true;
@@ -4284,8 +4621,10 @@ Core commands:
4284
4621
  thirdfy-agent profile show [--json]
4285
4622
  thirdfy-agent config set --key <path> --value <value> [--json]
4286
4623
  thirdfy-agent login [--auth-token <token> | --owner-session-token <token>] [--agent-api-key <key>] [--agent-key <key>] [--run-mode <mode>] [--custody-mode managed|external] [--wallet-address <addr>] [--json]
4624
+ thirdfy-agent login email <address> [--code <otp>] [--accept-terms] [--key-name <name>] [--agent-key <key>] [--not-interactive|--ni] [--json]
4287
4625
  thirdfy-agent logout [--all] [--clear-agent-key] [--json]
4288
4626
  thirdfy-agent whoami [--json]
4627
+ thirdfy-agent help onboarding [--json]
4289
4628
  thirdfy-agent catalogs list [--json]
4290
4629
  thirdfy-agent actions [--catalog <id>] [--provider <id>] [--agent-api-key <key>] [--chain-id <id>] [--run-mode <mode>] [--json]
4291
4630
  thirdfy-agent data summary --agent-key <key> [--chain-id <id>] [--network <id>] [--category trading|yield|prediction] [--limit <n>] [--json]
@@ -4308,6 +4647,7 @@ Core commands:
4308
4647
  thirdfy-agent managed wallet grant [--auth-token <token> | --owner-session-token <token>] --agent-key <key> --token-address <addr> --max-usd-per-day <usd> [--chain-id <id>] [--period-duration <sec>] [--expiry-seconds <sec>] [--json]
4309
4648
  thirdfy-agent managed setup [--auth-token <token> | --owner-session-token <token>] --agent-key <key> [--run-mode thirdfy|hybrid|agent_wallet] [--token-address <addr>] [--max-usd-per-day <usd>] [--chain-id <id>] [--json]
4310
4649
  thirdfy-agent wallet execute --agent-api-key <key> --user-did <did> --action <id> --params <json> [--chain-id <id>] [--idempotency-key <key>] [--wallet-address <expected>] [--allow-wallet-mismatch] [--json]
4650
+ thirdfy-agent wallet list [--json]
4311
4651
  thirdfy-agent wallet sign --agent-api-key <key> --action <id> --params <json> [--chain-id <id>] [--json]
4312
4652
  thirdfy-agent wallet submit --signed-tx-hex <hex> [--chain-id <id>] [--rpc-url <url>] [--json]
4313
4653
  thirdfy-agent agent run --agent-api-key <key> --action <id> --params <json> [--signer-method managed_wallet_server|byow|fanout_intent] [--strategy-intent single_wallet|fanout] [--run-mode <mode>] [--user-did <did>] [--json]
@@ -4327,6 +4667,7 @@ Core commands:
4327
4667
  thirdfy-agent run --agent-api-key <key> --action <id> --params <json> [--run-mode <mode>] [--broadcast] [--idempotency-key <key>] [--json]
4328
4668
  thirdfy-agent self-exec --agent-api-key <key> --action <id> --params <json> --wallet-address <addr> --ows-wallet-name <name> [--rpc-url <url>] [--effect-check strict|relaxed|off] [--json]
4329
4669
  thirdfy-agent doctor self [--wallet-address <addr>] [--ows-wallet-name <name>] [--rpc-url <url>] [--json]
4670
+ thirdfy-agent doctor auth [--json]
4330
4671
  thirdfy-agent jeff preflight --agent-api-key <key> --action <id> --params <json> [--run-mode <mode>] [--json]
4331
4672
  thirdfy-agent jeff trade --agent-api-key <key> --action <id> --params <json> [--run-mode <mode>] [--json]
4332
4673
  thirdfy-agent jeff status --intent-id <id> [--json]
@@ -4349,6 +4690,7 @@ Global flags:
4349
4690
  --allow-wallet-mismatch bypass strict funded-wallet vs execution-wallet guard
4350
4691
  --effect-check <mode> self-exec check mode: strict | relaxed | off (default: relaxed)
4351
4692
  --owner-session-token <token> owner session token (or THIRDFY_OWNER_SESSION_TOKEN)
4693
+ --not-interactive, --ni fail fast when required login input is missing
4352
4694
  --json stable machine-readable output
4353
4695
  --verbose print adapter diagnostics
4354
4696
  --version print version
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thirdfy/agent-cli",
3
- "version": "0.1.36",
3
+ "version": "0.1.37",
4
4
  "description": "Thirdfy Agent CLI for onboarding, governance preflight, execute-intent, and status polling.",
5
5
  "type": "module",
6
6
  "bin": {