@thirdfy/agent-cli 0.2.22 → 0.2.25
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 +22 -0
- package/README.md +10 -4
- 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,28 @@ All notable changes to `@thirdfy/agent-cli` are documented here. The format is b
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.2.25] - 2026-07-11
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Solo `agent_wallet` still uses `did:wallet:<agentKey>`, but hybrid `agent_wallet` and `--signer-method managed_wallet_server` keep saved Privy delegation identity.
|
|
12
|
+
|
|
13
|
+
## [0.2.24] - 2026-07-11
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- `agent_wallet` execute-intent read-only fallback now passes `runMode: agent_wallet` into identity resolution so solo `did:wallet:<agentKey>` is used consistently.
|
|
18
|
+
|
|
19
|
+
## [0.2.23] - 2026-07-11
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- 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).
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- `npm run validate:robinhood-agent-wallet-preflight` for live API solo agent_wallet preflight on chain 4663.
|
|
28
|
+
|
|
7
29
|
## [0.2.22] - 2026-07-10
|
|
8
30
|
|
|
9
31
|
### Added
|
package/README.md
CHANGED
|
@@ -40,12 +40,18 @@ 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.25
|
|
44
44
|
|
|
45
|
-
-
|
|
46
|
-
- Live capabilities validation asserts chain 4663 when `THIRDFY_API_BASE` is set. Pairs with Thirdfy API **v3.10.7+**.
|
|
45
|
+
- Hybrid and `managed_wallet_server` agent_wallet paths keep Privy delegation identity; solo Robinhood lane still uses `did:wallet:<agentKey>`.
|
|
47
46
|
|
|
48
|
-
|
|
47
|
+
## What's new in v0.2.24
|
|
48
|
+
|
|
49
|
+
- `agent_wallet` read-only execute-intent fallback keeps solo `did:wallet:<agentKey>` identity (matches preflight and primary execute path).
|
|
50
|
+
|
|
51
|
+
## What's new in v0.2.23
|
|
52
|
+
|
|
53
|
+
- Solo `agent_wallet` preflight uses `did:wallet:<agentKey>` so Robinhood and direct agent lanes skip subscriber delegation (`SUBSCRIPTION_NOT_FOUND` fix).
|
|
54
|
+
- `npm run validate:robinhood-agent-wallet-preflight` for live chain 4663 execution-wallet checks.
|
|
49
55
|
|
|
50
56
|
Older versions: see [CHANGELOG.md](./CHANGELOG.md) and [GitHub Releases](https://github.com/thirdfy/agent-cli/releases).
|
|
51
57
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thirdfy/agent-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.25",
|
|
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-agent-wallet-preflight": "node ./scripts/validate-robinhood-agent-wallet-preflight.mjs",
|
|
51
|
+
"validate:robinhood-agent-wallet-preflight": "node ./scripts/validate-robinhood-agent-wallet-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
|
}
|