@thirdfy/agent-cli 0.1.2 → 0.1.3

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/README.md CHANGED
@@ -34,25 +34,47 @@ npx @thirdfy/agent-cli --help
34
34
  export THIRDFY_API_BASE="https://api.thirdfy.com"
35
35
  export AGENT_API_KEY="..."
36
36
  export THIRDFY_AUTH_TOKEN="..."
37
+ export THIRDFY_OWNER_SESSION_TOKEN="..."
37
38
 
38
39
  thirdfy-agent actions --api-base "$THIRDFY_API_BASE" --agent-api-key "$AGENT_API_KEY" --json
39
40
  thirdfy-agent preflight --api-base "$THIRDFY_API_BASE" --agent-api-key "$AGENT_API_KEY" --action swap --params '{"tokenIn":"0x...","tokenOut":"0x...","amountIn":"1000000"}' --estimated-amount-usd 25 --json
40
- thirdfy-agent run --api-base "$THIRDFY_API_BASE" --agent-api-key "$AGENT_API_KEY" --action swap --params '{"tokenIn":"0x...","tokenOut":"0x...","amountIn":"1000000"}' --estimated-amount-usd 25 --idempotency-key "swap-001" --json
41
+ thirdfy-agent run --api-base "$THIRDFY_API_BASE" --agent-api-key "$AGENT_API_KEY" --action swap --params '{"tokenIn":"0x...","tokenOut":"0x...","amountIn":"1000000"}' --estimated-amount-usd 25 --json
41
42
  thirdfy-agent intent-status --api-base "$THIRDFY_API_BASE" --intent-id "<intentId>" --json
42
43
  ```
43
44
 
44
45
  ## Auth model
45
46
 
46
47
  - `AGENT_API_KEY`: execution identity and policy-aware action access (`actions --agent-api-key`, `preflight`, `run`)
47
- - `THIRDFY_AUTH_TOKEN`: user-scoped onboarding and account/governance operations (`agent register`, `agent key *`, `delegation *`, `credentials *`, `credits balance`)
48
+ - `THIRDFY_AUTH_TOKEN`: Privy-native owner/account auth (`agent register`, `agent key *`, `delegation *`, `credentials *`, `credits balance`)
49
+ - `THIRDFY_OWNER_SESSION_TOKEN`: wallet-sign owner auth session (`agent register`, `agent key *`)
48
50
 
49
51
  Execution-only workflows can run with only `AGENT_API_KEY` after onboarding is complete.
50
52
 
53
+ ### Wallet-sign onboarding path
54
+
55
+ ```bash
56
+ thirdfy-agent agent auth challenge --api-base "$THIRDFY_API_BASE" --agent-key "0xYOUR_AGENT_KEY" --json
57
+ # Sign challenge.message with your wallet, then:
58
+ thirdfy-agent agent auth verify --api-base "$THIRDFY_API_BASE" --challenge-id "<challengeId>" --signature "0x..." --agent-key "0xYOUR_AGENT_KEY" --json
59
+ ```
60
+
61
+ Use the returned session token:
62
+
63
+ ```bash
64
+ thirdfy-agent agent register --api-base "$THIRDFY_API_BASE" --owner-session-token "$THIRDFY_OWNER_SESSION_TOKEN" --agent-key "0xYOUR_AGENT_KEY" --name "my-agent" --json
65
+ ```
66
+
67
+ ### Idempotency behavior (`run`)
68
+
69
+ - `run` auto-generates `idempotencyKey` by default when not provided.
70
+ - For deterministic retries across workers/restarts, pass your own stable `--idempotency-key`.
71
+ - `preflight` does not force idempotency keys.
72
+
51
73
  ## Command groups
52
74
 
53
75
  - Discovery: `catalogs list`, `actions`
54
76
  - Execution: `preflight`, `run`, `intent-status`
55
- - Onboarding: `agent register`, `agent key rotate`, `agent key revoke`
77
+ - Onboarding: `agent auth challenge`, `agent auth verify`, `agent register`, `agent key rotate`, `agent key revoke`
56
78
  - Governance readiness: `delegation upsert`, `delegation status`, `credentials upsert`, `credentials status`
57
79
  - Account: `credits balance`
58
80
 
@@ -113,6 +113,14 @@ async function main() {
113
113
  await commandAgentKeyRevoke(context, subFlags, capabilities);
114
114
  return;
115
115
  }
116
+ if (commandKey3 === 'agent auth challenge') {
117
+ await commandAgentAuthChallenge(context, subFlags, capabilities);
118
+ return;
119
+ }
120
+ if (commandKey3 === 'agent auth verify') {
121
+ await commandAgentAuthVerify(context, subFlags, capabilities);
122
+ return;
123
+ }
116
124
 
117
125
  const rootCommand = parsed.positionals[0];
118
126
  switch (rootCommand) {
@@ -483,7 +491,10 @@ async function commandCredentialsStatus(ctx, flags, capabilities) {
483
491
  }
484
492
 
485
493
  async function commandAgentRegister(ctx, flags, capabilities) {
486
- const authToken = getAuthToken(flags, 'Missing --auth-token (or THIRDFY_AUTH_TOKEN) for agent register');
494
+ const ownerHeaders = buildOwnerAuthHeaders(
495
+ flags,
496
+ 'Missing owner auth for agent register: provide --auth-token (THIRDFY_AUTH_TOKEN) or --owner-session-token'
497
+ );
487
498
  const payload = {
488
499
  agentKey: requireFlag(flags, 'agentKey', 'Missing --agent-key'),
489
500
  name: requireFlag(flags, 'name', 'Missing --name'),
@@ -501,9 +512,10 @@ async function commandAgentRegister(ctx, flags, capabilities) {
501
512
  if (flags.strategy) payload.strategy = parseJsonFlag(flags, 'strategy');
502
513
  if (flags.apiKeyEnvelopePublicKey) payload.apiKeyEnvelopePublicKey = String(flags.apiKeyEnvelopePublicKey);
503
514
 
504
- const response = await apiPost(ctx, '/api/v1/agent/onboarding/register-with-privy', payload, {
505
- Authorization: `Bearer ${authToken}`,
506
- });
515
+ const route = ownerHeaders['x-owner-session-token']
516
+ ? '/api/v1/agent/onboarding/register-with-wallet'
517
+ : '/api/v1/agent/onboarding/register-with-privy';
518
+ const response = await apiPost(ctx, route, payload, ownerHeaders);
507
519
  printEnvelope({
508
520
  success: true,
509
521
  code: 'AGENT_REGISTERED',
@@ -517,12 +529,13 @@ async function commandAgentRegister(ctx, flags, capabilities) {
517
529
  }
518
530
 
519
531
  async function commandAgentKeyRotate(ctx, flags, capabilities) {
520
- const authToken = getAuthToken(flags, 'Missing --auth-token (or THIRDFY_AUTH_TOKEN) for agent key rotate');
532
+ const ownerHeaders = buildOwnerAuthHeaders(
533
+ flags,
534
+ 'Missing owner auth for agent key rotate: provide --auth-token (THIRDFY_AUTH_TOKEN) or --owner-session-token'
535
+ );
521
536
  const payload = {};
522
537
  if (flags.agentKey) payload.agentKey = String(flags.agentKey).trim();
523
- const response = await apiPost(ctx, '/api/v1/agent/onboarding/me/api-key/rotate', payload, {
524
- Authorization: `Bearer ${authToken}`,
525
- });
538
+ const response = await apiPost(ctx, '/api/v1/agent/onboarding/me/api-key/rotate', payload, ownerHeaders);
526
539
  printEnvelope({
527
540
  success: true,
528
541
  code: 'AGENT_KEY_ROTATED',
@@ -536,12 +549,13 @@ async function commandAgentKeyRotate(ctx, flags, capabilities) {
536
549
  }
537
550
 
538
551
  async function commandAgentKeyRevoke(ctx, flags, capabilities) {
539
- const authToken = getAuthToken(flags, 'Missing --auth-token (or THIRDFY_AUTH_TOKEN) for agent key revoke');
552
+ const ownerHeaders = buildOwnerAuthHeaders(
553
+ flags,
554
+ 'Missing owner auth for agent key revoke: provide --auth-token (THIRDFY_AUTH_TOKEN) or --owner-session-token'
555
+ );
540
556
  const payload = {};
541
557
  if (flags.agentKey) payload.agentKey = String(flags.agentKey).trim();
542
- const response = await apiPost(ctx, '/api/v1/agent/onboarding/me/api-key/revoke', payload, {
543
- Authorization: `Bearer ${authToken}`,
544
- });
558
+ const response = await apiPost(ctx, '/api/v1/agent/onboarding/me/api-key/revoke', payload, ownerHeaders);
545
559
  printEnvelope({
546
560
  success: true,
547
561
  code: 'AGENT_KEY_REVOKED',
@@ -554,6 +568,47 @@ async function commandAgentKeyRevoke(ctx, flags, capabilities) {
554
568
  });
555
569
  }
556
570
 
571
+ async function commandAgentAuthChallenge(ctx, flags, capabilities) {
572
+ const payload = {
573
+ agentKey: requireFlag(flags, 'agentKey', 'Missing --agent-key'),
574
+ chainId: Number(flags.chainId || 8453),
575
+ };
576
+ if (flags.walletAddress) payload.walletAddress = String(flags.walletAddress).trim();
577
+
578
+ const response = await apiPost(ctx, '/api/v1/agent/onboarding/wallet/challenge', payload);
579
+ printEnvelope({
580
+ success: true,
581
+ code: 'OWNER_CHALLENGE_CREATED',
582
+ message: 'Wallet challenge created',
583
+ data: response,
584
+ meta: {
585
+ apiBase: ctx.apiBase,
586
+ capabilitiesVersion: capabilities?.contractVersion || null,
587
+ },
588
+ });
589
+ }
590
+
591
+ async function commandAgentAuthVerify(ctx, flags, capabilities) {
592
+ const payload = {
593
+ challengeId: requireFlag(flags, 'challengeId', 'Missing --challenge-id'),
594
+ signature: requireFlag(flags, 'signature', 'Missing --signature'),
595
+ agentKey: requireFlag(flags, 'agentKey', 'Missing --agent-key'),
596
+ };
597
+ if (flags.walletAddress) payload.walletAddress = String(flags.walletAddress).trim();
598
+
599
+ const response = await apiPost(ctx, '/api/v1/agent/onboarding/wallet/verify', payload);
600
+ printEnvelope({
601
+ success: true,
602
+ code: 'OWNER_VERIFIED',
603
+ message: 'Wallet challenge verified',
604
+ data: response,
605
+ meta: {
606
+ apiBase: ctx.apiBase,
607
+ capabilitiesVersion: capabilities?.contractVersion || null,
608
+ },
609
+ });
610
+ }
611
+
557
612
  function buildIntentPayload(flags, options) {
558
613
  const payload = {
559
614
  agentApiKey: requireFlag(flags, 'agentApiKey', 'Missing --agent-api-key'),
@@ -687,6 +742,18 @@ function getAuthToken(flags, missingMessage) {
687
742
  return authToken;
688
743
  }
689
744
 
745
+ function buildOwnerAuthHeaders(flags, missingMessage) {
746
+ const authToken = String(flags.authToken || process.env.THIRDFY_AUTH_TOKEN || '').trim();
747
+ const ownerSessionToken = String(flags.ownerSessionToken || process.env.THIRDFY_OWNER_SESSION_TOKEN || '').trim();
748
+ if (!authToken && !ownerSessionToken) {
749
+ throw new Error(missingMessage);
750
+ }
751
+ if (authToken) {
752
+ return { Authorization: `Bearer ${authToken}` };
753
+ }
754
+ return { 'x-owner-session-token': ownerSessionToken };
755
+ }
756
+
690
757
  function extractActions(response) {
691
758
  if (Array.isArray(response)) return response;
692
759
  if (Array.isArray(response.actions)) return response.actions;
@@ -793,9 +860,11 @@ Core commands:
793
860
  thirdfy-agent delegation status --auth-token <token> --agent-key <key> [--verify] [--json]
794
861
  thirdfy-agent credentials upsert --auth-token <token> --venue <id> --api-key <key> --api-secret <secret> [--json]
795
862
  thirdfy-agent credentials status --auth-token <token> [--venue <id>] [--json]
796
- thirdfy-agent agent register --auth-token <token> --agent-key <key> --name <name> [--json]
797
- thirdfy-agent agent key rotate --auth-token <token> [--agent-key <key>] [--json]
798
- thirdfy-agent agent key revoke --auth-token <token> [--agent-key <key>] [--json]
863
+ thirdfy-agent agent auth challenge --agent-key <key> [--wallet-address <addr>] [--chain-id <id>] [--json]
864
+ thirdfy-agent agent auth verify --challenge-id <id> --signature <hex> --agent-key <key> [--wallet-address <addr>] [--json]
865
+ thirdfy-agent agent register --agent-key <key> --name <name> [--auth-token <token> | --owner-session-token <token>] [--json]
866
+ thirdfy-agent agent key rotate [--agent-key <key>] [--auth-token <token> | --owner-session-token <token>] [--json]
867
+ thirdfy-agent agent key revoke [--agent-key <key>] [--auth-token <token> | --owner-session-token <token>] [--json]
799
868
  thirdfy-agent preflight --agent-api-key <key> --action <id> --params <json> [--json]
800
869
  thirdfy-agent run --agent-api-key <key> --action <id> --params <json> [--idempotency-key <key>] [--json]
801
870
  thirdfy-agent intent-status --intent-id <id> [--json]
@@ -805,6 +874,7 @@ Global flags:
805
874
  --api-base <url> default: https://api.thirdfy.com
806
875
  --env <file> load env vars from file
807
876
  --timeout <ms> request timeout
877
+ --owner-session-token <token> owner session token (or THIRDFY_OWNER_SESSION_TOKEN)
808
878
  --json stable machine-readable output
809
879
  --verbose print adapter diagnostics
810
880
  --version print version
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thirdfy/agent-cli",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Thirdfy Agent CLI for onboarding, governance preflight, execute-intent, and status polling.",
5
5
  "type": "module",
6
6
  "bin": {