@thirdfy/agent-cli 0.2.22 → 0.2.28
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 +44 -0
- package/README.md +2 -5
- package/package.json +3 -1
- package/src/runtime/execution/payloads.mjs +61 -6
- package/src/runtime/execution/runners.mjs +14 -3
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,50 @@ All notable changes to `@thirdfy/agent-cli` are documented here. The format is b
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.2.28] - 2026-07-11
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- `e2e:base:simulate` Robinhood tier uses `--run-mode agent_wallet` so chain 4663 compatibility passes (Robinhood advertises `self` + `agent_wallet` only).
|
|
12
|
+
|
|
13
|
+
## [0.2.27] - 2026-07-11
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Robinhood partner validator moved to `scripts/e2e/chains/robinhood/delegated-preflight.mjs` with shared `delegation-lane` helper and Robinhood constants.
|
|
18
|
+
- `e2e:base:simulate` includes `actions --chain-id 4663` tier; `docs/partners/robinhood-validation.md` documents CLI vs API validation split.
|
|
19
|
+
- npm alias `validate:robinhood:delegated-preflight`; legacy `validate:robinhood-agent-wallet-preflight` preserved.
|
|
20
|
+
|
|
21
|
+
## [0.2.26] - 2026-07-11
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Robinhood live validator uses Privy subscriber delegation (`THIRDFY_USER_DID` + `managed_wallet_server`) and Robinhood-native WETH/USDG addresses instead of solo `did:wallet:<agentKey>`.
|
|
26
|
+
- Validator requires explicit `THIRDFY_USER_DID` or `ROBINHOOD_SMOKE_USER_DID` (no `~/.thirdfy/config.json` fallback) so partner checks always exercise the delegation lane.
|
|
27
|
+
- Validator probes `GET /api/v1/agent/execution-wallet` and rejects agent-owner bypass when `canonicalUserDid` rewrites to `did:wallet:<agentKey>`.
|
|
28
|
+
|
|
29
|
+
## [0.2.25] - 2026-07-11
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
|
|
33
|
+
- Solo `agent_wallet` still uses `did:wallet:<agentKey>`, but hybrid `agent_wallet` and `--signer-method managed_wallet_server` keep saved Privy delegation identity.
|
|
34
|
+
|
|
35
|
+
## [0.2.24] - 2026-07-11
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
- `agent_wallet` execute-intent read-only fallback now passes `runMode: agent_wallet` into identity resolution so solo `did:wallet:<agentKey>` is used consistently.
|
|
40
|
+
|
|
41
|
+
## [0.2.23] - 2026-07-11
|
|
42
|
+
|
|
43
|
+
### Fixed
|
|
44
|
+
|
|
45
|
+
- Solo `agent_wallet` preflight now resolves `did:wallet:<agentKey>` from `--agent-key`, `THIRDFY_AGENT_KEY`, or `config.agent.agentKey` instead of falling back to subscriber Privy `userDid` (fixes `SUBSCRIPTION_NOT_FOUND` on Robinhood and other direct agent lanes).
|
|
46
|
+
|
|
47
|
+
### Added
|
|
48
|
+
|
|
49
|
+
- `npm run validate:robinhood-agent-wallet-preflight` for live API delegated agent_wallet preflight on chain 4663 (requires `THIRDFY_USER_DID` + active delegation on 4663).
|
|
50
|
+
|
|
7
51
|
## [0.2.22] - 2026-07-10
|
|
8
52
|
|
|
9
53
|
### Added
|
package/README.md
CHANGED
|
@@ -40,12 +40,9 @@ Run without global install:
|
|
|
40
40
|
npx @thirdfy/agent-cli --help
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
## What's new in v0.2.
|
|
43
|
+
## What's new in v0.2.28
|
|
44
44
|
|
|
45
|
-
-
|
|
46
|
-
- Live capabilities validation asserts chain 4663 when `THIRDFY_API_BASE` is set. Pairs with Thirdfy API **v3.10.7+**.
|
|
47
|
-
|
|
48
|
-
Older versions: see [CHANGELOG.md](./CHANGELOG.md) and [GitHub Releases](https://github.com/thirdfy/agent-cli/releases).
|
|
45
|
+
- `e2e:base:simulate` Robinhood tier passes chain 4663 compatibility by using `--run-mode agent_wallet`.
|
|
49
46
|
|
|
50
47
|
Older versions: see [CHANGELOG.md](./CHANGELOG.md) and [GitHub Releases](https://github.com/thirdfy/agent-cli/releases).
|
|
51
48
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thirdfy/agent-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.28",
|
|
4
4
|
"description": "Thirdfy Agent CLI for onboarding, governance preflight, execute-intent, and status polling.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -47,6 +47,8 @@
|
|
|
47
47
|
"smoke:cli": "node ./bin/thirdfy-agent.mjs --help && node ./bin/thirdfy-agent.mjs -V && node ./bin/thirdfy-agent.mjs --version --json",
|
|
48
48
|
"validate:release-preflight": "npm run lint && npm run validate:public-docs && npm run validate:cli-contract-schemas && npm run validate:provider-parity && npm run validate:cli-manifest-handlers && npm run validate:runtime-boundaries && npm run test && npm run validate:npm-pack && npm run smoke:cli",
|
|
49
49
|
"validate:live-api-capabilities": "node ./scripts/validate-live-api-capabilities.mjs",
|
|
50
|
+
"validate:robinhood:delegated-preflight": "node ./scripts/e2e/chains/robinhood/delegated-preflight.mjs",
|
|
51
|
+
"validate:robinhood-agent-wallet-preflight": "node ./scripts/e2e/chains/robinhood/delegated-preflight.mjs",
|
|
50
52
|
"prepublishOnly": "npm run validate:release-preflight"
|
|
51
53
|
},
|
|
52
54
|
"keywords": [
|
|
@@ -16,13 +16,57 @@ function buildBuildTxPayload(flags, resolvedAction) {
|
|
|
16
16
|
return payload;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
function
|
|
19
|
+
function resolveAgentKey(flags) {
|
|
20
|
+
const explicit = String(flags.agentKey || '').trim();
|
|
21
|
+
if (explicit) return explicit.toLowerCase();
|
|
22
|
+
const envKey = String(process.env.THIRDFY_AGENT_KEY || process.env.AGENT_KEY || '').trim();
|
|
23
|
+
if (envKey) return envKey.toLowerCase();
|
|
24
|
+
const config = loadProfileConfig();
|
|
25
|
+
const configKey = String(config?.agent?.agentKey || '').trim();
|
|
26
|
+
if (configKey) return configKey.toLowerCase();
|
|
27
|
+
return '';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function buildSoloAgentWalletUserDid(agentKey) {
|
|
31
|
+
const normalized = String(agentKey || '').trim().toLowerCase();
|
|
32
|
+
if (!normalized) return '';
|
|
33
|
+
return `did:wallet:${normalized}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function isWalletScopedUserDid(value) {
|
|
37
|
+
return String(value || '').trim().toLowerCase().startsWith('did:wallet:');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function preferDelegationAgentWalletIdentity(flags, options = {}) {
|
|
41
|
+
if (options.preferDelegationIdentity === true) return true;
|
|
42
|
+
if (String(flags.runMode || '').trim().toLowerCase() === 'hybrid') return true;
|
|
43
|
+
if (options.hybridWalletMode) return true;
|
|
44
|
+
const signerMethod = String(flags.signerMethod || '').trim().toLowerCase();
|
|
45
|
+
if (signerMethod === 'managed_wallet_server') return true;
|
|
46
|
+
const scope = String(flags.executionScope || '').trim();
|
|
47
|
+
if (scope && scope !== 'solo_owner_mirror') return true;
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function resolveEffectiveUserDid(flags, options = {}) {
|
|
20
52
|
const explicit = String(flags.userDid || '').trim();
|
|
21
53
|
if (explicit) return explicit;
|
|
54
|
+
const runMode = String(options.runMode || flags.runMode || '').trim().toLowerCase();
|
|
22
55
|
const envUserDid = String(process.env.THIRDFY_USER_DID || '').trim();
|
|
23
|
-
if (envUserDid) return envUserDid;
|
|
24
56
|
const config = loadProfileConfig();
|
|
25
|
-
|
|
57
|
+
const configUserDid = String(config?.wallets?.userDid || config?.identity?.userDid || '').trim();
|
|
58
|
+
|
|
59
|
+
// Solo agent_wallet uses did:wallet:<agentKey>. Hybrid and managed_wallet_server keep Privy delegation.
|
|
60
|
+
if (runMode === 'agent_wallet' && !preferDelegationAgentWalletIdentity(flags, options)) {
|
|
61
|
+
const soloDid = buildSoloAgentWalletUserDid(resolveAgentKey(flags));
|
|
62
|
+
if (soloDid) return soloDid;
|
|
63
|
+
if (isWalletScopedUserDid(envUserDid)) return envUserDid;
|
|
64
|
+
if (isWalletScopedUserDid(configUserDid)) return configUserDid;
|
|
65
|
+
return '';
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (envUserDid) return envUserDid;
|
|
69
|
+
return configUserDid;
|
|
26
70
|
}
|
|
27
71
|
|
|
28
72
|
function buildManagedExecutePayload(flags, options) {
|
|
@@ -55,7 +99,11 @@ function buildManagedExecutePayload(flags, options) {
|
|
|
55
99
|
const payload = {
|
|
56
100
|
agentApiKey: resolveAgentApiKey(flags, runMode),
|
|
57
101
|
action: String(options.resolvedAction || requireFlag(flags, 'action', 'Missing --action')).trim(),
|
|
58
|
-
userDid: resolveEffectiveUserDid(flags
|
|
102
|
+
userDid: resolveEffectiveUserDid(flags, {
|
|
103
|
+
runMode,
|
|
104
|
+
hybridWalletMode: options.hybridWalletMode,
|
|
105
|
+
preferDelegationIdentity: options.preferDelegationIdentity,
|
|
106
|
+
}),
|
|
59
107
|
params: managedParams,
|
|
60
108
|
chainId: Number(flags.chainId || 8453),
|
|
61
109
|
executionStrategy: {
|
|
@@ -66,7 +114,7 @@ function buildManagedExecutePayload(flags, options) {
|
|
|
66
114
|
if (!payload.userDid) {
|
|
67
115
|
throw createCliError(
|
|
68
116
|
'MISSING_USER_DID',
|
|
69
|
-
'Managed wallet execution requires --user-did, THIRDFY_USER_DID, or a saved userDid from `thirdfy-agent login email`.'
|
|
117
|
+
'Managed wallet execution requires --user-did, --agent-key (solo did:wallet identity), THIRDFY_USER_DID, or a saved userDid from `thirdfy-agent login email`.'
|
|
70
118
|
);
|
|
71
119
|
}
|
|
72
120
|
if (flags.estimatedAmountUsd) payload.estimatedAmountUsd = Number(flags.estimatedAmountUsd);
|
|
@@ -96,7 +144,12 @@ function buildIntentPayload(flags, options) {
|
|
|
96
144
|
if (flags.catalog) payload.catalog = String(flags.catalog).trim();
|
|
97
145
|
if (flags.chainId) payload.chainId = Number(flags.chainId);
|
|
98
146
|
if (flags.estimatedAmountUsd) payload.estimatedAmountUsd = Number(flags.estimatedAmountUsd);
|
|
99
|
-
const
|
|
147
|
+
const intentRunMode = String(options.runMode || flags.runMode || '').trim().toLowerCase();
|
|
148
|
+
const userDid = resolveEffectiveUserDid(flags, {
|
|
149
|
+
runMode: intentRunMode,
|
|
150
|
+
hybridWalletMode: options.hybridWalletMode,
|
|
151
|
+
preferDelegationIdentity: options.preferDelegationIdentity,
|
|
152
|
+
});
|
|
100
153
|
if (flags.userDid || (options.validationOnly && (runMode === 'agent_wallet' || (runMode === 'hybrid' && options.mirrorOnly)))) {
|
|
101
154
|
if (userDid) payload.userDid = userDid;
|
|
102
155
|
}
|
|
@@ -139,6 +192,8 @@ function resolveAgentApiKey(flags, runMode) {
|
|
|
139
192
|
|
|
140
193
|
return {
|
|
141
194
|
buildBuildTxPayload,
|
|
195
|
+
resolveAgentKey,
|
|
196
|
+
buildSoloAgentWalletUserDid,
|
|
142
197
|
resolveEffectiveUserDid,
|
|
143
198
|
buildManagedExecutePayload,
|
|
144
199
|
resolveTokenInForFunding,
|
|
@@ -338,7 +338,11 @@ async function executeManagedWalletRun(ctx, flags, resolved, options) {
|
|
|
338
338
|
const actionCtx = withActionTimeout(ctx, resolved.resolvedAction);
|
|
339
339
|
const response = await apiPost(actionCtx, '/api/v1/agent/execute', payload);
|
|
340
340
|
if (shouldFallbackAgentWalletToExecuteIntent(resolved, response)) {
|
|
341
|
-
const userDid = resolveEffectiveUserDid(flags
|
|
341
|
+
const userDid = resolveEffectiveUserDid(flags, {
|
|
342
|
+
runMode: 'agent_wallet',
|
|
343
|
+
hybridWalletMode: options.hybridWalletMode,
|
|
344
|
+
preferDelegationIdentity: options.preferDelegationIdentity,
|
|
345
|
+
});
|
|
342
346
|
const chainId = Number(flags.chainId || 8453);
|
|
343
347
|
const intentResult = await executeThirdfyRun(
|
|
344
348
|
ctx,
|
|
@@ -493,13 +497,20 @@ async function resolveManagedExecutionPreflight(ctx, flags, resolved, options =
|
|
|
493
497
|
const chainId = Number(flags.chainId || 8453);
|
|
494
498
|
const runMode = String(options.runMode || 'agent_wallet').trim().toLowerCase();
|
|
495
499
|
const agentApiKey = resolveAgentApiKey(flags, runMode);
|
|
496
|
-
const userDid = resolveEffectiveUserDid(flags
|
|
500
|
+
const userDid = resolveEffectiveUserDid(flags, {
|
|
501
|
+
runMode,
|
|
502
|
+
hybridWalletMode: options.hybridWalletMode,
|
|
503
|
+
preferDelegationIdentity: options.preferDelegationIdentity,
|
|
504
|
+
});
|
|
497
505
|
if (!userDid) {
|
|
498
506
|
return {
|
|
499
507
|
success: false,
|
|
500
508
|
blockedReason: 'MISSING_USER_DID',
|
|
501
509
|
blockedStage: 'routing',
|
|
502
|
-
error:
|
|
510
|
+
error:
|
|
511
|
+
runMode === 'agent_wallet'
|
|
512
|
+
? 'Solo agent_wallet requires --agent-key, THIRDFY_AGENT_KEY, config.agent.agentKey, or --user-did did:wallet:<agentKey>. Subscriber Privy DIDs require delegation; use did:wallet for direct agent execution.'
|
|
513
|
+
: 'Managed wallet execution requires --user-did, THIRDFY_USER_DID, or a saved userDid from `thirdfy-agent login email`.',
|
|
503
514
|
signerMethod: 'managed_wallet_server',
|
|
504
515
|
};
|
|
505
516
|
}
|